1. 程式人生 > >單向迴圈連結串列的簡單實現

單向迴圈連結串列的簡單實現

單向迴圈連結串列:       在單向連結串列中,頭指標是相當重要的,因為單向連結串列的操作都需要頭指標,所以如果頭指標丟失或者破壞,那麼整個連結串列都會遺失,並且浪費連結串列記憶體空間。 單向迴圈連結串列的構成:       如果把單鏈表的最後一個節點的指標指向連結串列頭部,而不是指向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完美執行)
#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;
}

執行介面: