女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言_鏈表總結

DS小龍哥-嵌入式技術 ? 來源:DS小龍哥-嵌入式技術 ? 作者:DS小龍哥-嵌入式技 ? 2022-08-14 09:53 ? 次閱讀

本篇文章介紹C語言鏈表相關知識點,涉及鏈表的創建、單向鏈表、循環鏈表、雙向鏈表、單向循環鏈表,鏈表常見問題總結等,還列出了結構體數組與鏈表的練習題,將在下篇文章貼出完整代碼。

1. 鏈表

1.1 結構體對比

數組特性: 內存空間連續、只能存放相同類型的數據
結構體特性: 內存空間連續、可以存放不同類型的數據

#include 
struct MyStruct
{
	int a;
	char b;
};

int main()
{
	struct MyStruct *p;
	struct MyStruct data={12,'A'};
	data.a=123;
	data.b='B';

	p=&data;
	printf("%d\n",p->a);
	printf("%c\n",p->b);
	return 0;
}

數組學生管理系統作業:

作業:   學生管理系統
需求:   (每一個功能都是使用函數進行封裝)
1.實現從鍵盤上錄入學生信息。 (姓名、性別、學號、成績、電話號碼)
2.將結構體里的學生信息全部打印出來。
3.實現根據學生的姓名或者學號查找學生,查找到之后打印出學生的具體信息。
4.根據學生的成績對學生信息進行排序。
5.根據學號刪除學生信息。

1.2 單向鏈表的創建與運用

鏈表: 單鏈表、雙鏈表 區分: 循環和不循環鏈表
鏈表的特性: 一種數據結構的運行—>結構體。

學習結構體數組(編寫學生管理系統): 學生的人數問題不好確定。
鏈表本身就是一個結構體。

單向鏈表的創建與運用:

#include 
#include 
#include 

//定義結構體
struct MyListStruct
{
	int a;
	struct MyListStruct *next; //結構體指針。存放下一個節點的地址
};

//定義鏈表頭
struct MyListStruct *ListHead=NULL; 

//函數聲明
struct MyListStruct *CreateListHead(struct MyListStruct *head);
void  PintListInfo(struct MyListStruct *head);
void AddListNode(struct MyListStruct *head,struct MyListStruct NewNode);
void DeleteListNode(struct MyListStruct *head,int a);
int main()
{
	int i;
	struct MyListStruct temp;
	int a;
	//1. 創建鏈表頭
	ListHead=CreateListHead(ListHead);

	//2. 添加節點
	for(i=0; i<5; i++)
	{
		printf("輸入新節點數據:");
		scanf("%d",&temp.a);
		AddListNode(ListHead,temp);
	}

	//3. 打印所有節點數據
	PintListInfo(ListHead);

	//4. 刪除節點數據
	printf("輸入刪除的節點數據值:");
	scanf("%d",&a);
	DeleteListNode(ListHead,a);

	//5. 打印所有節點數據
	PintListInfo(ListHead);
	return 0;
}
/*
函數功能: 創建鏈表頭
返回值  : 鏈表頭指針
*/
struct MyListStruct *CreateListHead(struct MyListStruct *head)
{
	if(head==NULL)
	{
		head=malloc(sizeof(struct MyListStruct));
		head->next=NULL; 
	}
	return head; //返回鏈表頭
}

/*
函數功能: 添加鏈表節點
說明: 鏈表頭一般不存放數據
*/
void AddListNode(struct MyListStruct *head,struct MyListStruct NewNode)
{
	struct MyListStruct *p=head; //保存頭地址
	struct MyListStruct *new_p=NULL;  //新的節點

	/*1. 尋找鏈表尾*/
	while(p->next!=NULL)
	{
		p=p->next; //移動到下一個地址
	}
    /*2. 創建新節點*/
	new_p=malloc(sizeof(struct MyListStruct));
	if(new_p==NULL)
	{
		printf("新節點內存申請失敗!\n");
		return;
	}
	/*3. 新節點賦值*/
	memcpy(new_p,&NewNode,sizeof(struct MyListStruct)); //內存拷貝
	new_p->next=NULL; //尾節點指向空

	/*4. 新節點添加*/
	p->next=new_p;
}

