單向迴圈連結串列的簡單實現
阿新 • • 發佈:2019-02-09
單向迴圈連結串列:
在單向連結串列中,頭指標是相當重要的,因為單向連結串列的操作都需要頭指標,所以如果頭指標丟失或者破壞,那麼整個連結串列都會遺失,並且浪費連結串列記憶體空間。
單向迴圈連結串列的構成:
如果把單鏈表的最後一個節點的指標指向連結串列頭部,而不是指向NULL,那麼就構成了一個單向迴圈連結串列。
單向連結串列結構圖示:(以下示意圖均摘自來源: http://blog.csdn.net/fisherwan/ar)
單向迴圈連結串列的初始化:
當單向迴圈連結串列中只有一個節點時,那麼這個節點的next指標指向的就是這個節點本身。 單向迴圈連結串列的建立:
單向迴圈連結串列的建立和單向連結串列很相似,不同的地方是新插入節點的next指向的不再是NULL,而是指向第一個節點。 程式碼如下: 遍歷到連結串列的最後一個節點ptemp; ptemp->next = pnew; pnew->next = head; 單向迴圈連結串列的插入:
單向迴圈連結串列的插入與單向連結串列有所不同,因為單向迴圈連結串列首尾相連,所以沒有從尾部插入的問題。 (1)從連結串列頭部插入 將新插入的節點變為連結串列頭部,next指向原來的第一個節點,在遍歷整個連結串列找到連結串列末尾(即它的next指向的是head的那個節點),將這個節點的next指向新插入的節點,最後再將連結串列頭指標指向新節點。 程式碼如下: pnew->next = head->next; ptemp = head; while(ptemp->next != head) //注意此時的遍歷條件是 ptemp->next != head
ptemp = ptemp->next; //退出while迴圈後ptemp指向連結串列尾部
ptemp->next = pnew; head = pnew; (2)從連結串列中間插入 此時插入的過程和單向連結串列的一樣,找到要插入位置前驅節點ptemp,將新插入節點的next指向ptemp的next,再將ptemp的next指向新插入的節點pnew。 程式碼如下: pnew->next = ptemp->next; ptemp->next = pnew; 以上的順序不能變
單向迴圈連結串列的刪除:
刪除操作與插入操作類似,也分為兩種情況: (1)在連結串列頭部刪除 將連結串列頭指標指向第二個節點,再將最後一個節點的指標指向新插入的節點,最後釋放掉原來第一個節點的記憶體空間 程式碼如下: ptemp = head; first = head;
while(ptemp->next != head) ptemp = ptemp->next; //退出while迴圈後ptemp指向連結串列尾部
head= head->next;//頭指標指向第二個節點 ptemp->next = headt;//指向第二個節點 free(first);//釋放掉原來的第一個節點 (2)在連結串列中間刪除 找到要刪除的連結串列的前驅節點ptr,將ptr的next指向pdelete的next,再釋放掉pdelete的記憶體空間。 程式碼如下: ptr = head; while(ptr->next != del) ptr = ptr->next;//退出迴圈後此時ptr為pdelete的前驅
pdelete = ptr->next; ptr-next = pdelete->next; 單向迴圈連結串列的C語言實現:(codeblocks完美執行)
單向迴圈連結串列的初始化:
當單向迴圈連結串列中只有一個節點時,那麼這個節點的next指標指向的就是這個節點本身。 單向迴圈連結串列的建立:
單向迴圈連結串列的建立和單向連結串列很相似,不同的地方是新插入節點的next指向的不再是NULL,而是指向第一個節點。 程式碼如下: 遍歷到連結串列的最後一個節點ptemp; ptemp->next = pnew; pnew->next = head; 單向迴圈連結串列的插入:
單向迴圈連結串列的插入與單向連結串列有所不同,因為單向迴圈連結串列首尾相連,所以沒有從尾部插入的問題。 (1)從連結串列頭部插入 將新插入的節點變為連結串列頭部,next指向原來的第一個節點,在遍歷整個連結串列找到連結串列末尾(即它的next指向的是head的那個節點),將這個節點的next指向新插入的節點,最後再將連結串列頭指標指向新節點。 程式碼如下: pnew->next = head->next; ptemp = head; while(ptemp->next != head) //注意此時的遍歷條件是
ptemp->next = pnew; head = pnew; (2)從連結串列中間插入 此時插入的過程和單向連結串列的一樣,找到要插入位置前驅節點ptemp,將新插入節點的next指向ptemp的next,再將ptemp的next指向新插入的節點pnew。 程式碼如下: pnew->next = ptemp->next; ptemp->next = pnew; 以上的順序不能變
單向迴圈連結串列的刪除:
刪除操作與插入操作類似,也分為兩種情況: (1)在連結串列頭部刪除 將連結串列頭指標指向第二個節點,再將最後一個節點的指標指向新插入的節點,最後釋放掉原來第一個節點的記憶體空間 程式碼如下: ptemp = head; first = head;
while(ptemp->next != head) ptemp = ptemp->next; //退出while迴圈後ptemp指向連結串列尾部
head= head->next;//頭指標指向第二個節點 ptemp->next = headt;//指向第二個節點 free(first);//釋放掉原來的第一個節點 (2)在連結串列中間刪除 找到要刪除的連結串列的前驅節點ptr,將ptr的next指向pdelete的next,再釋放掉pdelete的記憶體空間。 程式碼如下: ptr = head; while(ptr->next != del) ptr = ptr->next;//退出迴圈後此時ptr為pdelete的前驅
pdelete = ptr->next; ptr-next = pdelete->next; 單向迴圈連結串列的C語言實現:(codeblocks完美執行)
#include <stdlib.h>
#include <stdio.h>
typedef struct circle_list
{
int date;
struct circle_list *next;
}list;
//節點建立函式
list *creat_node()
{
//建立頭節點
list *newnode = (list *)malloc(sizeof(struct circle_list));
if(newnode == NULL)
{
printf("建立頭結點失敗!\n");
}
else
{
newnode->next=NULL;
return newnode;
}
}
//插入資料到連結串列中
int insert_list(list *head)
{
//建立節點
int val;
printf("請輸入要插入的元素:");
scanf("%d",&val);
list *newnode = creat_node();
newnode->date = val;
//判斷頭節點是否為NULL
if(head != NULL)
{
//遍歷頭節點,中間變數P
list *p = head;
//遍歷頭節點到,最後一個數據
while(p->next != head )
{
//錯誤,這樣會改變頭節的位置,必須使用中間變數進行變數
// head = head->next;
p = p->next;
}
//把最後一個節點賦新的節點過去
p->next = newnode;
newnode->next = head;
return 1;
}
else
{
printf("head is NULL\n");
return 0;
}
}
//遍歷連結串列中的資料
int display(list *head)
{
if(head != NULL)
{
//遍歷頭節點,中間變數P
list *p = head;
//遍歷頭節點到,最後一個數據
while(p->next != head )
{
//錯誤,這樣會改變頭節的位置,必須使用中間變數進行變數
// head = head->next;
printf("%d ",p->next->date);
p = p->next;
}
//把最後一個節點賦新的節點過去
return 1;
}
else
{
printf("頭結點為空!\n");
return 0;
}
}
int delete_list(list *head)
{
if(head == NULL)
{
printf("連結串列為空!\n");
return 0;
}
list *temp = head;
list *ptr = head->next;
int del;
printf("請輸入你要刪除的元素:");
scanf("%d",&del);
while(ptr != head)
{
if(ptr->date == del)
{
if(ptr->next == head)//迴圈結束的條件換成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("沒有找到要刪除的元素%d\n",del);
return 0;
}
int update_list(list *head)
{
if(head == NULL)
{
printf("連結串列為空!\n");
return 0;
}
list *temp = head;
int olddate,newdate;
printf("請輸入要修改的元素:");
scanf("%d",&olddate);
printf("修改為:");
scanf("%d",&newdate);
while(temp->next != head)
{
if(temp->next->date == olddate)
{
temp->next->date = newdate;
return 1;
}
temp = temp->next;
}
printf("沒有找到要修改的元素!\n");
return 0;
}
int seek_list(list*head)
{
if(head == NULL)
{
printf("連結串列為空!\n");
return 0;
}
int val,i=0;
printf("請輸入要查詢的元素:");
scanf("%d",&val);
list *p = head;
while(p->next != head)
{
i++;
if(p->next->date == val)
{
printf("找到元素%d,位置在%d\n",val,i);
}
p = p->next;
}
printf("沒有找到該元素!\n");
return 0;
}
void menu()
{
system("cls");//清屏
printf("\t\t|===============================================|\t\t\n");
printf("\t\t|==================單向迴圈操作=================|\t\t\n");
printf("\t\t|===================1.插入元素==================|\t\t\n");
printf("\t\t|===================2.列印連結串列==================|\t\t\n");
printf("\t\t|===================3.刪除元素==================|\t\t\n");
printf("\t\t|===================4.修改連結串列==================|\t\t\n");
printf("\t\t|===================5.查詢元素==================|\t\t\n");
printf("\t\t|==請輸入對應的數字執行對應的功能!(輸入0退出)==|\t\t\n");
printf("\t\t|====== 作者:RXX 時間:2017/07/06 ======|\t\t\n");
printf("\t\t|===============================================|\t\t\n");
}
int main()
{
//建立頭節點
list *head = creat_node();
//讓頭位元組自我迴圈
head->next = head;
int num;
menu();
scanf("%d",&num);
//插入節點
while(num)
{
switch(num)
{
case 1:
{
printf("插入元素操作:\n");
if(insert_list(head))
printf("插入節點成功!\n");
else
printf("插入節點失敗!\n");
break;
}
case 2:
{
printf("列印連結串列操作:\n");
display(head);
break;
}
case 3:
{
if(delete_list(head))
printf("刪除節點成功!\n");
break;
}
case 4:
{
if(update_list(head))
printf("修改元素成功!\n");
break;
}
case 5:
{
if(seek_list(head))
printf("查詢元素成功!\n");
break;
}
}
getch();
menu();
scanf("%d",&num);
//清空快取區
//while(getchar()!='\n');
}
printf("\t\t|================感謝使用!再見!===============|\t\t\n");
return 0;
}
執行介面: