您的位置:首頁>正文

資料結構|圖解單鏈表的創建、插入、刪除、銷毀操作

單鏈表是一種線性資料結構, 與順序表佔據一段連續的記憶體空間不同, 鏈表是用一組位址任意的存儲單元來存儲資料, 每個存儲單元分散在記憶體的任意位址上, 存儲單元之間用指標連接。 在鏈表中, 每個資料元素都存放到鏈表的一個結點 , 結點之間由指標串聯在一起, 這樣就形成了一條如同“鏈”的結構, 故稱作鏈表。

通過下面的代碼可定義一個單鏈表:

typedef struct node{

ElemType data; //資料欄

struct node * next; //指針域

} LNode,*LinkList;

其實上面這段代碼定義的是一個單鏈表的結點。 每一個結點包括兩部分:資料欄和指針域。 其中資料欄用來存放資料元素本身的資訊,

指標域用來存放後繼結點的地址。

上面使用typedef將結構體struct node定義為LNode類型, 表示鏈表中每個結點的類型為LNode, 它等價於結構體類型struct node。 另外, *LinkList是指向LNode類型的指標類型, 當定義一個指向LNode類型資料的指標變數時, LNode *L與LinkList L是等價的。

一個鏈表只要得到了頭指標就可以操作鏈表上的每一個結點, 因此把LinkList類型抽象地看作是單鏈表類型。 也就是說, 只要得到了LinkList類型的鏈表頭結點指標, 就可以操作整個單鏈表。

單鏈表的操作包括單鏈表的創建、結點插入、刪除、鏈表銷毀等, 下以的實例就包括了這些方面的操作。

先看運行效果:

代碼:

對於線性表(順序表和單鏈表)的遍歷, 注意指標移動的細微區別。 在順序表中, 申請一個指標p後, p指示資料元素的存儲位置, 用*p可取得該資料的值, 用p++可以順序進到物理上下一個元素的位置。 在單鏈表的情形下, 指針p指示鏈表的結點位址, 用*p不能取得該結點數據的值, 用p++也不能進到下一個結點位置, 只能使用p->data取得結點數據的值, 用p=p->next進到下一個結點。

結點元素的插入,分為兩種情況:

I 插入到單鏈表的最前面:

II 插入到中間位置:

結點元素的刪除,也分兩種情況:

如果是刪除頭節點,只需要將將頭節點的next指針賦值給單鏈表指針即可:*list = q->next;

如果是刪除中間位置的節點:

源碼:

#include "stdio.h"

#include "malloc.h"

typedef struct node{

int data;

struct node *next;

}LNode,*LinkList;

LinkList GreatLinkList(int n)

{

/*建立一個長度為n的鏈表*/

LinkList p, r, list = NULL;

int e;

int i;

for (i=1;i<=n;i++){

printf("請輸入第%d個結點值(共%d)個:",i,n);

scanf("%d",&e);/*獲取鏈表結點中的資料元素*/

p=(LinkList)malloc(sizeof(LNode));/*分配一個新的鏈表結點*/

p->data=e;

p->next=NULL;

if (list == NULL) {

list = p;/*list指向第一個結點,list是頭指標*/

} else {

r->next = p;/*將新結點連接到鏈表的尾部*/

}

r = p;/*指標r始終指向鏈表的最後一個結點*/

}

return list;/*返回鏈表的頭指針*/

}

void insertListInOrder(LinkList *list,int e)

{

/*向按值有序(遞增序列)的鏈表list中插入包含元素e的結點*/

LinkList p, q, r;

q = *list;

p=(LinkList)malloc(sizeof(LNode));/*生成一個新結點,由p指向它*/

p->data=e;/*向該結點的資料欄賦值e*/

if (*list == NULL || e < (*list)->data) {

p->next = *list;

*list = p;

} else {

while(q != NULL && e >= q->data) {/*迴圈找到插入結點的位置*/

r = q;/*r指向q的前驅結點*/

q = q->next;/*q指標向後移動*/

}

p->next= q; /*插入新的結點*/

r->next = p;

}

}

void delLink(LinkList *list, LinkList q) {

LinkList r;

if (q == *list) {

*list = q->next;/*如果q指向的結點即為第1個結點,則需要修改list的值*/

free(q);/*釋放被刪除結點的空間*/

} else {

r = *list;

while ((r->next != q)&&(r->next != NULL)) {

r = r->next;/*通過迴圈找到q所指結點的前驅結點*/

}

if (r->next != NULL) {

r->next = q->next;/*刪除q所指向的結點*/

free(q);/*釋放被刪除結點的空間*/

}

}

}

void deleteLinkList(LinkList *list) {

LinkList p = *list;/*p指向第一個結點*/

while (p != NULL) {

*list = p ->next;/* list指向p的下一個結點 */

free(p);/*釋放掉p指向結點的記憶體空間*/

p = *list;/*p再指向第一個結點*/

}

}

