連結串列(C語言)刪除、插入(頭插法)、清空等操作
阿新 • • 發佈:2018-12-13
幾個重要知識點: 一:
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
在給節點分配記憶體後,一定要將next指標賦值為null。 二:
Status ListInsert(LinkList &L, int i, ElemType e)
為什麼有些函式引數前帶&號? 答:&是取地址的意思,傳遞變數的指標,使形參得到一個變數的地址,這時形參指標變數指向實參變數單元。如果我們在函式中對帶有&號的變數進行更改,那麼主函式相應變數的值也會隨之更改。 三:
typedef struct LNode { ElemType data; struct LNode *next; }LNode,*LinkList;
定義節點時,LNode* p 和 LinkList p 的意思是一樣的。 四:
Status ClearList(LinkList &L)//清除連結串列的資料,連結串列的頭還在,可以繼續插入節點 { LNode *p = L->next;//p指向頭結點的下一個節點 LNode *q;//q為哨兵 if (L == NULL)return ERROR; while (p!=NULL) { q = p->next;//q指向p的下一個節點 free(p); //清除p p = q; //再將p指向q } L->next = NULL; return OK; }
迴圈體為什麼不能寫成 free§;p=p->next呢? 答:這樣寫是錯的,p指標的資料域和指標域已經被釋放了,不存在p=p->next。 清空操作先保留了連結串列的頭,然後把頭後面的所有的都銷燬,最後把頭指標的指標域指向NULL,這樣就相當與清空了,但這個連結串列還在,還可以繼續使用;保留了頭,後面的全部釋放。
程式碼如下:
#include<stdio.h> #include<stdlib.h> #define TRUE 1; #define FALSE 0; #define OK 1; #define ERROR 0; #define OVERFLOW -2; typedef int Status; typedef int ElemType; typedef struct LNode { ElemType data; struct LNode *next; }LNode,*LinkList; void CreateList(LinkList &L,int n) { L = (LinkList)malloc(sizeof(LNode)); L->next = NULL; for (int i= n; i>0; i--) { LNode *p = (LinkList)malloc(sizeof(LNode)); scanf_s("%d",&p->data); p->next = L->next; L->next = p; } } Status ListInsert(LinkList &L, int i, ElemType e)//在頭節點的單鏈線性表中第i個位置之前插入元素e { LinkList p = L; int j = 0; while (p&&j<i-1)//尋找第i-1個節點 { p = p->next; ++j; } if (!p || j > i - 1) return ERROR; LNode *s = (LinkList)malloc(sizeof(LNode));//生成新節點 s->data = e; s->next = p->next; //插入L中,p的地址就是L的地址,插入p相當於插入L p->next = s; return OK; } void OutputList(LinkList L) { LNode *p = L->next; while (p) { printf("%d\n",p->data); p = p->next; } } Status GetElem(LinkList L,int i,ElemType &e) { LNode *p = L->next; //初始化p指向第一個節點 int j = 1; //計數器,計算查詢次數 while (p&&j<i) //順時針向後查詢,直到p指向第i個元素或p為空 { p = p->next; ++j; } if (!p || j > i) return ERROR; e = p->data; return OK; } Status ListDelete(LinkList &L, int i, ElemType &e)//在帶頭結點的單鏈線性表L中刪除第i個元素,並用e返回其值 { LinkList p = L; int j = 0; while (p->next&&j < i - 1)//尋找第i個節點 { p = p->next; ++j; } if (!(p->next) || j > i - 1) return ERROR;//刪除位置不合理 LNode *q = p->next; p->next = q->next; e = q->data; free(q);//釋放q節點 } Status ClearList(LinkList &L)//清除連結串列的資料,連結串列的頭還在,可以繼續插入節點 { LNode *p = L->next;//p指向頭結點的下一個節點 LNode *q;//q為哨兵 if (L == NULL)return ERROR; while (p!=NULL) { q = p->next;//q指向p的下一個節點 free(p); //清除p p = q; //再將p指向q } L->next = NULL; return OK; } Status ListLength(LinkList L)//求連結串列表長 { LNode *p = L->next; int j = 0; while (p) { p = p->next; j++; } return j; } int main() { LinkList L; CreateList(L,4); printf("表中的元素依次為:\n"); OutputList(L); ElemType e; GetElem(L,2,e); printf("第二個元素為:%d\n",e); printf("將101插入表中第二個位置:\n"); ListInsert(L,2,101); OutputList(L); printf("刪除第三個元素:\n"); ListDelete(L,3,e); OutputList(L); printf("連結串列長度為:%d\n",ListLength(L)); ClearList(L); printf("清除資料後的連結串列長度為:%d\n", ListLength(L)); system("pause"); }
程式碼參考《資料結構》(C語言)嚴蔚敏版,轉載請標明出處。