嵌入式C語言基礎鏈表

什么是鏈表?
鏈表其實就是一種數據結構,所謂的數據結構就是數據存放的思想。
數組、鏈表優缺點:
增加一個元素或者刪除一個元素都很難,因為地址是連續的,刪除一個元素可能會挪動多個元素,不靈活。但是對于鏈表來說就很輕松了,鏈表的每一個節點都是一個結構體,可以通過指針指向的方式將鏈表串起來,很靈活。

鏈表和數組的引入:

#include <stdio.h>
#include <stdlib.h>
//只要是通過指針的凡是訪問結構體中的數據都要用->
struct Text//用鏈表的形式存儲數據
{int data;struct Text* next;
};
int main()
{int i;int array[]={1,2,3,4};//用數組的方式實現數據的存儲,訪問到數組的首地址就可以輸出整個數組//因為數組的地址是連續的for(i=0;i<sizeof(array)/sizeof(array[0]);i++){printf("%d",array[i]);}putchar('\n');struct Text t1={1,NULL};struct Text t2={2,NULL};struct Text t3={3,NULL};//下面幾行代碼是將上面定義的幾個結構體串起來,形成鏈表t1.next=&t2;//指針是存放別人的地址t1里的指針變量指向t2的地址t2.next=&t3;//這樣就將三個結構體聯系了起來printf("use t1 printf four number:\n");printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);//t1.next就是指向t2的一個指針(我理解的就是相當于struct Text * p)//然后通過->這種方式去訪問結構體中的數據,然后t1.next->next就是相當于//指向t3的一個指針,也要通過->這種方式去訪問里面的數據system("pause");return 0;
}

鏈表的動態輸出:

#include <stdio.h>
#include <stdlib.h>
//只要是通過指針的凡是訪問結構體中的數據都要用->
struct Text//用鏈表的形式存儲數據
{int data;struct Text* next;
};void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭}putchar('\n');}
int main()
{int i;int array[]={1,2,3,4};//用數組的方式實現數據的存儲,訪問到數組的首地址就可以輸出整個數組//因為數組的地址是連續的for(i=0;i<sizeof(array)/sizeof(array[0]);i++){printf("%d",array[i]);}putchar('\n');struct Text t1={1,NULL};struct Text t2={2,NULL};struct Text t3={3,NULL};//下面幾行代碼是將上面定義的幾個結構體串起來,形成鏈表t1.next=&t2;//指針是存放別人的地址t1里的指針變量指向t2的地址t2.next=&t3;//這樣就將三個結構體聯系了起來printLink(&t1);//將第一個鏈表的地址傳入動態輸出函數system("pause");return 0;
}

鏈表的查找和節點個數的計算:

#include <stdio.h>
#include <stdlib.h>
//只要是通過指針的凡是訪問結構體中的數據都要用->
struct Text//用鏈表的形式存儲數據
{int data;struct Text* next;
};void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭}putchar('\n');}
void countLink(struct Text* head)//鏈表計算節點個數函數
{int cont=0;struct Text* Point;Point=head;while(head!=NULL){cont++;head=head->next;}printf("鏈表節點數為:%d\n",cont);}
void serchLink(struct Text*head,int data)
{while(head!=NULL){if(head->data==data){printf("存在此節點\n");return;}head=head->next;}printf("無此節點\n");
}
int main()
{int i;int input;int array[]={1,2,3,4};//用數組的方式實現數據的存儲,訪問到數組的首地址就可以輸出整個數組//因為數組的地址是連續的for(i=0;i<sizeof(array)/sizeof(array[0]);i++){printf("%d",array[i]);}putchar('\n');struct Text t1={1,NULL};struct Text t2={2,NULL};struct Text t3={3,NULL};//下面幾行代碼是將上面定義的幾個結構體串起來,形成鏈表t1.next=&t2;//指針是存放別人的地址t1里的指針變量指向t2的地址t2.next=&t3;//這樣就將三個結構體聯系了起來printLink(&t1);countLink(&t1);printf("請輸入要查找的節點:\n");scanf("%d",&input);serchLink(&t1,input);system("pause");return 0;
}