/*
函數功能: 刪除鏈表節點
*/
void DeleteListNode(struct MyListStruct *head,int a)
{
	struct MyListStruct *p=head; //保存頭地址
	struct MyListStruct *tmp=NULL;
	/*查找數據存在的節點位置*/
	while(p->next!=NULL)
	{
		tmp=p; //保存上一個節點的地址
		p=p->next;
		if(p->a==a)  //查找成功
		{
			tmp->next=p->next; //將要刪除節點的指針值賦值給刪除節點的上一個節點指針域
			//tmp->next=tmp->next->next;
			free(p); //直接釋放p節點空間
			//break;
			p=head; //重新指向鏈表頭
		}
	}
}
/*
函數功能: 遍歷所有鏈表信息
*/
void  PintListInfo(struct MyListStruct *head)
{
	int cnt=0;
	struct MyListStruct *p=head;
	printf("\n鏈表遍歷的數據如下:\n");
	while(p->next!=NULL)
	{
		p=p->next;
		cnt++;
		printf("第%d個節點的數據=%d\n",cnt,p->a);
	}
}

作業:

1.看代碼、理解鏈表的創建流程
2.編寫出單向鏈表的基礎運用
3.將之前的學生管理系統使用鏈表方式做出來

鏈表的功能:
(1)創建鏈表頭
(2)在鏈表結尾添加一個節點
(3)刪除指定的一個鏈表節點
(4)遍歷鏈表,打印出所有的數據。
(5)在鏈表的指定節點的后面添加一個節點。
(6)根據鏈表節點里的數據對鏈表進行排序。
雙向鏈表:
(1)使用逆向+順向兩種遍歷方式刪除鏈表節點,目的: 提高效率。
     類似于二分法查找。

2. 鏈表問題總結

動態空間分配:
#include 
#include 
#include 

int main()
{
	char *p=malloc(100); //申請動態空間。
	if(p==NULL)
	{
		return -1;
	}
	strcpy(p,"1234567890");
	printf("%s\n",p);
	return 0;
}

#include 
#include 
#include 

int main()
{
	char *p1=malloc(100); //申請動態空間。
	printf("%p\n",p1);
	char *p2=malloc(100); //申請動態空間。
	printf("%p\n",p2);
	char *p3=malloc(100); //申請動態空間。
	printf("%p\n",p3);
	char *p4=malloc(100); //申請動態空間。
	printf("%p\n",p4);
	return 0;
}
錯誤解決:
1.第一個錯誤開始解決
2.常規錯誤:  函數沒有聲明、分號每加、括號沒有加、=
3.括號沒有對齊。

3. 雙向鏈表和循環鏈表

3.1 單向循環鏈表:

#include 
#include 
#include 

//定義結構體
struct MyListStruct
{
	int a;
	struct MyListStruct *next; //結構體指針。存放下一個節點的地址
};

//定義鏈表頭
struct MyListStruct *ListHead=NULL;

//函數聲明
struct MyListStruct *CreateListHead(struct MyListStruct *head);
void  PintListInfo(struct MyListStruct *head);
void AddListNode(struct MyListStruct *head,struct MyListStruct NewNode);
void DeleteListNode(struct MyListStruct *head,int a);
int main()
{
	int i;
	struct MyListStruct temp;
	int a;
	//1. 創建鏈表頭
	ListHead=CreateListHead(ListHead);

	//2. 添加節點
	for(i=0; i<5; i++)
	{
		printf("輸入新節點數據:");
		scanf("%d",&temp.a);
		AddListNode(ListHead,temp);
	}

	//3. 打印所有節點數據
	PintListInfo(ListHead);

	//4. 刪除節點數據
	printf("輸入刪除的節點數據值:");
	scanf("%d",&a);
	DeleteListNode(ListHead,a);

	//5. 打印所有節點數據
	PintListInfo(ListHead);
	return 0;
}
/*
函數功能: 創建鏈表頭
返回值  : 鏈表頭指針
*/
struct MyListStruct *CreateListHead(struct MyListStruct *head)
{
	if(head==NULL)
	{
		head=malloc(sizeof(struct MyListStruct));
		head->next=head;
	}
	return head; //返回鏈表頭
}

/*
函數功能: 添加鏈表節點
說明: 鏈表頭一般不存放數據
*/
void AddListNode(struct MyListStruct *head,struct MyListStruct NewNode)
{
	struct MyListStruct *p=head; //保存頭地址
	struct MyListStruct *new_p=NULL;  //新的節點
    
	/*1. 尋找鏈表尾*/
	while(p->next!=head)
	{
		p=p->next; //移動到下一個地址
	}
	/*2. 創建新節點*/
	new_p=malloc(sizeof(struct MyListStruct));
	if(new_p==NULL)
	{
		printf("新節點內存申請失敗!\n");
		return;
	}
	/*3. 新節點賦值*/
	memcpy(new_p,&NewNode,sizeof(struct MyListStruct)); //內存拷貝
	new_p->next=head; //尾節點指向頭

	/*4. 新節點添加*/
	p->next=new_p;
}

