两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

如圖,對(duì)于插入數(shù)據(jù)的操作,基本與單鏈表的插入操作相同,我們可以創(chuàng)建一個(gè)獨(dú)立的結(jié)點(diǎn),通過(guò)將需要插入的結(jié)點(diǎn)的上一個(gè)結(jié)點(diǎn)的next指針指向該節(jié)點(diǎn),再由需要插入的結(jié)點(diǎn)的next指針指向下一個(gè)結(jié)點(diǎn)的方式完成插入操作。 

單向循環(huán)鏈表插入

其代碼可以表示為:

//插入元素
list *insert_list(list *head,int pos,int data){
    //三個(gè)參數(shù)分別是鏈表,位置,參數(shù)
    list *node=initlist();  //新建結(jié)點(diǎn)
    list *p=head;       //p表示新的鏈表
    list *t;
    t=p;
    node->data=data;
    if(head!=NULL){
        for(int i=1;i<pos;i++){
            t=t->next;  //走到需要插入的位置處
        }
        node->next=t->next;
        t->next=node;
        return p;
    }
    return p;
}

2.   循環(huán)單鏈表的刪除操作

如圖所示,循環(huán)單鏈表的刪除操作可以參考單鏈表的刪除操作,其都是找到需要?jiǎng)h除的結(jié)點(diǎn),將其前一個(gè)結(jié)點(diǎn)的next指針直接指向刪除結(jié)點(diǎn)的下一個(gè)結(jié)點(diǎn)即可,但需要注意的是尾節(jié)點(diǎn)和頭結(jié)點(diǎn)的特判,尤其是尾結(jié)點(diǎn),因?yàn)閯h除尾節(jié)點(diǎn)后,尾節(jié)點(diǎn)前一個(gè)結(jié)點(diǎn)就成了新的尾節(jié)點(diǎn),這個(gè)新的尾節(jié)點(diǎn)需要指向的是頭結(jié)點(diǎn)而不是空,其重點(diǎn)可以記錄為【當(dāng)前的前一節(jié)點(diǎn).next=自身結(jié)點(diǎn).next】這樣的操作可以省去頭尾結(jié)點(diǎn)的特判:

單向循環(huán)鏈表刪除結(jié)點(diǎn)


其代碼可以表示為:

//刪除元素
int delete_list(list *head) {
    if(head == NULL) {
        printf("鏈表為空!\n");
        return 0;
    }
    //建立臨時(shí)結(jié)點(diǎn)存儲(chǔ)頭結(jié)點(diǎn)信息(目的為了找到退出點(diǎn))
    //如果不這么建立的化需要使用一個(gè)數(shù)據(jù)進(jìn)行計(jì)數(shù)標(biāo)記,計(jì)數(shù)達(dá)到鏈表長(zhǎng)度時(shí)自動(dòng)退出
    //循環(huán)鏈表當(dāng)找到最后一個(gè)元素的時(shí)候會(huì)自動(dòng)指向頭元素,這是我們不想讓他發(fā)生的
    list *temp = head;          
    list *ptr = head->next;
 
    int del;
    printf("請(qǐng)輸入你要?jiǎng)h除的元素:");
    scanf("%d",&del);
 
    while(ptr != head) {
        if(ptr->data == del) {
            if(ptr->next == head) { 
                temp->next = head;
                free(ptr);
                return 1;
            }
            temp->next = ptr->next;    //核心刪除操作代碼
            free(ptr);
            //printf("元素刪除成功!\n");
            return 1;
        }
        temp = temp->next;
        ptr = ptr->next;
    }
    printf("沒有找到要?jiǎng)h除的元素\n");
    return 0;
}


3.   循環(huán)單鏈表的遍歷

與普通的單鏈表和雙向鏈表的遍歷不同,循環(huán)鏈表需要進(jìn)行結(jié)點(diǎn)的特判,找到尾節(jié)點(diǎn)的位置,由于尾節(jié)點(diǎn)的next指針是指向頭結(jié)點(diǎn)的,所以不能使用鏈表本身是否為空(NULL)的方法進(jìn)行簡(jiǎn)單的循環(huán)判斷,我們需要通過(guò)判斷結(jié)點(diǎn)的next指針是否等于頭結(jié)點(diǎn)的方式進(jìn)行是否完成循環(huán)的判斷。

此外還有一種計(jì)數(shù)的方法,即建立一個(gè)計(jì)數(shù)器count=0,每一次next指針指向下一個(gè)結(jié)點(diǎn)時(shí)計(jì)數(shù)器加一,當(dāng)count數(shù)字與鏈表的節(jié)點(diǎn)數(shù)相同的時(shí)候即完成循環(huán),這樣做有一個(gè)問(wèn)題,就是獲取到鏈表的節(jié)點(diǎn)數(shù)同時(shí)也需要完成一次遍歷才可以達(dá)成目標(biāo)。

其代碼可以表示為:

//遍歷元素
int display(list *head) {
    if(head != NULL) {
        list *p  = head;
        //遍歷頭節(jié)點(diǎn)到,最后一個(gè)數(shù)據(jù)
        while(p->next != head ) {
            printf("%d   ",p->next->data);
            p = p->next;
        }
        printf("\n");   //習(xí)慣性換行 ( o=^?ェ?)o ┏━┓
        //把最后一個(gè)節(jié)點(diǎn)賦新的節(jié)點(diǎn)過(guò)去
        return 1;
    } else {
        printf("頭結(jié)點(diǎn)為空!\n");
        return 0;
    }
}

4.   進(jìn)階概念—雙向循環(huán)鏈表

