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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

单向链表的C语言实现与基本操作

發布時間:2024/4/18 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单向链表的C语言实现与基本操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文的主要內容目錄:

一、單向鏈表的C語言實現

二、單向鏈表的基本操作


一、單向鏈表的C語言實現

鏈表作為一種基本的數據結構在程序開發過程當中經常會使用到。對C語言來說鏈表的實現主要依靠結構體和指針,所以本文相關內容和程序需要有C語言當中指針和結構體的基礎。

鏈表是一種線性存儲數據的結構,存儲內容在邏輯上連續的,在物理上卻不一定連續。單向鏈表的組成包括一個鏈表頭(head)和若干鏈表元素(node),對鏈表的基本操作其實就是增、刪、改、查。

首先說說單向鏈表的C語言實現方法。為了實現一個單向鏈表,首先定義一個結構體:

[cpp] view plain copy
  • /*?定義一個表示鏈表的結構體指針?*/??
  • struct?list?{??
  • ????int?id;?????????/*?標識這個元素方便查找?*/??
  • ????char?data[20];??????/*?鏈表中包含的元素?*/??
  • ????struct?list?*next;??/*?指向下一個鏈表的指針?*/??
  • };??
  • 下面來編寫程序實現一個鏈表的基本操作。該程序的功能是首先分配若干個鏈表元素(node),然后對這些鏈表元素進行賦初值,賦完初值之后將這些鏈表元素依次加入到鏈表當中,最后把這些元素的data字段依次打印出來。(注意 :本程序實現的鏈表頭結點(head)當中是存放數據的;為了保證每一個元素的id字段都不相同,所以定義了一個全局靜態數據成員list_id;使用linux下的gcc進行編譯)。程序如下: [cpp] view plain copy
  • /*?包含的頭文件?*/??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • ??
  • /*?定義一個表示鏈表的結構體指針?*/??
  • struct?list?{??
  • ????int?id;?????????/*?標識這個元素方便查找?*/??
  • ????char?data[20];??????/*?鏈表中包含的元素?*/??
  • ????struct?list?*next;??/*?指向下一個鏈表的指針?*/??
  • };??
  • ??
  • /*?定義一個鏈表頭部?*/??
  • static?struct?list?*list_head?=?NULL;??
  • ??
  • /*?為了保證每一個鏈表元素的id不同,特意把id定義成一個全局靜態變量?*/??
  • static?int?list_id?=?0;??
  • ??
  • /**?將指定元素插入到聊表尾部?
  • ??*?????head????:?表示要插入元素的鏈表的頭部的地址?
  • ??*?list????:?表示要插入到鏈表中的元素?
  • ??*/??
  • static?void?list_add(struct?list?**head,?struct?list?*list)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????/*?判斷鏈表是否為空?*/??
  • ????if(NULL?==?*head)??
  • ????{??
  • ????????/*?為空?*/??
  • ????????*head?=?list;??
  • ????????(*head)->next?=?NULL;??
  • ????}??
  • ????else??
  • ????{??
  • ????????/*?不為空?*/??
  • ????????temp?=?*head;??
  • ????????while(temp)??
  • ????????{??
  • ????????????if(NULL?==?temp->next)??
  • ????????????{??
  • ????????????????temp->next?=?list;??
  • ????????????????list->next?=?NULL;??
  • ????????????}??
  • ????????????temp?=?temp->next;??
  • ????????}??
  • ????}??
  • }??
  • ??
  • /**?遍歷一個鏈表,打印鏈表中每個元素所包含的數據?
  • ??*?head?:?表示要遍歷的鏈表的頭部的指針?
  • ??*/??
  • static?void?list_print(struct?list?**head)??
  • {?????
  • ????struct?list?*temp;??
  • ??
  • ????temp?=?*head;??
  • ??
  • ????printf("list?information?:\n");??
  • ????while(temp)??
  • ????{??
  • ????????printf("\tlist?%d?:?%s\n",?temp->id,?temp->data);??
  • ????????temp?=?temp->next;??
  • ????}??
  • }??
  • ??
  • /*?主函數,程序的入口?*/??
  • int?main(int?argc,?char?*argv[])??
  • {??
  • ????int?i?=?0;??
  • ????struct?list?*lists?=?NULL;??
  • ??
  • ????/*?分配10個元素?*/??
  • ????lists?=?malloc(sizeof(struct?list)?*?10);??
  • ????if(NULL?==?lists)??
  • ????{??
  • ????????printf("malloc?error!\n");??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????/*?將分配的10個元素依次填充數據并加入到鏈表當中?*/??
  • ????for(i?=?0;?i?<?10;?i++)??
  • ????{??
  • ????????lists[i].id?=?list_id++;??
  • ????????sprintf(lists[i].data,?"TECH-PRO?-?%d",?i);??
  • ??
  • ????????list_add(&list_head,?&lists[i]);??
  • ????}??
  • ??
  • ????/*?遍歷鏈表,把鏈表中每個元素的信息都打印出來?*/??
  • ????list_print(&list_head);??
  • ??
  • ????return?0;??
  • }??
  • 程序的運行結果如下所示:


    二、單向鏈表的基本操作

    鏈表的基本操作其實就是對鏈表中元素的操作。鏈表的基本操作包括鏈表中結點元素的添加、刪除、修改和查看,簡單來說就是增、刪、改、查。

    2.1 單向鏈表中元素添加

    在鏈表中添加元素時首先判斷鏈表是否為空,為空時直接把要添加的元素賦值給鏈表頭部,否者就要對鏈表進行遍歷找到下一個為空的結點,然后把元素插入到鏈表尾部。

    實現鏈表插入的程序代碼:

    [cpp] view plain copy
  • /**?將指定元素插入到聊表尾部?
  • ??*?????head????:?表示要插入元素的鏈表的頭部的地址?
  • ??*?list????:?表示要插入到鏈表中的元素?
  • ??*/??
  • static?void?list_add(struct?list?**head,?struct?list?*list)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????/*?判斷鏈表是否為空?*/??
  • ????if(NULL?==?*head)??
  • ????{??
  • ????????/*?為空?*/??
  • ????????*head?=?list;??
  • ????????(*head)->next?=?NULL;??
  • ????}??
  • ????else??
  • ????{??
  • ????????/*?不為空?*/??
  • ????????temp?=?*head;??
  • ????????while(temp)??
  • ????????{??
  • ????????????if(NULL?==?temp->next)??
  • ????????????{??
  • ????????????????temp->next?=?list;??
  • ????????????????list->next?=?NULL;??
  • ????????????}??
  • ????????????temp?=?temp->next;??
  • ????????}??
  • ????}??
  • }??
  • 在main函數中田間如下代碼: [cpp] view plain copy
  • struct?list?temp_list;??
  • ??
  • /*?填充這個結構體并加入鏈表當中?*/??
  • ????temp_list.id?=?list_id++;??
  • ????sprintf(temp_list.data,?"temp_list");??
  • ????list_add(&list_head,?&temp_list);??
  • 對程序進行編譯,結果如下:

    2.2 在單向鏈表中刪除元素

    在鏈表刪除一個元素結點是鏈表基本操作中相對復雜的。首先需要判斷鏈表是否為空,當鏈表不為空時,要再次判斷要刪除的元素是否是頭結點(head),如果是直接將下一個元素賦值給頭結點,不過不是就需要遍歷整個鏈表找到要刪除的結點元素。(注:本算法實現的刪除是通過對元素結點的id字段進行的)。

    刪除鏈表結點的程序代碼:

    [cpp] view plain copy
  • /**?將指定元素從鏈表尾部刪除?
  • ??*?????head????:?表示要刪除元素的鏈表的頭部的地址?
  • ??*?id??????:?表示要刪除元素的標識?
  • ??*?返回值??:?0-成功,-1-失敗?
  • ??*/??
  • static?int?list_del(struct?list?**head,?int?id)??
  • {??
  • ????struct?list?*temp,?*p;??
  • ????temp?=?*head;??
  • ??
  • ????if(NULL?==?temp)??
  • ????{??
  • ????????/*?鏈表為空?*/??
  • ????????printf("鏈表為空!\n");??
  • ????????return?-1;??
  • ????}??
  • ????else??
  • ????{??
  • ????????/*?判斷匹配的元素是否為鏈表頭部的元素?*/??
  • ????????if(id?==?temp->id)???????/*?是鏈表頭部?*/??
  • ????????{??
  • ????????????*head?=?temp->next;??
  • ????????????return?0;??
  • ????????}??
  • ????????else????????????????????/*?不是鏈表頭部?*/??
  • ????????{??
  • ????????????while(temp->next)??
  • ????????????{??
  • ????????????????p?=?temp;??
  • ????????????????temp?=?temp->next;??
  • ??
  • ????????????????if(id?==?temp->id)??
  • ????????????????{??
  • ????????????????????p->next?=?temp->next;??
  • ????????????????????return?0;??
  • ????????????????}??
  • ????????????}?????
  • ????????????return?-1;??
  • ????????}??
  • ????}??
  • ??
  • ????return?-1;??
  • }??
  • 在main函數中添加如下代碼: [cpp] view plain copy
  • /*?刪除鏈表中開始位置、中間位置、尾部的元素?*/??
  • ????list_del(&list_head,?0);??
  • ????list_del(&list_head,?5);??
  • ????list_del(&list_head,?10);??
  • 對程序進行編譯結果如下所示,第0、5、10號元素都被刪除:


    2.3 在單向鏈表中修改指定的元素

    在鏈表中修改元素,通過對鏈表中元素進行遍歷,找到要修改的元素對其內容分進行修改即可,實現鏈表元素的修改是相對容易的。(注 :對要修改的元素的定位是通過id字段來完成的)

    鏈表中修改元素的程序如下:

    [cpp] view plain copy
  • /**?將指定id的元素所定義的內容進行修改?
  • ??*?????head????:?表示要改變元素的鏈表的頭部的地址?
  • ??*?id??????:?表示要改變元素的標識?
  • ??*?content?:?表示要改變的內容?
  • ??*?返回值??:?0-成功,-1-失敗?
  • ??*/??
  • static?int?list_chg(struct?list?**head,?int?id,?char?*content)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????temp?=?*head;???/*?將鏈表的頭部賦值給臨時聊表變量?*/??
  • ??
  • ????while(temp)?????/*?對鏈表進行輪詢?*/??
  • ????{??
  • ????????if(id?==?temp->id)??
  • ????????{??
  • ????????????memset(temp->data,?0,?sizeof(temp->data));??
  • ????????????sprintf(temp->data,?"%s",?content);??
  • ????????????temp->data[strlen(content)]?=?'\0';??
  • ????????????return?0;??
  • ????????}??
  • ????????temp?=?temp->next;??
  • ????}??
  • ????return?-1;??
  • }??
  • 在main函數中添加如下代碼: [cpp] view plain copy
  • /*?改變id為4的元素所對應的值為?"change!!!"?*/??
  • ????list_chg(&list_head,?4,?"change!!!");??
  • 編譯程序,運行結果如下所示:


    2.4 對單向鏈表的元素進行查詢操作

    在鏈表中查詢一個元素,根據鏈表頭部對鏈表進行遍歷即可。

    鏈表中查詢的程序代碼:

    [cpp] view plain copy
  • /**?將指定id的元素所定義的內容進行查找?
  • ??*?????head????:?表示要查詢元素的鏈表的頭部的地址?
  • ??*?id??????:?表示要查詢元素的標識?
  • ??*?返回值??:?0-成功,-1-失敗?
  • ??*/??
  • static?int?list_query(struct?list?**head,?int?id)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????temp?=?*head;???/*?將鏈表的頭部賦值給臨時聊表變量?*/??
  • ??
  • ????while(temp)?????/*?對鏈表進行輪詢?*/??
  • ????{??
  • ????????if(id?==?temp->id)??
  • ????????{??
  • ????????????printf("list?%d?:?%s\n",?temp->id,?temp->data);??
  • ????????????return?0;??
  • ????????}??
  • ????????temp?=?temp->next;??
  • ????}??
  • ??
  • ????/*?沒有找到元素?*/??
  • ????printf("not?finding!\n");??
  • ??????
  • ????return?-1;??
  • }??
  • 程序運行結果:



    附錄:單向鏈表的基本操作已經說完,附上一個完整的程序。

    [cpp] view plain copy
  • /*?包含的頭文件?*/??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<string.h>??
  • ??
  • /*?定義一個表示鏈表的結構體指針?*/??
  • struct?list?{??
  • ????int?id;?????????????/*?標識這個元素方便查找?*/??
  • ????char?data[20];??????/*?鏈表中包含的元素?*/??
  • ????struct?list?*next;??/*?指向下一個鏈表的指針?*/??
  • };??
  • ??
  • /*?定義一個鏈表頭部?*/??
  • static?struct?list?*list_head?=?NULL;??
  • ??
  • /*?為了保證每一個鏈表元素的id不同,特意把id定義成一個全局靜態變量?*/??
  • static?int?list_id?=?0;??
  • ??
  • /**?將指定元素插入到鏈表尾部?
  • ??*?????head????:?表示要插入元素的鏈表的頭部的地址?
  • ??*?list????:?表示要插入到鏈表中的元素?
  • ??*/??
  • static?void?list_add(struct?list?**head,?struct?list?*list)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????/*?判斷鏈表是否為空?*/??
  • ????if(NULL?==?*head)??
  • ????{??
  • ????????/*?為空?*/??
  • ????????*head?=?list;??
  • ????????(*head)->next?=?NULL;??
  • ????}??
  • ????else??
  • ????{??
  • ????????/*?不為空?*/??
  • ????????temp?=?*head;??
  • ????????while(temp)??
  • ????????{??
  • ????????????if(NULL?==?temp->next)??
  • ????????????{??
  • ????????????????temp->next?=?list;??
  • ????????????????list->next?=?NULL;??
  • ????????????}??
  • ????????????temp?=?temp->next;??
  • ????????}??
  • ????}??
  • }??
  • ??
  • /**?遍歷一個鏈表,打印鏈表中每個元素所包含的數據?
  • ??*?head?:?表示要遍歷的鏈表的頭部的指針?
  • ??*/??
  • static?void?list_print(struct?list?**head)??
  • {?????
  • ????struct?list?*temp;??
  • ??
  • ????temp?=?*head;??
  • ??
  • ????printf("list?information?:\n");??
  • ????while(temp)??
  • ????{??
  • ????????printf("\tlist?%d?:?%s\n",?temp->id,?temp->data);??
  • ????????temp?=?temp->next;??
  • ????}??
  • }??
  • ??
  • /**?將指定元素從鏈表尾部刪除?
  • ??*?????head????:?表示要刪除元素的鏈表的頭部的地址?
  • ??*?id??????:?表示要刪除元素的標識?
  • ??*?返回值??:?0-成功,-1-失敗?
  • ??*/??
  • static?int?list_del(struct?list?**head,?int?id)??
  • {??
  • ????struct?list?*temp,?*p;??
  • ????temp?=?*head;??
  • ??
  • ????if(NULL?==?temp)??
  • ????{??
  • ????????/*?鏈表為空?*/??
  • ????????printf("鏈表為空!\n");??
  • ????????return?-1;??
  • ????}??
  • ????else??
  • ????{??
  • ????????/*?判斷匹配的元素是否為鏈表頭部的元素?*/??
  • ????????if(id?==?temp->id)???????/*?是鏈表頭部?*/??
  • ????????{??
  • ????????????*head?=?temp->next;??
  • ????????????return?0;??
  • ????????}??
  • ????????else????????????????????/*?不是鏈表頭部?*/??
  • ????????{??
  • ????????????while(temp->next)??
  • ????????????{??
  • ????????????????p?=?temp;??
  • ????????????????temp?=?temp->next;??
  • ??
  • ????????????????if(id?==?temp->id)??
  • ????????????????{??
  • ????????????????????p->next?=?temp->next;??
  • ????????????????????return?0;??
  • ????????????????}??
  • ????????????}?????
  • ????????????return?-1;??
  • ????????}??
  • ????}??
  • ??
  • ????return?-1;??
  • }??
  • ??
  • /**?將指定id的元素所定義的內容進行修改?
  • ??*?????head????:?表示要改變元素的鏈表的頭部的地址?
  • ??*?id??????:?表示要改變元素的標識?
  • ??*?content?:?表示要改變的內容?
  • ??*?返回值??:?0-成功,-1-失敗?
  • ??*/??
  • static?int?list_chg(struct?list?**head,?int?id,?char?*content)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????temp?=?*head;???/*?將鏈表的頭部賦值給臨時聊表變量?*/??
  • ??
  • ????while(temp)?????/*?對鏈表進行輪詢?*/??
  • ????{??
  • ????????if(id?==?temp->id)??
  • ????????{??
  • ????????????memset(temp->data,?0,?sizeof(temp->data));??
  • ????????????sprintf(temp->data,?"%s",?content);??
  • ????????????temp->data[strlen(content)]?=?'\0';??
  • ????????????return?0;??
  • ????????}??
  • ????????temp?=?temp->next;??
  • ????}??
  • ????return?-1;??
  • }??
  • ??
  • /**?將指定id的元素所定義的內容進行查找?
  • ??*?????head????:?表示要查詢元素的鏈表的頭部的地址?
  • ??*?id??????:?表示要查詢元素的標識?
  • ??*?返回值??:?0-成功,-1-失敗?
  • ??*/??
  • static?int?list_query(struct?list?**head,?int?id)??
  • {??
  • ????struct?list?*temp;??
  • ??
  • ????temp?=?*head;???/*?將鏈表的頭部賦值給臨時聊表變量?*/??
  • ??
  • ????while(temp)?????/*?對鏈表進行輪詢?*/??
  • ????{??
  • ????????if(id?==?temp->id)??
  • ????????{??
  • ????????????printf("list?%d?:?%s\n",?temp->id,?temp->data);??
  • ????????????return?0;??
  • ????????}??
  • ????????temp?=?temp->next;??
  • ????}??
  • ??
  • ????/*?沒有找到元素?*/??
  • ????printf("not?finding!\n");??
  • ??????
  • ????return?-1;??
  • }??
  • ??
  • ??
  • /*?主函數,程序的入口?*/??
  • int?main(int?argc,?char?*argv[])??
  • {??
  • ????int?i?=?0;??
  • ????struct?list?*lists?=?NULL;??
  • ??
  • ????struct?list?temp_list;??
  • ??
  • ????/*?分配10個元素?*/??
  • ????lists?=?malloc(sizeof(struct?list)?*?10);??
  • ????if(NULL?==?lists)??
  • ????{??
  • ????????printf("malloc?error!\n");??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????/*?將分配的10個元素依次填充數據并加入到鏈表當中?*/??
  • ????for(i?=?0;?i?<?10;?i++)??
  • ????{??
  • ????????lists[i].id?=?list_id++;??
  • ????????sprintf(lists[i].data,?"TECH-PRO?-?%d",?i);??
  • ??
  • ????????list_add(&list_head,?&lists[i]);??
  • ????}??
  • ??
  • ????/*?填充這個結構體并加入鏈表當中?*/??
  • ????temp_list.id?=?list_id++;??
  • ????sprintf(temp_list.data,?"temp_list");??
  • ????list_add(&list_head,?&temp_list);??
  • ??
  • ????/*?刪除鏈表中開始位置、中間位置、尾部的元素?*/??
  • ????list_del(&list_head,?0);??
  • ????list_del(&list_head,?5);??
  • ????list_del(&list_head,?10);??
  • ??
  • ????/*?改變id為4的元素所對應的值為?"change!!!"?*/??
  • ????list_chg(&list_head,?4,?"change!!!");??
  • ??
  • ????/*?查詢鏈表中id為4的元素結點的內容?*/??
  • ????list_query(&list_head,?4);??
  • ??
  • ????return?0;??
  • }?
  • 總結

    以上是生活随笔為你收集整理的单向链表的C语言实现与基本操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。