靜態連結串列 - C語言
阿新 • • 發佈:2020-08-20
#include <stdlib.h> #include <stdio.h> #define STATUS_OK 0 #define STATUS_FAILED -1 // 定義基本資料結構 // 1 利用大陣列定義靜態連結串列,陣列由頭結點,尾結點,已用連結串列,備用連結串列四部分構成 // 2 陣列頭結點:存放連結串列第一個結點的索引值 // 3 陣列尾結點:存放備用連結串列第一個結點的索引值 #define MAXSIZE 10 typedef char ElemType; typedef struct node { ElemType data; int cur; }LNode; // 定義結點名稱 typedef LNode StaticLinkedList[MAXSIZE]; // 定義連結串列名稱 // 常見操作: // init - 核心 // insert - 核心 // delete - 核心 // find // traverse // length // 初始化操作:本質是將一個大陣列賦索引值,形成空的單鏈表的過程 // 賦值過程分為: // a. 頭結點:備用連結串列的頭結點索引位置,賦值為0,尾結點:連結串列的第一個結點的索引,賦值為0 // b. 普通結點:指向陣列下個元素的索引位置,索引值+1 void init(StaticLinkedList list) { for (int i = 0; i < MAXSIZE - 1; i++) { list[i].cur = i + 1; // 各個結點的指標指向下一陣列序號 } list[MAXSIZE - 1].cur = 0; } // 申請記憶體空間操作: // 1 本質是將備用連結串列第一個結點取出,並更新備用連結串列第一個結點的指向 int malloc_node(StaticLinkedList list) { int p = list[0].cur; // 備用連結串列第一個結點的索引 printf("malloc_node-1-p索引值:%d\n", p); if (list[0].cur) { // 是否非0,初始化以後,除了陣列最後一個結點,都是非零。排除陣列尾結點 list[0].cur = list[p].cur; // 更新備用連結串列頭結點索引 } return p; } // 釋放操作: // 1 本質是將結點新增到備用連結串列的過程 void free_node(StaticLinkedList list, int k) // 結點釋放後,放到備用連結串列的第一個結點位置。頭插法 { printf("free_node-1-p索引值:%d\n", list[0].cur); list[k].cur = list[0].cur; // 原第一結點的指向賦給k結點的指向 list[0].cur = k; // 更新第一結點指向為索引值k printf("free_node-2-p索引值:%d\n", list[0].cur); } // 插入操作:在初始化形成的空靜態連結串列基礎上進行插入 // 步驟: // 1 從備用連結串列中拿出一個結點---->自定義malloc函式 // 2 將拿出的結點賦值後,連結到連結串列指定位置 int insert(StaticLinkedList list, int k, ElemType x) { if (k < 1 || k > length(list) + 1) return; int p = MAXSIZE - 1; int j = malloc_node(list); if (j) { // 排除陣列尾結點 list[j].data = x; for (int i = 1; i < k; i++) { // for迴圈執行1次,p指向第1個元素的索引 p = list[p].cur; } list[j].cur = list[p].cur; list[p].cur = j; return STATUS_OK; } return STATUS_FAILED; } // 刪除結點: // 1 找到該結點前一結點k-1, 將k+1結點的索引賦給k-1的向量 // 2 釋放k結點 void delete_node(StaticLinkedList list, int k) { if (k < 1 || k > length(list)) return; int p = MAXSIZE - 1; for (int i = 1; i < k; i++) { p = list[p].cur; } // for迴圈結束後,p為k-1結點的index值 int q = list[p].cur; // q 為第k個結點 list[p].cur = list[q].cur; // k+1 指向賦給 k-1 free_node(list, q); } // 遍歷連結串列 // 1 從第一個結點【陣列尾結點所指向的結點】開始,依次遍歷每個結點的數值 void traverse(StaticLinkedList list) { int p = list[MAXSIZE - 1].cur; // 連結串列第一個結點的索引 while (p > 0) { printf("索引值:%d, 指標向量值:%d, 資料值:%c\n", p, list[p].cur, list[p].data); p = list[p].cur; } } int length(StaticLinkedList list) { int j = 0; int p = list[MAXSIZE - 1].cur; // 連結串列第一個結點的索引 while (p > 0) { p = list[p].cur; j++; } return j; } void traverseArray(StaticLinkedList list) { for (int i = 1; i < MAXSIZE; i++) { printf("索引值:%d, 指標向量值:%d, 資料值: %c\n", i, list[i].cur, list[i].data); } } int main() { StaticLinkedList list; int status; init(list); printf("Init finished, static link list length:%d \n", length(list)); insert(list, 1, 'A'); insert(list, 2, 'B'); insert(list, 3, 'C'); insert(list, 4, 'D'); insert(list, 5, 'E'); insert(list, 6, 'F'); insert(list, 7, 'G');/* insert(list, 8, 'H'); insert(list, 9, 'I'); insert(list, 10, 'K'); insert(list, 11, 'G');*/ traverseArray(list); /*printf("=========================分割線=========================\n"); insert(list, 4, 'N'); traverse(list); traverseArray(list);*/ printf("=========================分割線=========================\n"); delete_node(list, 2); traverseArray(list); printf("=========================分割線=========================\n"); traverse(list); }