從指定節點后插入節點:

#include <stdio.h>
#include <stdlib.h>
//只要是通過指針的凡是訪問結構體中的數據都要用->
struct Text//用鏈表的形式存儲數據
{int data;struct Text* next;
};void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭}putchar('\n');}
void countLink(struct Text* head)//鏈表計算節點個數函數
{int cont=0;struct Text* Point;Point=head;while(head!=NULL){cont++;head=head->next;}printf("鏈表節點數為:%d\n",cont);}
void serchLink(struct Text*head,int data)
{while(head!=NULL){if(head->data==data){printf("存在此節點\n");return;}head=head->next;}printf("無此節點\n");
}void InsertFromBhind(struct Text*head,struct Text*newLink,int data)
{struct Text* Point;Point=head;while(Point!=NULL){if(Point->data==data){newLink->next=Point->next;//head->next是插入位置后一個節點的指針,就是head->next指向插入位置的后一個節點Point->next=newLink;//修改插入位置前一個節點內的指針指向,指向新節點的地址,將鏈表串起來printLink(head);return;}Point=Point->next;}printf("無此節點\n");
}
int main()
{int i;int input;int link;struct Text t1={1,NULL};struct Text t2={2,NULL};struct Text t3={3,NULL};struct Text t4={4,NULL};//下面幾行代碼是將上面定義的幾個結構體串起來,形成鏈表t1.next=&t2;//指針是存放別人的地址t1里的指針變量指向t2的地址t2.next=&t3;//這樣就將三個結構體聯系了起來printLink(&t1);countLink(&t1);printf("請輸入要查找的節點:\n");scanf("%d",&input);serchLink(&t1,input);printf("請輸入在哪個節點后插入;\n");scanf("%d",&link);InsertFromBhind(&t1,&t4,link);system("pause");return 0;
}

在指定節點前插入節點:

#include <stdio.h>
#include <stdlib.h>
//只要是通過指針的凡是訪問結構體中的數據都要用->
struct Text//用鏈表的形式存儲數據
{int data;struct Text* next;
};void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭}putchar('\n');}
void countLink(struct Text* head)//鏈表計算節點個數函數
{int cont=0;struct Text* Point;Point=head;while(head!=NULL){cont++;head=head->next;}printf("鏈表節點數為:%d\n",cont);}
void serchLink(struct Text*head,int data)
{while(head!=NULL){if(head->data==data){printf("存在此節點\n");return;}head=head->next;}printf("無此節點\n");
}
void InsertFromBefore(struct Text*head,struct Text*newlink,int data)
{struct Text*Point;Point=head;if(head!=NULL && head->data==data){newlink->next=head;printLink(newlink);return;}while(Point->next!=NULL){//因為是在指定節點前插入節點//所以要通過指定節點的前一個節點插入//Point就是指向,指定節點前一個節點的指針//Point->next是指向,指定的插入節點的指針,也就是在這個節點前插入節點if(Point->next->data==data){newlink->next=Point->next;Point->next=newlink;printLink(head);return;}Point=Point->next;}
}int main()
{int i;int input;int link;struct Text t1={1,NULL};struct Text t2={2,NULL};struct Text t3={3,NULL};struct Text t4={4,NULL};//下面幾行代碼是將上面定義的幾個結構體串起來,形成鏈表t1.next=&t2;//指針是存放別人的地址t1里的指針變量指向t2的地址t2.next=&t3;//這樣就將三個結構體聯系了起來printLink(&t1);countLink(&t1);printf("請輸入要查找的節點:\n");scanf("%d",&input);serchLink(&t1,input);printf("請輸入在哪個節點前插入;\n");scanf("%d",&link);InsertFromBefore(&t1,&t4,link);system("pause");return 0;
}

靜態鏈表的刪除和修改:

#include <stdio.h>
#include <stdlib.h>
//只要是通過指針的凡是訪問結構體中的數據都要用->
struct Text//用鏈表的形式存儲數據
{int data;struct Text* next;
};void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭}putchar('\n');}
void countLink(struct Text* head)//鏈表計算節點個數函數
{int cont=0;struct Text* Point;Point=head;while(head!=NULL){cont++;head=head->next;}printf("鏈表節點數為:%d\n",cont);}
void serchLink(struct Text*head,int data)//查找函數
{while(head!=NULL){if(head->data==data){printf("存在此節點\n");return;}head=head->next;}printf("無此節點\n");
}void changeLink(struct Text*head,int data,int data2)//改函數
{struct Text*Point=head;while(Point!=NULL){if(Point->data==data){printf("此節點存在可改\n");Point->data=data2;printLink(head);return;}Point=Point->next;}printf("無此節點\n");
}void delLink(struct Text*head,int data)
{struct Text*Point=head;if(head->data==data){head=head->next;//將第二個節點指定為數組頭,那么第一個節點就需要釋放掉避免造成內存泄漏//free(Point);   //將這個地址釋放掉,可以通過Point指針將之前的head的內存空間釋放掉//free可以將指針指向的內存空間釋放掉,但是釋放掉之后最好將指針指向NULL//因為free只是把指針所指的內存給釋放掉,但并沒有把指針本身干掉。//free只能釋放malloc開辟的內存空間printLink(head);return;}while(Point->next!=NULL){//head->next是指向要刪除的那個節點的指針if(Point->next->data==data){Point->next=Point->next->next;//如果是動態創建,就要新定義一個指針//通過新定義的指針把(Ponit->next)free掉printLink(head);return;}Point=Point->next;}printf("沒有找到\n");
}
int main()
{int i;int input;int link;struct Text t1={1,NULL};struct Text t2={2,NULL};struct Text t3={3,NULL};struct Text t4={4,NULL};//下面幾行代碼是將上面定義的幾個結構體串起來,形成鏈表t1.next=&t2;//指針是存放別人的地址t1里的指針變量指向t2的地址t2.next=&t3;//這樣就將三個結構體聯系了起來printLink(&t1);countLink(&t1);printf("請輸入要查找的節點:\n");scanf("%d",&input);serchLink(&t1,input);printf("請輸入要刪除哪個節點;\n");scanf("%d",&link);delLink(&t1,link);printf("修改哪個節點;\n");scanf("%d",&link);changeLink(&t1,link,100);//這些所有的函數并不修改main函數中的節點system("pause");return 0;
}

鏈表的動態創建之頭插法(每插進來一個節點就將它當做頭結點,就像棧一樣)

#include <stdio.h>
#include <stdlib.h>struct Text
{int data;struct Text*next;
};
void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭               }putchar('\n');}
struct Text *creatFromHead(struct Text*head,struct Text*newnode)//節點頭插法插入函數
//節點創建函數和插入節點函數分開寫,有利于后面節點的插入
{if(head==NULL){head=newnode;}else{newnode->next=head;head=newnode;}return head;
}
struct Text*creatLink(struct Text*head)//鏈表節點創建函數
{struct Text*newnode=NULL;while(1){//不斷創建新的節點,直到輸入的數字為0newnode=(struct Text*)malloc(sizeof(struct Text));newnode->next=NULL;printf("請輸入data:\n");scanf("%d",&(newnode->data));if(newnode->data==0){free(newnode);//新創建的節點里的data等于0;所以不把他插入鏈表中//將它指向的內存空間釋放掉printf("鏈表創建結束\n");return head;}head=creatFromHead(head,newnode);}
}
int main()
{struct Text *head=NULL;printLink(creatLink(head));system("pause");return 0;
}

尾插法插入節點:

#include <stdio.h>
#include <stdlib.h>struct Text
{int data;struct Text*next;
};
void printLink(struct Text *head)//鏈表的動態輸出函數,struct Text *head是鏈表的頭
{struct Text*Point;Point=head;while(Point!=NULL){printf("%d ",Point->data);Point=Point->next;//head是第一個節點的指針,輸出完第一個鏈表的內容后,將鏈表的頭部往后移一個,變為指向第二個節點的指針//head->next是指向下一個鏈表的頭               }putchar('\n');}
struct Text *insertFromBehind(struct Text*head,struct Text*newnode)//節點尾插法插入函數
{struct Text* p=NULL;p=head;if(p==NULL){//如果沒有這句話,如果P為空指針,繼續往下執行p->next對空指針進行操作,會出現段錯誤head=newnode;return head;}while(p->next!=NULL){p=p->next;}p->next=newnode;return head;
}
struct Text*creatLink(struct Text*head)//鏈表節點創建函數
{struct Text*newnode=NULL;while(1){//不斷創建新的節點,直到輸入的數字為0newnode=(struct Text*)malloc(sizeof(struct Text));newnode->next=NULL;printf("請輸入data:\n");scanf("%d",&(newnode->data));if(newnode->data==0){free(newnode);//新創建的節點里的data等于0;所以不把他插入鏈表中//將它指向的內存空間釋放掉printf("鏈表創建結束\n");return head;}head=insertFromBehind(head,newnode);}
}
int main()
{struct Text *head=NULL;printLink(creatLink(head));system("pause");return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272276.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272276.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272276.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker pull 從倉庫拉取鏡像

docker pull 要拉取的鏡像名 等價于 docker pull 要拉取的鏡像名:lastest 拉取固定的鏡像&#xff1a;docker pull 要拉取的鏡像名:版本號 省略lastest表設計就是拉取的最新的

理解js中的原型鏈,prototype與__proto__的關系

說到prototype&#xff0c;就不得不先說下new的過程。 我們先看看這樣一段代碼&#xff1a; 1<script type"text/javascript">2 var Person function () { };3 var p new Person();4</script>很簡單的一段代碼&#xff0c;我們來看看這個new究竟做了什…

C#抓取網頁HTML內容

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Net; using System.Text; using System.IO; using System.Text.RegularExpressions; namespace Web { /// <summary> /// 公共方法類 /// </summary> p…

項目一感應垃圾桶(Wemos)

硬件材料&#xff1a; Wemos D1、SG90舵機、HC-SR04、杜邦線若干、蜂鳴器3.3V&#xff08;可有可無&#xff09; 軟件材料&#xff1a; arduino IDE編譯器、USB轉串口驅動 Wemos D1&#xff1a; 特性&#xff1a; 基于ESP-8266EX及arduino做的一個融合arduino兼容&#xff0…

docker刪除本地所有鏡像

docker rmi -f ${docker images -qa}

PAT1069. The Black Hole of Numbers

//這是到水題&#xff0c;之前因為四位數的原因一直不能A&#xff0c;看了別人的程序&#xff0c;才明白&#xff0c;不夠四位的時候沒考慮到&#xff0c;坑啊。。。。。臉打腫 #include<cstdio>#include<algorithm>using namespace std;int main(){ //freopen(&qu…

WiFi避障小車

硬件清單&#xff1a; Wemos D1&#xff08;支持AP模式也就是路由模式和STA模式也就是上網設備&#xff09;、超聲波模塊、小車、L9110s步進電機控制器 軟件&#xff1a; eclipse、arduino IDE WiFi配置參考博文 ESP8266WiFi庫: 從上圖中可以看出ESP8266WiFi庫主要包含Stati…

yum常用命令整理

yum命令的形式一般如下。要說明的是以下演示中所使用到的PACKAGE、GROUP都是變量&#xff0c;需要保證運行yum命令的主機能連接外網&#xff0c;否則大部分命令將由于沒有網絡連接而不能輸出結果。yum [options] [command] [package]#以下演示中大寫的單詞是變量1.安裝操作yum …

CSS3 2D 轉換

CSS3 2D 轉換 先看兼容性 transform屬性向應用元素應用2d 或者 3d裝換&#xff1b;該屬性允許我們進行旋轉&#xff0c;縮放&#xff0c;移動或者傾斜&#xff1b; 基本語法&#xff1a; transform: none|transform-functions;transform-function&#xff1a;這東東有n的函數可…

程序猿最喜歡說的30句話

雖然代碼總會有這個那個問題&#xff0c;但程序猿卻總有謎一般的從容和自信。上圖來自&#xff1a;《當程序出問題時程序員最喜歡說的30句話》來看看程序猿經常說的話&#xff1a;1、在我的電腦上是正常的啊。。。2、不可能出現這種情況的3、快了&#xff0c;已經完成了90%。4、…

linux環境下Ncurses實現貪吃蛇游戲

游戲說明&#xff1a; linux環境下基于Ncurses圖形庫的C語言小游戲。 Ncurses介紹&#xff1a; Ncurses(new curses)是一套編程庫&#xff0c;它提供了一系列的函數以便使用者調用它們去生成基于文本的用戶界面。 Ncurses是一個能提供功能鍵定義(快捷鍵),屏幕繪制以及基于文本…

韓順平循序漸進學java 第13講 抽象類.接口

13.1抽象類 13.1.1 概念 當父類的一些方法不能確定時&#xff0c;可以用abstract關鍵字來修飾該方法&#xff0c;稱為抽象方法&#xff0c;用abstract來修飾該類&#xff0c;稱為抽象類。 13.1.2 抽象類-深入討論 抽象類是java中一個比較重要的類&#xff1a; 1、用abstract關鍵…

C#實現簡體繁體轉換代碼示例

//簡體轉繁體 public static string _ConvertChinTrad(string strInput) { EncodeRobert edControl new EncodeRobert(); string strResult ""; if (strInput null) return strResult; if (strInput.ToString().Length > 1) strResult edControl.SCTCConvert(…

java基礎JDK的安裝和環境變量的配置

JRE和JDK&#xff1a; JRE是java程序運行時環境&#xff0c;包含JVM&#xff08;相當于java在不同操作系統上運行時java和操作系統之間的翻譯&#xff0c;保證java程序的跨平臺&#xff09;和運行時所需要的核心庫。所以我們想要運行一個已有的java程序&#xff0c;那么只需要…

C#通過SMTP發送郵件代碼示例

1、新建SMTP.cs類庫文件 public class SMTP { /// <summary> /// SMTP服務器 /// </summary> public string smtp { get; set; } /// <summary> /// SMTP服務器端口 /// </summary> public int port { get; set; } /// <summary> /// 發件人 ///…

docker下載tomact

docker run -it -p 8080:8080 tomcat 比如下載tomcat,你現在去訪問&#xff0c;先訪問docker里面的tomcat, 左邊的8080是對外暴露的服務端口&#xff0c;對應著右邊的8080是tomact的實際端口 下載tomcat 啟動tomcat docker run -it -p 8080:8080 tomcat

Wijmo 2016年藍圖

2015年很快就過去了&#xff0c;這是 Wijmo 重要的一年&#xff0c;尤其是對 Wijmo5。脫離傳統的小部件&#xff0c;重新寫一套 JS 控件&#xff0c;現在看來這個決定是正確的。用 TypeScript 寫 Wijmo5&#xff0c;意味著我們沒有任何依賴&#xff0c;不再需要 jQuery&#xf…

IDEA安裝和運行HelloWorld

IDEA安裝&#xff1a; IDEA中Hello World步驟&#xff1a; ① ②點擊創建空項目&#xff0c;下一步 ③ ④在打開后會彈出以下界面&#xff0c;然后點擊新建模塊 ⑤點擊新建模塊后出現以下界面&#xff0c;選擇java并選擇JDK的安裝路徑。 ⑥然后修改模塊名稱&#xff0c;點擊…