/*
函數功能: 刪除鏈表節點
*/
void DeleteListNode(struct MyListStruct *head,int a)
{
	struct MyListStruct *p=head; //保存頭地址
	struct MyListStruct *tmp=NULL;

	/*查找數據存在的節點位置*/
	while(p->next!=head)
	{
		tmp=p; //保存上一個節點的地址
		p=p->next;
		if(p->a==a)  //查找成功
		{
			tmp->next=p->next; //將要刪除節點的指針值賦值給刪除節點的上一個節點指針域
							   //tmp->next=tmp->next->next;
			free(p); //直接釋放p節點空間
					 //break;
			p=head; //重新指向鏈表頭
		}
	}
}
/*
函數功能: 遍歷所有鏈表信息
*/
void  PintListInfo(struct MyListStruct *head)
{
	int cnt=0;
	struct MyListStruct *p=head;
	printf("\n鏈表遍歷的數據如下:\n");
	while(p->next!=head)
	{
		p=p->next;
		cnt++;
		printf("第%d個節點的數據=%d\n",cnt,p->a);
	}
}

3.2 雙向鏈表

#include 
#include 
#include 

//定義結構體
struct MyListStruct
{
	int a;
	struct MyListStruct *next; //結構體指針。存放下一個節點的地址
	struct MyListStruct *old;  //結構體指針。存放上一個節點的地址
};
//定義鏈表頭
struct MyListStruct *ListHead=NULL;

//函數聲明
struct MyListStruct *CreateListHead(struct MyListStruct *head);
void  PintListInfo(struct MyListStruct *head);
void AddListNode(struct MyListStruct *head,struct MyListStruct NewNode);
void DeleteListNode(struct MyListStruct *head,int a);
void  PintListInfo_old(struct MyListStruct *head);
int main()
{
	int i;
	struct MyListStruct temp;
	int a;
	//1. 創建鏈表頭
	ListHead=CreateListHead(ListHead);

	//2. 添加節點
	for(i=0; i<5; i++)
	{
		printf("輸入新節點數據:");
		scanf("%d",&temp.a);
		AddListNode(ListHead,temp);
	}

	//3. 打印所有節點數據
	PintListInfo(ListHead);
	PintListInfo_old(ListHead);

	//4. 刪除節點數據
	printf("輸入刪除的節點數據值:");
	scanf("%d",&a);
	DeleteListNode(ListHead,a);

	//5. 打印所有節點數據
	PintListInfo(ListHead);
	PintListInfo_old(ListHead);
	return 0;
}
/*
函數功能: 創建鏈表頭
返回值  : 鏈表頭指針
*/
struct MyListStruct *CreateListHead(struct MyListStruct *head)
{
	if(head==NULL)
	{
		head=malloc(sizeof(struct MyListStruct));
		head->next=NULL; //尾節點指向空
		head->old=head;  //上一個節點指向頭
	}
	return head; //返回鏈表頭
}

/*
函數功能: 添加鏈表節點
說明: 鏈表頭一般不存放數據
*/
void AddListNode(struct MyListStruct *head,struct MyListStruct NewNode)
{
	struct MyListStruct *p=head;     //保存頭地址
	struct MyListStruct *new_p=NULL; //新的節點
    
	/*1. 尋找鏈表尾*/
	while(p->next!=NULL)
	{
		p=p->next; //移動到下一個地址
	}
	/*2. 創建新節點*/
	new_p=malloc(sizeof(struct MyListStruct));
	if(new_p==NULL)
	{
		printf("新節點內存申請失敗!\n");
		return;
	}
	/*3. 新節點賦值*/
	memcpy(new_p,&NewNode,sizeof(struct MyListStruct)); //內存拷貝
	new_p->next=NULL; //尾節點指向NULL
	new_p->old=p;     //保存上一個節點的地址
	/*4. 新節點添加*/
	p->next=new_p;
}

/*
函數功能: 刪除鏈表節點
順向刪除。
*/
void DeleteListNode(struct MyListStruct *head,int a)
{
	struct MyListStruct *p=head; //保存頭地址
	struct MyListStruct *tmp=NULL;

	/*查找數據存在的節點位置*/
	while(p->next!=NULL)
	{
		tmp=p; //保存上一個節點的地址
		p=p->next;
		if(p->a==a)  //查找成功
		{
			tmp->next=p->next; //將要刪除節點的指針值賦值給刪除節點的上一個節點指針域
							   //tmp->next=tmp->next->next;
			p->next->old=tmp;  //保存上一個節點的地址

			free(p); //直接釋放p節點空間
					 //break;
			p=head; //重新指向鏈表頭
		}
	}
}
/*
函數功能: 遍歷所有鏈表信息
從頭到尾遍歷
*/
void  PintListInfo(struct MyListStruct *head)
{
	int cnt=0;
	struct MyListStruct *p=head;
	printf("\n(順向)鏈表遍歷的數據如下:\n");
	while(p->next!=NULL)
	{
		p=p->next;
		cnt++;
		printf("第%d個節點的數據=%d\n",cnt,p->a);
	}
}