void printLink(LinkList list) {

while (list != NULL) {

printf("%3d",list->data);/*列印出每個結點中的資料data*/

list = list->next;

}

printf(" ");

}

void main() {

int i;

LinkList q,list = NULL;

list = GreatLinkList(10); /*創建一個長度為10的鏈表*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("插入元素3 ");

insertListInOrder(&list,3);/*插入元素3*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("插入元素0 ");

insertListInOrder(&list,0);/*插入元素0*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("插入元素11 ");

insertListInOrder(&list,11);/*插入元素10*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("刪除鏈表中的第5個元素: ");

q=list;

for (i=0; i<4; i++) {

q = q->next;/*指標q指向鏈表中第5個元素*/

}

delLink(&list, q);/*刪除q指向的結點*/

printLink(list);/*列印出鏈表中的內容*/

deleteLinkList(&list);/*銷毀該鏈表*/

if (list == NULL) {

printf( " This Linklist have been deleted ");

}

system("pause");

}

-End-

結點元素的插入,分為兩種情況:

I 插入到單鏈表的最前面:

II 插入到中間位置:

結點元素的刪除,也分兩種情況:

如果是刪除頭節點,只需要將將頭節點的next指針賦值給單鏈表指針即可:*list = q->next;

如果是刪除中間位置的節點:

源碼:

#include "stdio.h"

#include "malloc.h"

typedef struct node{

int data;

struct node *next;

}LNode,*LinkList;

LinkList GreatLinkList(int n)

{

/*建立一個長度為n的鏈表*/

LinkList p, r, list = NULL;

int e;

int i;

for (i=1;i<=n;i++){

printf("請輸入第%d個結點值(共%d)個:",i,n);

scanf("%d",&e);/*獲取鏈表結點中的資料元素*/

p=(LinkList)malloc(sizeof(LNode));/*分配一個新的鏈表結點*/

p->data=e;

p->next=NULL;

if (list == NULL) {

list = p;/*list指向第一個結點,list是頭指標*/

} else {

r->next = p;/*將新結點連接到鏈表的尾部*/

}

r = p;/*指標r始終指向鏈表的最後一個結點*/

}

return list;/*返回鏈表的頭指針*/

}

void insertListInOrder(LinkList *list,int e)

{

/*向按值有序(遞增序列)的鏈表list中插入包含元素e的結點*/

LinkList p, q, r;

q = *list;

p=(LinkList)malloc(sizeof(LNode));/*生成一個新結點,由p指向它*/

p->data=e;/*向該結點的資料欄賦值e*/

if (*list == NULL || e < (*list)->data) {

p->next = *list;

*list = p;

} else {

while(q != NULL && e >= q->data) {/*迴圈找到插入結點的位置*/

r = q;/*r指向q的前驅結點*/

q = q->next;/*q指標向後移動*/

}

p->next= q; /*插入新的結點*/

r->next = p;

}

}

void delLink(LinkList *list, LinkList q) {

LinkList r;

if (q == *list) {

*list = q->next;/*如果q指向的結點即為第1個結點,則需要修改list的值*/

free(q);/*釋放被刪除結點的空間*/

} else {

r = *list;

while ((r->next != q)&&(r->next != NULL)) {

r = r->next;/*通過迴圈找到q所指結點的前驅結點*/

}

if (r->next != NULL) {

r->next = q->next;/*刪除q所指向的結點*/

free(q);/*釋放被刪除結點的空間*/

}

}

}

void deleteLinkList(LinkList *list) {

LinkList p = *list;/*p指向第一個結點*/

while (p != NULL) {

*list = p ->next;/* list指向p的下一個結點 */

free(p);/*釋放掉p指向結點的記憶體空間*/

p = *list;/*p再指向第一個結點*/

}

}

void printLink(LinkList list) {

while (list != NULL) {

printf("%3d",list->data);/*列印出每個結點中的資料data*/

list = list->next;

}

printf(" ");

}

void main() {

int i;

LinkList q,list = NULL;

list = GreatLinkList(10); /*創建一個長度為10的鏈表*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("插入元素3 ");

insertListInOrder(&list,3);/*插入元素3*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("插入元素0 ");

insertListInOrder(&list,0);/*插入元素0*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("插入元素11 ");

insertListInOrder(&list,11);/*插入元素10*/

printf("The elems of this linklist is ");

printLink(list); /*列印出鏈表的內容*/

printf("刪除鏈表中的第5個元素: ");

q=list;

for (i=0; i<4; i++) {

q = q->next;/*指標q指向鏈表中第5個元素*/

}

delLink(&list, q);/*刪除q指向的結點*/

printLink(list);/*列印出鏈表中的內容*/

deleteLinkList(&list);/*銷毀該鏈表*/

if (list == NULL) {

printf( " This Linklist have been deleted ");

}

system("pause");

}

-End-

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示