

鏈表的每一個結點中只包含一個指標域
優點 : 儲存空間利用高效
舉例來說:
typedef struct student{ int id; //學生編號 char* name; //學生名稱 //指向下一結點的指標 struct Student* pNext; }Student;與之相反的是多鏈表
typedef struct student{ int id; //學生編號 char* name; //學生名稱 //指向下一結點的指標 struct Student* pNext; struct Student* qNext; }Student;

獲取第i個結點的資料元素
- 宣告一個結點指標p指向鏈表的第一個結點a1,初始化j從1開始
- 當j < i 時,遍歷鏈表,讓p的指標向后移動,不斷指向下一個結點,j 累加 1
- 當鏈表末尾 p 為空時,則說明第 i 個元素不存在;否則查找成功,回傳結點 p 的資料
1,定義資料元素
//定義資料元素 typedef struct student{ int id; char* name; }ElementType;2,定義順序表結構
typedef struct { ElementType dates[MAX_SIZE]; //當前順序表中的資料集合 int length; //當前順序表中的元素個數 }SeqList;3,定義鏈表的結點(包括資料域和指標域)
typedef struct Node { ElementType date; //資料域 struct Node* node; //指標域,指向下一個結點 }Node;4,設定頭結點
我們在定義鏈表時,習慣性的會定義頭結點,以便統一鏈表結點的插入和洗掉操作
typedef struct Linklist { Node* next; //頭指標 int length; }Linklist;
- 如果鏈表有頭結點,next就指向頭結點,沒有就指向第一個結點
- 鏈表的長度初始值為0
插入資料元素
在第i個結點后插入資料元素
- 創建一個空節點,分配記憶體空間,設定資料元素
- 獲取第i個結點,設定新結點的后繼結點為該結點的后繼結點
- 設定第i個結點的后繼結點為該結點
1,創建空節點并為資料域賦值
//創建空節點并為資料賦值 Node* node = (Node*)malloc(sizeof(Node)); node -> date = element; node -> next = NULL;2,通過回圈找到要插入的結點
for (int i = 1; currNode && i < pos - 1; i++) { currNode = currNode->next; }3,將結點插入并對接前面的結點
if (currNode) { node->next = currNode->next; currNode->next = node; linkList->length++; }
初始化鏈表
void InitLinkList(LinkList* linkList, ElementType* dateArrar, int length) { for (int i = 0; i < length; i++) { InsertLinkList(linkList, i + 1, dateArrar[i]); } }列印鏈表
void PrintLinkList(LinkList* linklist) { Node* node = linklist->next; if (!node) { printf("鏈表為空!\n"); linklist->length = 0; return 0; } for (int i = 0; i < linklist->length; i++) { printf("%d\t%s\t\n", node->date.id, node->date.name); node = node->next; } }順序表查空
int IsLinkListEmpty(LinkList* linkList) { return linkList->length == 0 ? TRUE : FALSE; }
順序表的洗掉
洗掉第i個結點及其資料元素
- 獲取第i個結點,若該結點不是第一個結點,則獲取第i - 1個結點
- 將第i -1個結點的后綴結點設為第i個結點的后綴結點
- 洗掉第i個結點,釋放記憶體空間,記錄并回傳洗掉資料元素的值
情況1:當洗掉的是第一個元素
if (pos == 1) { node = linkList->next; if (node) { element = node->date; linkList->next = node->next; free(node); //釋放被洗掉的結點 linkList->length--; } return element; }情況2:除第一個結點外
- 找到要洗掉的結點和他的前綴結點
- 要洗掉結點的next 賦值給前綴結點
- 釋放要洗掉的結點
Node* preNode; //前綴結點 node = linkList->next; for (int i = 1; node && i < pos; i++) { preNode = node; node = node->next; } if (node) { element = node->date; preNode->next = node->next; free(node); linkList->length--; } return element;完整代碼
ElementType DeleteLinkListElement(LinkList* linkList, int pos) { ElementType element; //被洗掉的元素 element.id = -999; //賦一個不可能的值,來判斷洗掉是否成功 Node* node = NULL; if (pos == 1) { node = linkList->next; if (node) { element = node->date; linkList->next = node->next; free(node); //釋放被洗掉的結點 linkList->length--; } } Node* preNode; //前綴結點 node = linkList->next; for (int i = 1; node && i < pos; i++) { preNode = node; node = node->next; } if (node) { element = node->date; preNode->next = node->next; free(node); linkList->length--; } return element; }
洗掉單鏈表整表
- 宣告結點p 和 q
- 將第一個結點賦值給p
- 回圈將下一個結點賦值給q,釋放p,將q賦值給p
![]()
void CleatLinkList(LinkList* linkList) { Node* node = linkList->next; Node* nextNode; while (node) { nextNode = node->next; //先記錄當前結點的下一個結點,以便釋放當前結點的記憶體 free(node); node = nextNode; } linkList->next = NULL; linkList->length = 0; }


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/387285.html
標籤:其他
上一篇:實時視頻服務器 SRS 開源初探