/*
函數功能: 遍歷所有鏈表信息
從尾到頭遍歷
*/
void  PintListInfo_old(struct MyListStruct *head)
{
	int cnt=0;
	struct MyListStruct *p=head;
	printf("\n(逆向)鏈表遍歷的數據如下:\n");
	/*1. 找到鏈表尾*/
	while(p->next!=NULL)
	{
		p=p->next;
	}
	/*2. 通過鏈表尾遍歷鏈表的數據*/
	while(p!=head)
	{
		cnt++;
		printf("第%d個節點的數據=%d\n",cnt,p->a);
		p=p->old; //訪問上一個節點
	}
}
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7630

    瀏覽量

    140284
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    11030
  • 鏈表
    +關注

    關注

    0

    文章

    80

    瀏覽量

    10785
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    C語言-鏈表(單向鏈表、雙向鏈表)

    在前面章節已經學習了數組的使用,數組的空間是連續空間,數組的大小恒定的,在很多動態數據存儲的應用場景下,使用不方便;而這篇文章介紹的鏈表結構,支持動態增加節點,釋放節點,比較適合存儲動態數據的應用場景,而且鏈表的空間是存儲在堆上面的,可以動態分配,釋放
    的頭像 發表于 09-09 11:30 ?1924次閱讀

    源碼|學生信息管理系統(C語言鏈表實現)

    源碼|學生信息管理系統(C語言鏈表實現)
    發表于 11-03 10:24 ?610次閱讀

    C語言實現靜態鏈表的建立

    在這么卷的時代,我覺得硬件工程師還是 要掌握基本的C語言編寫能力,鏈表在學生階段是一個比較難的知識點,可能有些同學上完一個大學都不會鏈表的編寫,但是在未來工作中,
    發表于 01-13 15:08 ?906次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>實現靜態<b class='flag-5'>鏈表</b>的建立

    C語言算法題:反轉一個單向鏈表

    鏈表是編程學習的一個難點。其實,在C語言編程以及單片機裸機開發中,鏈表運用并不多。但是如果想提升嵌入式技能水平或收入水平,可以考慮深入嵌入式系統層面(如參與操作系統設計、深入學習新的操
    發表于 06-21 11:07 ?1306次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>算法題:反轉一個單向<b class='flag-5'>鏈表</b>

    C語言鏈表知識點(2)

    C語言鏈表知識點(2)
    發表于 08-22 10:38 ?419次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>鏈表</b>知識點(2)

    C語言鏈表

    C語言鏈表,,,
    發表于 11-07 17:19

    C語言玩轉鏈表

    C語言是必學的一個課程,不管你是單片機還是嵌入式物聯網,都是基礎,所以還是要好好學習的今天推薦的資料是關于C語言鏈表的資料我自己看了一下主要
    發表于 11-13 13:50

    怎么實現c語言循環鏈表

    怎么實現c語言循環鏈表
    發表于 10-19 06:07

    請問鏈表在單片機C語言中有應用嗎?

    鏈表在單片機C語言中有應用么?
    發表于 10-16 07:28

    C語言鏈表的作用是什么?

    C語言中指針用的很少,鏈表、文件操作幾乎沒用過,所以也不能理解到底有什么作用。各位有經常在做程序時會用到這些嗎。
    發表于 11-06 06:23

    C語言實現單鏈表舉例

    所謂鏈表,就是用一組任意的存儲單元存儲線性表元素的一種數據結構。鏈表又分為單鏈表、雙向鏈表和循環鏈表等。我們先講講單
    發表于 07-11 16:40 ?87次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>實現單<b class='flag-5'>鏈表</b>舉例

    C加加建立動態鏈表

    C加加建立動態鏈表利用C語言c++編寫程序
    發表于 11-19 13:43 ?0次下載

    C語言_指針總結_經典講解

    C語言_指針總結_經典講解。
    發表于 01-06 13:47 ?10次下載

    C語言鏈表相關資料下載

    C語言鏈表相關資料
    發表于 03-08 10:47 ?5次下載

    總結那么幾個C語言中的“坑”

    總結幾個C語言中的“坑”
    的頭像 發表于 01-16 10:52 ?2828次閱讀