循環(huán)鏈表還有一個(gè)進(jìn)階的概念練習(xí),同雙向鏈表與單鏈表的關(guān)系一樣,循環(huán)單鏈表也有一個(gè)孿生兄弟——雙向循環(huán)鏈表,其設(shè)計(jì)思路與單鏈表和雙向鏈表的設(shè)計(jì)思路一樣,就是在原有的雙向鏈表的基礎(chǔ)上,將尾部結(jié)點(diǎn)和頭部結(jié)點(diǎn)進(jìn)行互相連接,這個(gè)鏈表的設(shè)計(jì)不難,就交給讀者自主進(jìn)行設(shè)計(jì)。

5.   循環(huán)單鏈表代碼

 #include<stdio.h>
#include<stdlib.h>
typedef struct list{
    int data;
    struct list *next;
}list;
//data為存儲(chǔ)的數(shù)據(jù),next指針為指向下一個(gè)結(jié)點(diǎn)

//初始結(jié)點(diǎn)
list *initlist(){
    list *head=(list*)malloc(sizeof(list));
    if(head==NULL){
        printf("創(chuàng)建失敗,退出程序");
        exit(0);
    }else{
        head->next=NULL;
        return head;
    }
}

//創(chuàng)建--插入數(shù)據(jù)
int create_list(list *head){
    int data;   //插入的數(shù)據(jù)類型
    printf("請(qǐng)輸入要插入的元素:");
    scanf("%d",&data);

    list *node=initlist();
    node->data=data;
    //初始化一個(gè)新的結(jié)點(diǎn),準(zhǔn)備進(jìn)行鏈接

    if(head!=NULL){
        list *p=head;
        //找到最后一個(gè)數(shù)據(jù)
        while(p->next!=head){
            p=p->next;
        }
        p->next=node;
        node->next=head;
        return 1;
    }else{
        printf("頭結(jié)點(diǎn)已無(wú)元素\n");
        return 0;
    }

}

//插入元素
list *insert_list(list *head,int pos,int data){
    //三個(gè)參數(shù)分別是鏈表,位置,參數(shù)
    list *node=initlist();  //新建結(jié)點(diǎn)
    list *p=head;       //p表示新的鏈表
    list *t;
    t=p;
    node->data=data;
    if(head!=NULL){
        for(int i=1;i<=pos;i++){
            t=t->next;
        }
        node->next=t->next;
        t->next=node;
        return p;
    }
    return p;
}

//刪除元素
int delete_list(list *head) {
	if(head == NULL) {
		printf("鏈表為空!\n");
		return 0;
	}
    //建立零時(shí)結(jié)點(diǎn)存儲(chǔ)頭結(jié)點(diǎn)信息(目的為了找到退出點(diǎn))
    //如果不這么建立的化需要使用一個(gè)數(shù)據(jù)進(jìn)行計(jì)數(shù)標(biāo)記,計(jì)數(shù)達(dá)到鏈表長(zhǎng)度時(shí)自動(dòng)退出
    //循環(huán)鏈表當(dāng)找到最后一個(gè)元素的時(shí)候會(huì)自動(dòng)指向頭元素,這是我們不想讓他發(fā)生的
	list *temp = head;          
	list *ptr = head->next;

	int del;
	printf("請(qǐng)輸入你要?jiǎng)h除的元素:");
	scanf("%d",&del);

	while(ptr != head) {
		if(ptr->data == del) {
			if(ptr->next == head) { //循環(huán)結(jié)束的條件換成ptr->next == head
				temp->next = head;
				free(ptr);
				return 1;
			}
			temp->next = ptr->next;
			free(ptr);
			//printf("元素刪除成功!\n");
			return 1;
		}
		temp = temp->next;
		ptr = ptr->next;
	}
	printf("沒有找到要?jiǎng)h除的元素\n");
	return 0;
}


//遍歷元素
int display(list *head) {
	if(head != NULL) {
		list *p  = head;
		//遍歷頭節(jié)點(diǎn)到,最后一個(gè)數(shù)據(jù)
		while(p->next != head ) {
			printf("%d   ",p->next->data);
			p = p->next;
		}
        printf("\n");   //習(xí)慣性換行 ( o=^?ェ?)o ┏━┓
		//把最后一個(gè)節(jié)點(diǎn)賦新的節(jié)點(diǎn)過(guò)去
		return 1;
	} else {
		printf("頭結(jié)點(diǎn)為空!\n");
		return 0;
	}
}

int main(){
    //////////初始化頭結(jié)點(diǎn)//////////////
    list *head=initlist();
    head->next=head;
    ////////通過(guò)插入元素完善鏈表/////////
    for(int i=0;i<5;i++){   //只是演示使用,不具體提供輸入
        create_list(head);
    }
    display(head);
    ////////////插入元素////////////////
    head=insert_list(head,1,10);
    display(head);
    ////////////刪除元素////////////////
    delete_list(head);
    display(head);
    return 0;
}


6.   推薦試題

如同雙向鏈表,循環(huán)單鏈表的單獨(dú)訓(xùn)練數(shù)據(jù)并不是很多,在網(wǎng)上的資料相比單鏈表也是偏少,不過(guò)我們?cè)谑煜ぴ碇罂梢酝瑔捂湵淼念}目,可以嘗試使用循環(huán)單鏈表進(jìn)行做題,如下題:

1676題、1585題 



點(diǎn)贊(1)

C語(yǔ)言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:

一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語(yǔ)言學(xué)練課程

解決困擾你多年的C語(yǔ)言疑難雜癥特性的C語(yǔ)言進(jìn)階課程

從零到寫出一個(gè)爬蟲的Python編程課程

只會(huì)語(yǔ)法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程

信息學(xué)奧賽或C++選手的 必學(xué)C++課程

藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程

手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程

Dotcpp在線編譯      (登錄可減少運(yùn)行等待時(shí)間)