最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言單鏈表的圖文示例講解

 更新時(shí)間:2023年02月14日 14:42:05   作者:[Pokemon]大貓貓  
單鏈表是鏈表的其中一種基本結(jié)構(gòu)。一個(gè)最簡單的結(jié)點(diǎn)結(jié)構(gòu)如圖所示,它是構(gòu)成單鏈表的基本結(jié)點(diǎn)結(jié)構(gòu)。在結(jié)點(diǎn)中數(shù)據(jù)域用來存儲(chǔ)數(shù)據(jù)元素,指針域用于指向下一個(gè)具有相同結(jié)構(gòu)的結(jié)點(diǎn)。?因?yàn)橹挥幸粋€(gè)指針結(jié)點(diǎn),稱為單鏈表

在上一篇所講述的 動(dòng)態(tài)順序表 中存在一些缺陷

1、當(dāng)空間不夠時(shí)需要擴(kuò)容,擴(kuò)容是有一定的消耗的

如果每次空間擴(kuò)大一點(diǎn),可能會(huì)造成空間的浪費(fèi),而空間擴(kuò)小了,又會(huì)造成頻繁的擴(kuò)容2、在順序表中進(jìn)行頭部和中部的插入時(shí)需要移動(dòng)數(shù)據(jù),效率低下

對于順序表的這些缺陷,有如下解決方案

1、需要時(shí)申請一塊空間,不需要時(shí)將其釋放

2、插入刪除不需要移動(dòng)數(shù)據(jù)

而鏈表就符合這兩點(diǎn),本篇介紹 無頭單向非循環(huán)鏈表(單鏈表)

一、單鏈表的結(jié)構(gòu)

空鏈表: 此時(shí)沒有存儲(chǔ)數(shù)據(jù),只有一個(gè)指針指向 NULL

以上便是單鏈表的結(jié)構(gòu):

  • 每一塊空間可以按需申請釋放
  • 插入和刪除不需要移動(dòng)數(shù)據(jù),修改每塊空間的指針指向即可

在習(xí)慣上將申請的一塊一塊的空間稱為結(jié)點(diǎn),指向第一個(gè)結(jié)點(diǎn)的指針稱為頭指針

//數(shù)據(jù)的類型:這里以 int 來舉例
typedef int SLTDataType;
//結(jié)點(diǎn)的類型
typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

二、單鏈表的函數(shù)接口

1. 申請結(jié)點(diǎn)及打印單鏈表

在插入時(shí)需要申請結(jié)點(diǎn),為了避免麻煩重復(fù)的操作,這里將申請結(jié)點(diǎn)封裝為一個(gè)函數(shù)

申請結(jié)點(diǎn)函數(shù)如下:

