c語言實現單向迴圈連結串列
//最終保證最後一個節點的後繼指向Head則構成單迴圈連結串列
//不帶頭節點判空: head == NULL
//帶頭節點判空: head->next == head; 為空
//與單鏈表程式碼的區別: 每次迴圈的跳出條件改變,尾插發生改變
//只要程式中插入節點是頭節點, 則必須更新尾節點的指向
//刪除頭節點, 更新尾節點指向, 刪除尾巴節點, 更新前一個節點的指向
建議讀者還是自己從單鏈表到迴圈連結串列手動實現一遍, 迴圈連結串列的道理很簡單
但是其中的許多細節,尤其是插入,刪除,以及頭結點,尾節點的處理等等存在一些難以注意到的問題,還是敲一遍來的實在!
單向迴圈連結串列選擇了單鏈表中的部分功能實現,讀者也可兩者對比來看
單鏈表各種功能的實現:http://blog.csdn.net/hkhl_235/article/details/78196865
主要功能:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> //包含sleep的標頭檔案,用來使程式暫停(linux)windows下可用用#include<windows.h> Sleep(2000); typedef struct node { int no; int age; char sex[5]; char name[20]; struct node *next; }Node; void Print(Node *head); //列印 void CreateNode(Node *head, Node **p, int no, int age, char *sex, char *name);//建立節點 void Add(Node **head, int no, int age, char *sex, char *name); //新增節點 Node *FindNode(Node *head, int no); //根據學號找節點, 沒有返回NULL Node *PrvNode(Node *head, Node *find); //找到前驅節點 void SerchNode(Node *head, int no); //按學號查詢資訊 void Insert(Node **head); //按學號大小有序插入 void HeadInsert(Node **head, int sid); //某個節點前插入(包括頭插) void BackInsert(Node **head, int sid); //某個節點後插入(包括尾插) void DeleteNode(Node **head, int no); //刪除學號為no的節點 void FreeAll(Node **head); //銷燬連結串列 int GetToatalNode(Node *head); //獲取節點總數
函式實現部分:
void Print(Node *head) { Node *first = head; if(head != NULL) { printf("學號 年齡 性別 姓名 下一個指向\n"); while(head != NULL) { printf("%d %d %s %s %p\n", head->no, head->age, head->sex, head->name, head->next); head = head->next; if(head == first) { //sleep(2); 是程式掛起兩秒 //註釋break可以迴圈列印 break ; } } } else { printf("空連結串列哦\n"); } } void CreateNode(Node *head, Node **p, int no, int age, char *sex, char *name) { *p = (Node *)malloc(sizeof(Node)); if(*p != NULL) { (*p)->no = no; (*p)->age = age; strcpy((*p)->sex, sex); strcpy((*p)->name, name); (*p)->next = head; } else { printf("建立節點失敗\n"); } } //為空建立新增節點,, 不為空尾部插入... void Add(Node **head, int no, int age, char *sex, char *name) { Node *h = *head; Node *p; if(*head == NULL) { CreateNode(*head, &p, no, age, sex, name); *head = p; //只有第一次賦值,將頭指標的內容更改 p->next = *head; //第一個節點建立的時候, CreareNode建立節點p的p->next 等於head ,但是此時head是NULL, 所以這裡要再次賦值 .不然執行到A會報錯 } else { CreateNode(*head, &p, no, age, sex, name); while(h->next != *head) //while迴圈條件是(*->next)都將發生改變 { h = h->next; //A, 如果head是NULL, 那麼這裡訪問非法記憶體 } h->next = p; } } //根據學號找到其節點 //沒找到返回NULL Node *FindNode(Node *head, int no) { int flag = 0; Node *first = head; while(head) { if(head->no == no) { flag = 1; break; } head = head->next; if(head == first) { break; } } if(flag == 0) { return NULL; } return head; } //找到前驅節點 Node *PrvNode(Node *head, Node *find) { Node *first = head; while(head) { if(find == head) //如果找頭節點前一個節點 返回頭節點 { break; } if(head->next == find) { break; } head = head->next; if(head == first) { break; } } return head; } //有序插入 按學號由小到大 void Insert(Node **head) { Node *first = *head; printf("請輸入要插入的資訊:\n"); int no; float age; char sex[5]; char name[10]; scanf("%d%f%s%s", &no, &age, sex, name); Node *q; CreateNode(*head, &q, no, age, sex, name); Node *p1 = *head; Node *p2; int flag = 0; while(p1->no <= no) //先判斷是否為NULL { p2 = p1; p1 = p1->next; if(p1 == *head) { flag = 1; break; } } if(p1 == *head && flag != 1) //頭部插入 { q->next = p1; *(head) = q; //尾節點要重新指向新的頭節點 for(; p1->next != first; p1 = p1->next); p1->next = *head; } else if(p1 == *head && flag == 1) //尾部插入 { p2->next = q; q->next = *head; } else //中間插入 { q->next = p2->next; p2->next = q; } } void HeadInsert(Node **head, int sid) //某個節點前插入(包括頭插) { Node *first = *head; printf("請輸入要插入的資訊:\n"); int no; float age; char sex[5]; char name[10]; scanf("%d%f%s%s", &no, &age, sex, name); Node *q; CreateNode(*head, &q, no, age, sex, name); Node *p1 = FindNode(*head, sid); Node *p2 = PrvNode(*head, p1); if(p1 == *head) //頭部插入 { q->next = p1; *(head) = q; //尾節點要重新指向新的頭節點 for(; p1->next != first; p1 = p1->next); p1->next = *head; } else //中間插入 { q->next = p2->next; p2->next = q; } } void BackInsert(Node **head, int sid) //某個節點後插入(包括尾插) { printf("請輸入要插入的資訊:\n"); int no; float age; char sex[5]; char name[10]; scanf("%d%f%s%s", &no, &age, sex, name); Node *q; CreateNode(*head, &q, no, age, sex, name); Node *p1 = FindNode(*head, sid); Node *p2 = p1->next; if(p1->next == *head) //尾部插入 { p1->next = q; q->next = *head; } else //中間插入 { q->next = p1->next; p1->next = q; } } //學號為no的成員刪除 void DeleteNode(Node **head, int no) { Node *first = *head; Node *p1, *p2; p1 = p2 = NULL; p1 = *head; while(p1) //遍歷節點 找到節點 { if(p1->no == no) { break; //如果刪除的是最後一個, 此時p1跳出, p1並不是NULL //所以刪除不用判斷尾節點 } p2 = p1; p1 = p1->next; if(p1 == *head) { break; } } if(p1 == *head) //刪除頭節點 { (*head) = p1->next; //跳過頭節點 //尾節點要重新指向新的頭節點 Node *p = p1; for(; p->next != first; p = p->next); p->next = *head; free(p1); //釋放頭節點 } else //刪除其他節點 { p2->next = p1->next; free(p1); } } void SerchNode(Node *head, int no) //按學號查詢資訊 { Node *sr = FindNode(head, no); if(sr != NULL) { printf("%d %d %s %s %p\n", sr->no, sr->age, sr->sex, sr->name, sr->next); } else { printf("查無此人\n"); } } //刪除所有節點 //最後刪除頭節點 void FreeAll(Node **head) { Node *p1 = *head; Node *p2 = NULL; Node *q = NULL; while(p1->next == *head) { p2 = p1->next; p1->next = p2->next; free(p2); } free(*head); *head = NULL; } int GetToatalNode(Node *head) //獲取節點總數 { int num = 0; Node *first = head; if(head != NULL) { while(head != NULL) { num++; head = head->next; if(head == first) { break; } } } return num; }
下面是測試程式碼:
int main()
{
Node *head = NULL;
Add(&head, 1002, 17, "男", "張2");
Add(&head, 1001, 15, "男", "張1");
Add(&head, 1003, 12, "男", "張3");
Add(&head, 1004, 21, "男", "張4");
Add(&head, 1005, 22, "女", "張5");
Print(head);
printf("刪除學號為1005的的連結串列:\n");
DeleteNode(&head, 1002);
Print(head);
printf("\n統計結點總數為: %d\n\n", GetToatalNode(head));
printf("插入資訊後的連結串列(指定節點插入):\n");
printf("(前插)輸入學號, 年齡, 性別, 姓名:\n");
HeadInsert(&head, 1002);
Print(head);
printf("(後插)輸入學號, 年齡, 性別, 姓名:\n");
BackInsert(&head, 1004);
Print(head);
printf("插入資訊後的連結串列(有序插入):\n");
printf("輸入學號, 年齡, 性別, 姓名:");
Insert(&head);
Print(head);
printf("銷燬後的連結串列:\n");
FreeAll(&head);
Print(head);
return 0;
}
如有問題,歡迎指出,共同進步! 單鏈表各種功能的實現:http://blog.csdn.net/hkhl_235/article/details/78196865
相關推薦
c語言實現單向迴圈連結串列
//單迴圈連結串列, 在單鏈表的基礎上, 每建立一個節點,讓其後繼預設指向head //最終保證最後一個節點的後繼指向Head則構成單迴圈連結串列//不帶頭節點判空: head == NULL //帶頭節點判空: head->next == head; 為空 //與
c語言實現雙向迴圈連結串列
此次工程還是使用了3個原始檔list.h(標頭檔案原始碼),main.c(實現介面的具體程式碼),list.c(單鏈表邏輯) list.h #pragma once #include<stdio.h> #include<stdlib.h> #include
資料結構之鏈式表的實現--單向迴圈連結串列(C語言)
學習參考: 嚴蔚敏: 《資料結構-C語言版》 單向迴圈連結串列的基本操作 單向迴圈連結串列的建立 單向迴圈連結串列新增結點(頭插法) 單向迴圈連結串列新增結點(尾插法) 單向迴圈連結串列
C語言_雙向迴圈連結串列的基本操作
目錄: 1、初始化 2、頭部插入 3、頭部刪除 4、尾部插入 5、尾部刪除 6、列印連結串列 7、任意位置插入 8、查詢值為data的節點 9、指定位置刪除 10、銷燬連結串列 ###1、初始化: 建立一個節點,給節點賦值為0;因為是迴圈連結串列,所以讓它的_pNext
用Python實現單向迴圈連結串列
直接看程式碼,有詳細註解 class Node(object): """節點""" def __init__(self, elem): self.elem = elem self.next = None class SingleCycl
用C語言實現在一個連結串列刪除指定的一個或多個元素
#include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node *next; }LinkList; //建立一個連結串列 LinkL
用C語言實現兩個連結串列查集
#include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node *next; }LinkList; //建立連結串列 LinkLis
演算法精解(二):C語言描述(迴圈連結串列)
迴圈連結串列 顧名思義,首尾相連的連結串列即是迴圈連結串列。可以是單鏈表,也可以是雙鏈表。 迴圈連結串列是另一種形式的連結串列,它提供了更為靈活的遍歷連結串列元素的能力。迴圈連結串列可以是單向的或雙向的,但區分一個連結串列是
python 實現單向迴圈連結串列
單向迴圈連結串列 特點: 若連結串列為空,則頭結點的next結點還是指向其本身,即head.next=head; 尾節點的next指標指向head結點,即頭尾相連; 判斷是否遍歷了完,直接判斷next==head即可; 由單鏈表變化的迴圈也成為單向迴圈連結串列
C語言資料結構----迴圈連結串列
主要講解釋迴圈連結串列的一些定義和具體的操作。 一、基本定義: 1.單鏈表的侷限:不可以迴圈。2.迴圈連結串列的定義:將單鏈表中最後一個元素的next指向第一個元素。3.迴圈連結串列擁有單鏈表的所有操作。4.迴圈連結串列的插入和單鏈表插入的差別:單鏈表的插入是 n
linux 下c語言建立單向動態連結串列的理解
#include <stdio.h> #include <malloc.h> //分配記憶體要加上這個庫函式 struct weapon { int price; int atk; struct weapon* next; }; //建立一個武器
華為面試題——約瑟夫問題的C++簡單實現(迴圈連結串列)
/* author:jiangxin Blog:http://blog.csdn.net/jiangxinnju Function:method of Josephus question */ #include <iostream> us
約瑟夫環(使用C語言單向迴圈連結串列來解決)
題目描述 編號為1,2,…,n的n個人按順時針方向圍坐在一張圓桌周圍,每人持有一個密碼(正整數)。一 開始任選一個正整數m作為報數上限值,從第一個人開始按順時針方向自1開始報數,報到m時停止報數,報m的那 個人出列,將他的密碼作為新的m值,從他順時針方向的下一個人開始重新從1報數,
(C語言版)連結串列(四)——實現雙向迴圈連結串列建立、插入、刪除、釋放記憶體等簡單操作
雙向迴圈連結串列是基於雙向連結串列的基礎上實現的,和雙向連結串列的操作差不多,唯一的區別就是它是個迴圈的連結串列,通過每個節點的兩個指標把它們扣在一起組成一個環狀。所以呢,每個節點都有前驅節點和後繼節點(包括頭節點和尾節點)這是和雙向連結串列不同的地方。我們看下雙向迴圈連結
資料結構(三)——單向迴圈連結串列的java實現
單向迴圈連結串列結構就是連結串列的最後一個指標不再是null,而是指向整個連結串列的第一個結點,使連結串列形成一個環。 上程式碼 package likend; /** * Created by yxf on 2018/3/27. * 單向迴圈連結串列 */ publ
資料結構學習筆記——C++實現雙向迴圈連結串列模板類(超詳解)
定義了兩個標頭檔案分別放置結點類模板(Node.h)和雙鏈表模板(DoubleLinkList.h), 然後在原始檔的main函式中測試。 Node.h #pragma once # include <iostream> template <class
利用單向迴圈連結串列結構實現如下記憶體頁置換策略CLOCK Algorithm
利用單向迴圈連結串列結構實現如下記憶體頁置換策略CLOCK Algorithm: 假設緩衝池有6個緩衝頁,以單向迴圈連結串列結構組織,結構如下圖所示。緩衝池初始狀態:所有緩衝頁可用,指標P指向下一個即將被分配的緩衝頁。緩衝池包含的緩衝頁數作為程式執行引數設定,該引數的有效設
(C++版)連結串列(二)——實現單項迴圈連結串列建立、插入、刪除等操作
連結串列(二)單向迴圈連結串列的實現,下面實現程式碼: #include <iostream> #include <stdlib.h> using namespace std; //結點類 class Node { public:
Java 單向連結串列和單向迴圈連結串列的程式碼實現
這個連結串列,以前上學的時候,學c語言,還是資料結構的時候,學過。也許也實現過吧。下面我就簡單記錄下這個連結串列的實現。 單向連結串列跟單向迴圈連結串列的差別就是:單向連結串列是有結束位的,指向null的時候,就到結尾了,但是單向迴圈連結串列,他就是一個圈,要是不設定指定位
約瑟夫環 單向迴圈連結串列實現
約瑟夫環 已知n個人(以編號1,2,3...n分別表示)圍坐在一張圓桌周圍。從編號為k的人開始報數,數到m的那個人出列;他的下一個人又從1開始報數,數到m的那個人又出列;依此規律重複下去,直到圓桌周圍的人全部出列。 ///迴圈連結串列實現 #include<bits/stdc++.h>