日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux C 数据结构---单向链表

發(fā)布時(shí)間:2023/12/9 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux C 数据结构---单向链表 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線性表存儲(chǔ)結(jié)構(gòu)分為順序存儲(chǔ)、鏈?zhǔn)酱鎯?chǔ)。

???????順序存儲(chǔ)的優(yōu)點(diǎn):

?????? 順序存儲(chǔ)的缺點(diǎn):

???????鏈表就是典型的鏈?zhǔn)酱鎯?chǔ),將線性表L = (a0,a1,a2,........an-1)中個(gè)元素分布在存儲(chǔ)器的不同存儲(chǔ)塊,成為結(jié)點(diǎn)(Node),通過地址或指針建立他們之間的練習(xí),所得到的存儲(chǔ)結(jié)構(gòu)為鏈表結(jié)構(gòu)。表中元素ai的結(jié)點(diǎn)形式如下:

其中,結(jié)點(diǎn)的data域存放數(shù)據(jù)元素ai,而next域是一個(gè)指針,指向ai的直接后繼a(i+1)所在的結(jié)點(diǎn)。于是,線性表L=(a0,a1,......an-1)的結(jié)構(gòu)如圖:

?

一、節(jié)點(diǎn)類型描述:

[cpp]?view plaincopy
  • typedef?struct?node_t??
  • {??
  • ????data_t?data;?//節(jié)點(diǎn)的數(shù)據(jù)域??
  • ????struct?node_t?*next;//節(jié)點(diǎn)的后繼指針域??
  • }linknode_t,*linklist_t;??
  • 也可這樣表示:

    [cpp]?view plaincopy
  • struct?node_t??
  • {??
  • ????data_t?data;???
  • ????struct?node_t?*next;??
  • }??
  • typedef?struct?node_t?linknode_t;??
  • typedef?struct?node_t?*linklist_t;??
  • 若說明

    linknode_t? A;

    linklist_t p? = &A;

    則結(jié)構(gòu)變量A為所描述的節(jié)點(diǎn),而指針變量P為指向此類型節(jié)點(diǎn)的指針(p的值為節(jié)點(diǎn)的地址);

    這樣看來 linknode_t? linklist_t 的作用是一樣的,那為什么我們要定義兩個(gè)數(shù)據(jù)類型(同一種)呢?主要為了代碼的可讀性,我們要求標(biāo)識(shí)符要望文識(shí)義,便于理解;

    1、linknode_t? *pnode? 指向一個(gè)節(jié)點(diǎn);

    2、linklist_t list? 指向一個(gè)整體


    二、頭結(jié)點(diǎn) head

    ??????? 我們?cè)谇捌岬降捻樞虼鎯?chǔ)線性表,如何表達(dá)一個(gè)空表{ },是通過list->last = -1來表現(xiàn)的,所謂的空表就是數(shù)據(jù)域?yàn)镹ULL,而我們的鏈表有數(shù)據(jù)域和指針域,我們?nèi)绾伪憩F(xiàn)空鏈表呢?這時(shí),就引入了頭結(jié)點(diǎn)的概念,頭結(jié)點(diǎn)和其他節(jié)點(diǎn)數(shù)據(jù)類型一樣,只是數(shù)據(jù)域?yàn)镹ULL,head->next = NULL,下面我們看一個(gè)創(chuàng)建空鏈表的函數(shù),如何利用頭結(jié)點(diǎn)來創(chuàng)建一個(gè)空鏈表:

    [cpp]?view plaincopy
  • linklist_t?CreateEmptyLinklist()??
  • {??
  • ????linklist_t?list;??
  • ??
  • ????list?=?(linklist_t)malloc(sizeof(linknode_t));??
  • ????if?(NULL?!=?list)?{??
  • ????????list->next?=?NULL;??
  • ????}??
  • ????return?list;??
  • }??
  • 只要頭結(jié)點(diǎn),鏈表就還在!

    ?

    三、鏈表基本運(yùn)算的相關(guān)算法

    ???????? 鏈表的運(yùn)算除了上面的創(chuàng)建空鏈表,還有數(shù)據(jù)的插入,刪除,查找等函數(shù),鏈表的運(yùn)算有各種實(shí)現(xiàn)方法,如何寫出一個(gè)高效的,封裝性較好的函數(shù)是我們要考慮的,比如數(shù)據(jù)插入函數(shù),我們就要盡可能考慮所有能出現(xiàn)的結(jié)果,比如:1)如果需插入數(shù)據(jù)的鏈表是個(gè)空表;2)所插入的位置超過了鏈表的長(zhǎng)度;如果我們的函數(shù)能包含所有能出現(xiàn)的情況,不僅能大大提高我們的開發(fā)效率,也會(huì)減少代碼的錯(cuò)誤率。下面,我們來看看下面的這個(gè)鏈表的插入函數(shù)的實(shí)現(xiàn):

    [cpp]?view plaincopy
  • int?InsertLinklist(linklist_t?list,?int?at,?data_t?x)??
  • {??
  • ????linknode_t?*node_prev,?*node_at,?*node_new;??
  • ????int?pos_at;??
  • ????int?found?=?0;??
  • ??
  • ????if?(NULL?==?list)?return?-1;??
  • ??
  • ????/*?at?must?>=?0??*/??
  • ????if?(at?<?0)?return?-1;??
  • ??????
  • ????/*第一步、分配空間*/??
  • ????node_new?=?malloc(sizeof(linknode_t));??
  • ????if?(NULL?==?node_new)???
  • ????{??
  • ????????return?-1;??
  • ????}??
  • ????node_new->data?=?x;?/*?assigned?value?*/??
  • ????node_new->next?=?NULL;?/*節(jié)點(diǎn)如果插入超過鏈表長(zhǎng)度的位置,會(huì)接到尾節(jié)點(diǎn)后面,這樣,node_new成了尾節(jié)點(diǎn),node_new->next?=?NULL?*/??
  • ??
  • ????/*第二步、定位*/??
  • ????node_prev?=?list;//跟隨指針,幫助我們更好的定位??
  • ????node_at?=?list->next;?//遍歷指針??
  • ????pos_at?=?0;??
  • ????while?(NULL?!=?node_at)???
  • ????{??
  • ????????if?(pos_at?==?at)??
  • ????????{??
  • ????????????found?=?1;?//找到正確的位置,跳出循環(huán)??
  • ????????????break;????????????
  • ????????}??
  • ??
  • ????????/*?move?to?the?next?pos_at?*/??
  • ????????node_prev?=?node_at;?//跟隨指針先跳到遍歷指針的位置??
  • ????????node_at?=?node_at->next;//遍歷指針跳到下一個(gè)節(jié)點(diǎn)的位置??
  • ????????pos_at++;??
  • ????}??
  • ??
  • ????/*第三步、插入*/????
  • ????if?(found)???
  • ????{??
  • ????????/*?found?=?1,找到正確的位置,插入??*/??
  • ????????node_new->next?=?node_at;//插入的節(jié)點(diǎn)next指向node_at??
  • ????????node_prev->next?=?node_new;//插入節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)??
  • ????}???
  • ????else???
  • ????{??
  • ????????/*若是沒找到正確的位置,即所插入位置超越了鏈表的長(zhǎng)度,則接到尾節(jié)點(diǎn)的后面,同樣,這樣適用于{?}即空鏈表,這樣我們可以建立一個(gè)空鏈表,利用這個(gè)函數(shù),實(shí)現(xiàn)鏈表的初始化*/??
  • ????????node_prev->next?=?node_new;??
  • ????}??
  • ??????
  • 這個(gè)插入函數(shù)可利用性就非常高。

    ?

    下面講一個(gè)完整鏈表代碼貼出:

    listlink.h

    [cpp]?view plaincopy
  • #ifndef?_LNK_LIST_H_??
  • #define?_LNK_LIST_H_??
  • ??
  • typedef?int?data_t;??
  • ??
  • typedef?struct?node_t?{??
  • ????data_t?data;??
  • ????struct?node_t?*next;??
  • }?linknode_t,?*linklist_t;??
  • ??
  • linklist_t?CreateEmptyLinklist();??
  • ??
  • void?DestroyLinklist(linklist_t?list);??
  • ??
  • void?ClearLinklist(linklist_t?list);??
  • ??
  • int?EmptyLinklist(linklist_t?list);??
  • ??
  • int?LengthLinklist(linklist_t?list);??
  • ??
  • int?GetLinklist(linklist_t?list,?int?at,?data_t?*x);??
  • ??
  • int?SetLinklist(linklist_t?list,?int?at,?data_t?x);??
  • ??
  • int?InsertLinklist(linklist_t?list,?int?at,?data_t?x);??
  • ??
  • int?DeleteLinklist(linklist_t?list,?int?at);??
  • ??
  • linklist_t?ReverseLinklist(linklist_t?list);??
  • ??
  • #endif?/*?_LNK_LIST_H_?*/??
  • linklist.c

    [cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?"linklist.h"??
  • ??
  • linklist_t?CreateEmptyLinklist()??
  • {??
  • ????linklist_t?list;??
  • ????list?=?(linklist_t)malloc(sizeof(linknode_t));??
  • ??
  • ????if?(NULL?!=?list)?{??
  • ????????list->next?=?NULL;??
  • ????}??
  • ??
  • ????return?list;??
  • }??
  • ??
  • void?DestroyLinklist(linklist_t?list)??
  • {??
  • ????if?(NULL?!=?list)?{??
  • ????????ClearLinklist(list);??
  • ????????free(list);??
  • ????}??
  • }??
  • ??
  • void?ClearLinklist(linklist_t?list)??
  • {??
  • ????linknode_t?*node;?/*?pointer?to?the?node?to?be?removed?*/??
  • ????if?(NULL?==?list)?return;??
  • ??
  • ????while?(NULL?!=?list->next)?{??
  • ????????node?=?list->next;??
  • ????????list->next?=?node->next;??
  • ????????free(node);??
  • ????}??
  • ????return;??
  • }??
  • ??
  • int?LengthLinklist(linklist_t?list)??
  • {??
  • ????int?len?=?0;??
  • ????linknode_t?*node;?//iterate?pointer??
  • ??
  • ????if?(NULL?==?list)?return?-1;??
  • ??
  • ????node?=?list->next;?//?node?points?to?the?first?data?node??
  • ????while?(NULL?!=?node)?{??
  • ????????len++;??
  • ????????node?=?node->next;??
  • ????}??
  • ????return?len;??
  • }??
  • ??
  • int?EmptyLinklist(linklist_t?list)??
  • {??
  • ????if?(NULL?!=?list)?{??
  • ????????if?(NULL?==?list->next)?{??
  • ????????????return?1;??
  • ????????}?else?{??
  • ????????????return?0;??
  • ????????}??
  • ????}?else?{??
  • ????????return?-1;??
  • ????}??
  • }??
  • ??
  • int?GetLinklist(linklist_t?list,?int?at,?data_t?*x)??
  • {??
  • ????linknode_t?*node;???/*?used?for?iteration?*/??
  • ????int?pos;????????/*?used?for?iteration?and?compare?with?*/??
  • ??
  • ????if?(NULL?==?list)?return?-1;??
  • ????/*?at?must?>=?0?*/??
  • ????if?(at?<?0)?return?-1;??
  • ????/*?start?from?the?first?element?*/??
  • ????node?=?list->next;??
  • ????pos?=?0;??
  • ????while?(NULL?!=?node)?{??
  • ????????if?(at?==?pos)?{??
  • ????????????if?(NULL?!=?x)?{??
  • ????????????????*x?=?node->data;??
  • ????????????}??
  • ????????????return?0;?????????????
  • ????????}??
  • ????????/*?move?to?the?next?*/??
  • ????????node?=?node->next;??
  • ????????pos++;??
  • ????}??
  • ????return?-1;??
  • }??
  • ??
  • ??
  • ??
  • int?SetLinklist(linklist_t?list,?int?at,?data_t?x)??
  • {??
  • ????linknode_t?*node;?/*?used?for?iteration?*/??
  • ????int?pos;??
  • ????int?found?=?0;??
  • ??
  • ????if?(!list)?return?-1;??
  • ????/*?at?must?>=?0?*/??
  • ????if?(at?<?0)?return?-1;??
  • ????/*?start?from?the?first?element?*/??
  • ????node?=?list->next;??
  • ????pos?=?0;??
  • ????while?(NULL?!=?node)?{??
  • ????????if?(at?==?pos)?{???
  • ????????????found?=?1;?/*?found?the?position?*/??
  • ????????????node->data?=?x;??
  • ????????????break;????????????
  • ????????}??
  • ????????/*?move?to?the?next?*/??
  • ????????node?=?node->next;??
  • ????????pos++;??
  • ????}??
  • ????if?(1?==?found)?{??
  • ????????return?0;??
  • ????}?else?{??
  • ????????return?-1;??
  • ????}??
  • }??
  • ??
  • int?InsertLinklist(linklist_t?list,?int?at,?data_t?x)??
  • {??
  • ????/*??
  • ?????*?node_at?and?pos_at?are?used?to?locate?the?position?of?node_at.?
  • ?????*?node_prev?follows?the?node_at?and?always?points?to?previous?node??
  • ?????*??of?node_at.?
  • ?????*?node_new?is?used?to?point?to?the?new?node?to?be?inserted.?
  • ?????*/??
  • ????linknode_t??*node_prev,?*node_at,?*node_new;??
  • ????int?????pos_at;??
  • ????int?????????found?=?0;??
  • ??
  • ????if?(NULL?==?list)?return?-1;??
  • ??
  • ????/*?at?must?>=?0?*/??
  • ????if?(at?<?0)?return?-1;??
  • ??
  • ????node_new?=?malloc(sizeof(linknode_t));??
  • ????if?(NULL?==?node_new)?{??
  • ????????return?-1;??
  • ????}??
  • ????node_new->data?=?x;?/*?assigned?value?*/??
  • ????node_new->next?=?NULL;??
  • ??
  • ????node_prev?=?list;??
  • ????node_at?=?list->next;??
  • ????pos_at?=?0;??
  • ????while?(NULL?!=?node_at)?{??
  • ????????if?(pos_at?==?at)?{??
  • ????????????/*??
  • ?????????????*?found?the?node?'at'?
  • ?????????????*/???
  • ????????????found?=?1;??
  • ????????????break;????????????
  • ????????}??
  • ????????/*?move?to?the?next?pos_at?*/??
  • ????????node_prev?=?node_at;??
  • ????????node_at?=?node_at->next;??
  • ????????pos_at++;??
  • ????}??
  • ??????
  • ????if?(found)?{??
  • ????????/*?insert?*/??
  • ????????node_new->next?=?node_at;??
  • ????????node_prev->next?=?node_new;??
  • ????}?else?{??
  • ????????/*??
  • ?????????*?If?not?found,?means?the?provided?"at"?
  • ?????????*?exceeds?the?upper?limit?of?the?list,?just??
  • ?????????*?append?the?new?node?to?the?end?of?the?list.?
  • ?????????*/??
  • ????????node_prev->next?=?node_new;??
  • ????}??
  • ????return?0;??
  • }??
  • ??
  • int?DeleteLinklist(linklist_t?list,?int?at)??
  • {??
  • ????/*??
  • ?????*?node_at?and?pos_at?are?used?to?locate?the?position?of?node_at.?
  • ?????*?node_prev?follows?the?node_at?and?always?points?to?previous?node??
  • ?????*??of?node_at.?
  • ?????*/??
  • ??
  • ????linknode_t??*node_prev,?*node_at;??
  • ????int?????pos_at;??
  • ????int?????????found?=?0;??
  • ??
  • ????if?(!list)?return?-1;??
  • ????/*?at?must?>=?0?*/??
  • ????if?(at?<?0)?return?-1;??
  • ??
  • ????node_prev?=?list;??
  • ????node_at?=?list->next;??
  • ????pos_at?=?0;???
  • ??
  • ????while?(NULL?!=?node_at)?{??
  • ????????if?(pos_at?==?at)?{??
  • ????????????/*??
  • ?????????????*?found?the?node?'at'?
  • ?????????????*/???
  • ????????????found?=?1;??
  • ????????????break;????????????
  • ????????}??
  • ????????/*?move?to?the?next?pos_at?*/??
  • ????????node_prev?=?node_at;??
  • ????????node_at?=?node_at->next;??
  • ????????pos_at++;??
  • ????}??
  • ????if?(found)?{??
  • ????????/*?remove?*/??
  • ????????node_prev->next?=?node_at->next;??
  • ????????free(node_at);??
  • ????????return??0;??
  • ????}?else?{??
  • ????????return?-1;??
  • ????}??
  • }??
  • ??
  • linklist_t?ReverseLinklist(linklist_t?list)??
  • {??
  • ????linknode_t?*node;???/*?iterator?*/??
  • ????linknode_t?*node_prev;??/*?previous?node?of?iterator?*/??
  • ????linknode_t?*node_next;??/*?next?node?of?iterator,??
  • ?????????????????*?used?to?backup?next?of?iterator??
  • ?????????????????*/??
  • ????if?(NULL?==?list)?return?NULL;??
  • ????node_prev?=?NULL;??
  • ????node?=?list->next;??
  • ????while?(NULL?!=?node)?{??
  • ????????/*?
  • ?????????*?step1:?backup?node->next?
  • ?????????*?due?to?the?next?of?iterator?will?be?
  • ?????????*?modified?in?step2?
  • ?????????*/??
  • ????????node_next?=?node->next;??
  • ????????/*??
  • ?????????*?when?iterator?reaches?the?last?node??
  • ?????????*?of?original?list,?make?the?list?head?
  • ?????????*?point?to?the?last?node,?so?the?original?
  • ?????????*?last?one?becomes?the?first?one.?
  • ?????????*/??
  • ??
  • ????????if?(NULL?==?node_next)?{??
  • ????????????list->next?=?node;??
  • ????????}??
  • ??
  • ????????/*??
  • ?????????*?step2:?reverse?the?linkage?between?nodes?
  • ?????????*?make?the?node?pointer?to?the?previous?node,?
  • ?????????*?not?the?next?node?
  • ?????????*/???????
  • ????????node->next?=?node_prev;????????
  • ????????/*??
  • ?????????*?step3:?move?forward??
  • ?????????*/??
  • ??
  • ????????node_prev?=?node;??
  • ????????node?=?node_next;??
  • ????}??
  • ????return?list;??
  • }??
  • main.c

    [cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?"linklist.h"??
  • ??
  • int?main()??
  • {??
  • ????int?i;??
  • ????data_t?x;??
  • ????linklist_t?p;??
  • ????p?=?CreateEmptyLinklist();??
  • ????data_t?a[10]?=?{1,3,5,7,9,11,13,15,17,19};??
  • ??
  • ????for(i?=?0;i?<?10;i++)??
  • ????{??
  • ????????InsertLinklist(p,i,a[i]);??
  • ????}??
  • ??
  • ????ReverseLinklist(p);??
  • ????printf("The?length?of?the?list?is:%d\n",LengthLinklist(p));??
  • ??????
  • ????GetLinklist(p,4,&x);??
  • ????printf("The?NO.4?of?this?list?is:%d\n",x);??
  • ??
  • ????SetLinklist(p,4,100);??
  • ????GetLinklist(p,4,&x);??
  • ????printf("After?updating!The?No.4?0f?this?list?is:%d\n",x);??
  • ??
  • ????DeleteLinklist(p,4);??
  • ????printf("After?updating!The?length?of?the?list?is:%d\n",LengthLinklist(p));??
  • ????GetLinklist(p,4,&x);??
  • ????printf("After?updating!The?No.4?0f?this?list?is:%d\n",x);??
  • ??
  • ????ReverseLinklist(p);??
  • ??????
  • ????ClearLinklist(p);??
  • ????if(EmptyLinklist(p))??
  • ????????printf("This?list?is?empty!\n");??
  • ????DestroyLinklist(p);??
  • ????printf("This?list?is?destroyed!\n");??
  • ??
  • ????return?0;??
  • ??????
  • }??
  • 執(zhí)行結(jié)果如下:

    [cpp]?view plaincopy
  • fs@ubuntu:~/qiang/list/list2$?./Test??
  • The?length?of?the?list?is:10??
  • The?NO.4?of?this?list?is:11??
  • After?updating!The?No.4?0f?this?list?is:100??
  • After?updating!The?length?of?the?list?is:9??
  • After?updating!The?No.4?0f?this?list?is:9??
  • This?list?is?empty!??
  • This?list?is?destroyed!?
  • 總結(jié)

    以上是生活随笔為你收集整理的Linux C 数据结构---单向链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。