SLTNode* BuySLTNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if(newnode == NULL)
	{
		//開辟空間失敗,打印錯(cuò)誤信息
		perror("malloc");
		//結(jié)束程序
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

為了驗(yàn)證插入、刪除等得到的結(jié)果是否正確,提供打印單鏈表的函數(shù),這里數(shù)據(jù)類型以 int 為例,當(dāng)讀者采用的類型不同時(shí),自行更改函數(shù)即可

打印單鏈表函數(shù)如下:

void SLTPrint(SLTNode* phead)
{
	SLTNode* cur = phead;
	//打印數(shù)據(jù)
	while(cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

2. 尾插尾刪

尾插:在鏈表的最后一個(gè)結(jié)點(diǎn)之后插入結(jié)點(diǎn)

尾插函數(shù)如下:

//在鏈表為空時(shí),需要改變頭指針,這里采用傳二級指針的方式
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	//申請結(jié)點(diǎn)
	SLTNode* newnode = BuySLTNode(x);
	//鏈表為空時(shí)
	if(*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		//找到最后一個(gè)結(jié)點(diǎn)
		SLTNode* ptail = *pphead;
		while(ptail->next)
		{
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}
}

尾刪:刪除鏈表最后一個(gè)結(jié)點(diǎn)

尾刪函數(shù)如下:

//鏈表只有一個(gè)結(jié)點(diǎn)時(shí),需要改變頭指針,這里采用傳二級指針的方式
void SLTPopBack(SLTNode** pphead)
{
	//鏈表為空時(shí),無法刪除
	assert(*pphead);
	//鏈表只有一個(gè)結(jié)點(diǎn)時(shí)
	if((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		//找到倒數(shù)第二個(gè)結(jié)點(diǎn)
		SLTNode* ptail = *pphead;
		while(ptail->next->next)
		{
			ptail = ptail->next;
		}
		free(ptail->next);
		ptail->next = NULL;
	}
}

3. 頭插頭刪

頭插: 在第一個(gè)結(jié)點(diǎn)之前插入新結(jié)點(diǎn)

頭插函數(shù)如下:

//需要改變頭指針,這里采用傳二級指針的方式
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	//申請結(jié)點(diǎn)
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}

頭刪:刪除鏈表的第一個(gè)結(jié)點(diǎn)

頭刪函數(shù)如下:

//需要改變頭指針,這里采用傳二級指針的方式
void SLTPopFront(SLTNode** pphead)
{
	//鏈表為空時(shí),無法刪除
	assert(*pphead);
	//保存第二個(gè)結(jié)點(diǎn)
	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}

4. 中間插入和刪除

中間插入:通過后面介紹的查找函數(shù) SLTFind 獲得指向結(jié)點(diǎn)的指針 pos,在 pos 指向的 結(jié)點(diǎn)之前 或 之后 插入結(jié)點(diǎn)

1. 在 pos 指向的結(jié)點(diǎn)之后插入結(jié)點(diǎn)

在 pos 之后插入結(jié)點(diǎn)函數(shù)如下:

void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	//pos 不能為空
	assert(pos);
	//申請結(jié)點(diǎn)
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

2. 在 pos 指向的結(jié)點(diǎn)之前插入結(jié)點(diǎn)

在 pos 之前插入結(jié)點(diǎn)函數(shù)如下:

//pos 指向頭結(jié)點(diǎn)時(shí),需要改變頭指針,這里采用傳二級指針的方式
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	//pos 不能為空
	assert(pos);
	//頭插
	if(*pphead == pos)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		//找到 pos 的前一個(gè)結(jié)點(diǎn)
		SLTNode* prev = *pphead;
		while(prev->next != pos)
		{
			prev = prev->next;
		}
		//申請結(jié)點(diǎn)
		SLTNode* newnode = BuySLTNode(x);
		newnode->next = pos;
		prev->next = newnode;
	}
}

中間刪除:通過后面介紹的查找函數(shù) SLTFind 獲得指向結(jié)點(diǎn)的指針 pos,刪除 pos 指向的結(jié)點(diǎn) 或 后一個(gè)結(jié)點(diǎn)

3. 刪除 pos 指向的結(jié)點(diǎn)的后一個(gè)結(jié)點(diǎn)

刪除 pos 之后的結(jié)點(diǎn)函數(shù)如下:

void SLTEraseAfter(SLTNode* pos)
{
	//pos 不能為空
	assert(pos);
	//指向最后一個(gè)結(jié)點(diǎn)時(shí),不做處理
	if(pos->next == NULL)
	{
		return;
	}
	else
	{
		//保存后一個(gè)結(jié)點(diǎn)
		SLTNode* next = pos->next;
		pos->next = next->next;
		free(next);
	}
}

4. 刪除 pos 指向的結(jié)點(diǎn)

刪除 pos 指向的結(jié)點(diǎn)函數(shù)如下:

//pos 指向頭結(jié)點(diǎn)時(shí),需要改變頭指針,這里采用傳二級指針的方式
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	//pos 不能為空
	assert(pos);
	//頭刪
	if (*pphead == pos)
	{
		SLTPopFront(pphead);
	}
	else
	{
		//找到 pos 的前一個(gè)結(jié)點(diǎn)
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

6. 查找

查找:如果數(shù)據(jù)存在,返回該數(shù)據(jù)結(jié)點(diǎn)的指針,不存在返回 NULL

查找函數(shù)如下:

SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	SLTNode* cur = phead;
	//查找
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

7. 銷毀單鏈表

在單鏈表中,存儲(chǔ)數(shù)據(jù)的結(jié)點(diǎn)是由自己開辟的,當(dāng)不使用單鏈表時(shí),應(yīng)將其銷毀

銷毀單鏈表函數(shù)如下:

需要將頭指針置空,這里采用傳二級指針的方式
void SLTDestroy(SLTNode** pphead)
{
	SLTNode* cur = *pphead;
	while (cur)
	{
		//保存下一個(gè)結(jié)點(diǎn)
		SLTNode* nextnode = cur->next;
		free(cur);
		cur = nextnode;
	}
	//將頭指針置空
	*pphead = NULL;
}

到此這篇關(guān)于C語言單鏈表的圖文示例講解的文章就介紹到這了,更多相關(guān)C語言單鏈表 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++線程間的互斥和通信場景分析

    C++線程間的互斥和通信場景分析

    很多朋友對C++線程間的互斥和通信知識(shí)掌握不是多牢靠,今天小編通過模擬車站賣票應(yīng)用場景給大家詳細(xì)解析C++線程間的互斥和通信知識(shí),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • strings命令分析淺談Go和C++編譯時(shí)的一點(diǎn)小區(qū)別

    strings命令分析淺談Go和C++編譯時(shí)的一點(diǎn)小區(qū)別

    今天小編就為大家分享一篇關(guān)于strings命令分析淺談Go和C++編譯時(shí)的一點(diǎn)小區(qū)別,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • OpenCV使用BSM統(tǒng)計(jì)視頻中移動(dòng)的對象

    OpenCV使用BSM統(tǒng)計(jì)視頻中移動(dòng)的對象

    這篇文章主要為大家詳細(xì)介紹了OpenCV如何使用BackgroundSubstractor(BSM)實(shí)現(xiàn)視頻中移動(dòng)對象統(tǒng)計(jì)功能,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2023-02-02
  • C語言kmp算法簡單示例和實(shí)現(xiàn)原理探究

    C語言kmp算法簡單示例和實(shí)現(xiàn)原理探究

    這篇文章主要介紹了C語言kmp算法簡單示例和實(shí)現(xiàn)原理探究,本文用簡潔的語言說明KMP算法的原理,并給出了示例,需要的朋友可以參考下
    2014-09-09
  • C語言實(shí)現(xiàn)的學(xué)生選課系統(tǒng)代碼分享

    C語言實(shí)現(xiàn)的學(xué)生選課系統(tǒng)代碼分享

    這篇文章主要介紹了C語言實(shí)現(xiàn)的學(xué)生選課系統(tǒng)代碼分享,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • 淺析C語言位域和位段

    淺析C語言位域和位段

    以下是對C語言中的位域和位段進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)

    Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)

    用于數(shù)據(jù)傳輸?shù)牡蛯泳W(wǎng)絡(luò)協(xié)議,多個(gè)物聯(lián)網(wǎng)協(xié)議都是基于TCP協(xié)議的,這篇文章為大家介紹了Qt?TCP網(wǎng)絡(luò)通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語言中組成不重復(fù)的三位數(shù)問題

    C語言中組成不重復(fù)的三位數(shù)問題

    這篇文章主要介紹了C語言中組成不重復(fù)的三位數(shù)問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • opencv提取外部輪廓并在外部加矩形框

    opencv提取外部輪廓并在外部加矩形框

    這篇文章主要為大家詳細(xì)介紹了opencv提取外部輪廓并在外部加矩形框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • 一文讀懂c++之static關(guān)鍵字

    一文讀懂c++之static關(guān)鍵字

    這篇文章主要介紹了c++之static關(guān)鍵字的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06

最新評論

嘉义市| 廉江市| 安塞县| 郎溪县| 驻马店市| 刚察县| 东丽区| 策勒县| 纳雍县| 罗田县| 揭阳市| 扎鲁特旗| 巴楚县| 大新县| 杭锦后旗| 会东县| 密山市| 曲靖市| 崇阳县| 大名县| 石城县| 区。| 枣庄市| 玛沁县| 福建省| 华坪县| 黄冈市| 保山市| 翁牛特旗| 焉耆| 贡觉县| 阳新县| 四会市| 沈阳市| 浦城县| 泸溪县| 农安县| 马鞍山市| 怀化市| 临汾市| 建昌县|