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

數(shù)據(jù)結(jié)構(gòu)之鏈?zhǔn)蕉鏄?shù)詳解

 更新時(shí)間:2023年04月17日 10:05:49   作者:蛋超飯不要加蛋  
所謂二叉樹(shù)遍歷 (Traversal) 是按照某種特定的規(guī)則,依次對(duì)二叉樹(shù)中的節(jié)點(diǎn)進(jìn)行相應(yīng)的操作,并且每個(gè)節(jié)點(diǎn)只操作一次。本文通過(guò)代碼示例詳細(xì)介紹了C語(yǔ)言中的鏈?zhǔn)蕉鏄?shù),需要的朋友可以參考一下

??1.二叉樹(shù)的遍歷??

所謂二叉樹(shù)遍歷 (Traversal) 是按照某種特定的規(guī)則,依次對(duì)二叉樹(shù)中的節(jié)點(diǎn)進(jìn)行相應(yīng)的操作,并且每個(gè)節(jié)點(diǎn)只操作一次。 訪問(wèn)結(jié)點(diǎn)所做的操作依賴(lài)于具體的應(yīng)用問(wèn)題。遍歷 是二叉樹(shù)上最重要的運(yùn)算之一,也是二叉樹(shù)上進(jìn)行其它運(yùn)算的基礎(chǔ)。
按照規(guī)則,二叉樹(shù)的遍歷分為: 前序遍歷、中序遍歷、后序遍歷的遞歸遍歷,層序遍歷的非遞歸遍歷下面將以下面的二叉樹(shù)為例講解四種遍歷

1.1前序遍歷

二叉樹(shù)的前序遍歷也叫先序遍歷,遍歷的順序?yàn)椋焊?、左子?shù)、右子樹(shù),即遇到一棵樹(shù),先訪問(wèn)根節(jié)點(diǎn),再訪問(wèn)左子樹(shù)和右子樹(shù),訪問(wèn)左子樹(shù)和右子樹(shù)的過(guò)程又分為先訪問(wèn)根節(jié)點(diǎn),再訪問(wèn)左子樹(shù)和右子樹(shù),這是一個(gè)遞歸訪問(wèn)的過(guò)程,因此前序遍歷屬于遞歸遍歷

遍歷的過(guò)程將以文字和圖片兩種方式展現(xiàn)

遍歷過(guò)程:

先遇到根節(jié)點(diǎn)1,訪問(wèn)根節(jié)點(diǎn)1,再訪問(wèn)1的左子樹(shù)

1的左子樹(shù):遇到根節(jié)點(diǎn)2,訪問(wèn)根節(jié)點(diǎn)2,再訪問(wèn)2的左子樹(shù),2的左子樹(shù)只有一個(gè)根節(jié)點(diǎn)3,3的左右子樹(shù)為空因此不需要訪問(wèn)3的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)3便結(jié)束,2的左子樹(shù)遍歷結(jié)束訪問(wèn)2的右子樹(shù),2的右子樹(shù)為空即不用訪問(wèn),此時(shí)2的整顆樹(shù)遍歷結(jié)束,即1的左子樹(shù)遍歷結(jié)束,然后接著訪問(wèn)1的右子樹(shù)

1的右子樹(shù):遇到根節(jié)點(diǎn)4,訪問(wèn)根節(jié)點(diǎn)4,再訪問(wèn)4的左子樹(shù),4的左子樹(shù)只有一個(gè)根節(jié)點(diǎn)5,5的左右子樹(shù)為空因此不需要訪問(wèn)5的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)5便結(jié)束,4的左子樹(shù)遍歷結(jié)束訪問(wèn)4的右子樹(shù),4的右子樹(shù)只有一個(gè)根節(jié)點(diǎn)6,6的左右子樹(shù)為空因此不需要訪問(wèn)6的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)6便結(jié)束,此時(shí)4的整顆樹(shù)遍歷結(jié)束,即1的右子樹(shù)遍歷結(jié)束

整棵樹(shù)遍歷完成,遍歷序列為:1 2 3 4 5 6

遍歷圖示:

1.2中序遍歷

二叉樹(shù)的中序遍歷也叫中根遍歷,遍歷的順序?yàn)椋鹤笞訕?shù)、根、右節(jié)點(diǎn),即遇到一棵樹(shù),先訪問(wèn)它的左子樹(shù),再訪問(wèn)根,最后訪問(wèn)右子樹(shù),訪問(wèn)左子樹(shù)和右子樹(shù)的過(guò)程又分為先訪問(wèn)左子樹(shù),再訪問(wèn)根和右子樹(shù),這是一個(gè)遞歸訪問(wèn)的過(guò)程,因此中序遍歷也屬于遞歸遍歷

遍歷的過(guò)程將以文字和圖片兩種方式展現(xiàn)

遍歷過(guò)程:

遇到根節(jié)點(diǎn)1,先不訪問(wèn)根節(jié)點(diǎn),先訪問(wèn)1的左子樹(shù)

1的左子樹(shù):遇到根節(jié)點(diǎn)2,先不訪問(wèn)根節(jié)點(diǎn)2,先訪問(wèn)2的左子樹(shù):2的左子樹(shù)只有一個(gè)根節(jié)點(diǎn)3,3的左右子樹(shù)為空因此不需要訪問(wèn)3的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)3便結(jié)束,此時(shí)2的左子樹(shù)結(jié)束,訪問(wèn)根節(jié)點(diǎn)2,然后訪問(wèn)2的右子樹(shù),2的右子樹(shù)為空則不訪問(wèn),此時(shí)2的整顆樹(shù)遍歷結(jié)束,即1的左子樹(shù)遍歷結(jié)束

訪問(wèn)根節(jié)點(diǎn)1,接著訪問(wèn)1的右子樹(shù)

1的右子樹(shù):遇到根節(jié)點(diǎn)4,先不訪問(wèn)根節(jié)點(diǎn)4,先訪問(wèn)4的左子樹(shù):遇到根節(jié)點(diǎn)5,5的左右子樹(shù)為空因此不需要訪問(wèn)5的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)5便結(jié)束,此時(shí)4的左子樹(shù)訪問(wèn)結(jié)束,訪問(wèn)根節(jié)點(diǎn)4,接著訪問(wèn)4的右子樹(shù),4的右子樹(shù)只有一個(gè)根節(jié)點(diǎn)6,6的左右子樹(shù)為空因此不需要訪問(wèn)6的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)6便結(jié)束,此時(shí)4的整棵樹(shù)訪問(wèn)結(jié)束,即1的右子樹(shù)訪問(wèn)結(jié)束

整棵樹(shù)遍歷完成,遍歷序列:3 2 1 5 4 6

 遍歷圖示:

1.3后序遍歷

二叉樹(shù)的后序遍歷也叫后根遍歷,遍歷的順序?yàn)椋鹤笞訕?shù)、右子樹(shù)、根,即遇到一棵樹(shù),先訪問(wèn)它的左子樹(shù),再訪問(wèn)右子樹(shù),最后訪問(wèn)根,訪問(wèn)左子樹(shù)和右子樹(shù)的過(guò)程又分為先訪問(wèn)左子樹(shù),再訪問(wèn)右子樹(shù)和根,這是一個(gè)遞歸訪問(wèn)的過(guò)程,因此后序遍歷也屬于遞歸遍歷

遍歷的過(guò)程將以文字和圖片兩種方式展現(xiàn)

遍歷過(guò)程:

遇到根節(jié)點(diǎn)1,先不訪問(wèn)根節(jié)點(diǎn)1,先訪問(wèn)左子樹(shù)

1的左子樹(shù):遇到根節(jié)點(diǎn)2,先不訪問(wèn)根節(jié)點(diǎn)2,先訪問(wèn)2的左子樹(shù):2的左子樹(shù)只有根節(jié)點(diǎn)3,3的左右子樹(shù)為空因此不需要訪問(wèn)3的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)3便結(jié)束,此時(shí)2的左子樹(shù)訪問(wèn)結(jié)束,接著訪問(wèn)2的右子樹(shù),2的右子樹(shù)為空因此不需要訪問(wèn),此時(shí)2的左右子樹(shù)訪問(wèn)結(jié)束,最后訪問(wèn)根節(jié)點(diǎn)2,此時(shí)2的整顆樹(shù)訪問(wèn)結(jié)束,即1的左子樹(shù)訪問(wèn)結(jié)束,接著訪問(wèn)1的右子樹(shù)

1的右子樹(shù):遇到根節(jié)點(diǎn)4,先不訪問(wèn)根節(jié)點(diǎn)4,先訪問(wèn)4的左子樹(shù):5的左右子樹(shù)為空因此不需要訪問(wèn)5的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)5便結(jié)束,此時(shí)4的左子樹(shù)訪問(wèn)結(jié)束,接著訪問(wèn)4的右子樹(shù),6的左右子樹(shù)為空因此不需要訪問(wèn)6的左右子樹(shù),訪問(wèn)根節(jié)點(diǎn)6便結(jié)束,此時(shí)4的左右子樹(shù)遍歷結(jié)束,最后訪問(wèn)根節(jié)點(diǎn)4,4的整顆樹(shù)訪問(wèn)結(jié)束,即1的右子樹(shù)訪問(wèn)結(jié)束

最后訪問(wèn)根節(jié)點(diǎn)1,整棵樹(shù)遍歷結(jié)束,遍歷序列:3 2 5 6 4 1

 遍歷圖示:

1.4層次遍歷

除了先序遍歷、中序遍歷、后序遍歷外,還可以對(duì)二叉樹(shù)進(jìn)行層序遍歷。設(shè)二叉樹(shù)的根節(jié)點(diǎn)所在層數(shù)為1, 層序遍歷就是從所在二叉樹(shù)的根節(jié)點(diǎn)出發(fā),首先訪問(wèn)第一層的樹(shù)根節(jié)點(diǎn),然后從左到右訪問(wèn)第 2 層上的節(jié)點(diǎn),接著是第三層的節(jié)點(diǎn),以此類(lèi)推, 自上而下,自左至右逐層訪問(wèn)樹(shù)的結(jié)點(diǎn)的過(guò)程就是層序遍歷。

遍歷圖示:

由上圖可以看出,層序遍歷為非遞歸遍歷

 ??2.鏈?zhǔn)蕉鏄?shù)的實(shí)現(xiàn)??

鏈?zhǔn)蕉鏄?shù)的實(shí)現(xiàn)包括二叉樹(shù)的創(chuàng)建、遍歷、銷(xiāo)毀、求節(jié)點(diǎn)個(gè)數(shù)、求葉子節(jié)點(diǎn)個(gè)數(shù)、求二叉樹(shù)的深度、求第k層節(jié)點(diǎn)個(gè)數(shù)、查找、判斷是否是完全二叉樹(shù)等

下面我們一一來(lái)實(shí)現(xiàn)這些接口

typedef struct BinaryTreeNode
{
	BTDataType data;
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
}BTNode;

2.1二叉樹(shù)的創(chuàng)建

給定一個(gè)前序遍歷字符串,按照此字符串以指針?lè)绞綐?gòu)建一顆二叉樹(shù)

給定字符串ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空樹(shù)

代碼設(shè)計(jì)思路:

函數(shù)參數(shù)為字符串指針和下標(biāo)指針,利用遞歸的思想,首先判斷是否遇到空格,遇到空格則跳過(guò)該空格即下標(biāo)加1并返回,接著構(gòu)建一個(gè)節(jié)點(diǎn),當(dāng)前字符指針指向的字符賦值給節(jié)點(diǎn)的值域然后下標(biāo)加1,將字符指針和下標(biāo)傳參調(diào)用遞歸函數(shù)然后用節(jié)點(diǎn)的左指針接收。再將字符指針和下標(biāo)傳參調(diào)用遞歸函數(shù)然后用節(jié)點(diǎn)的右指針接收,最后返回節(jié)點(diǎn)指針

BTNode *TreeBuild(char *arr,int* i)
{
    if(arr[*i]=='#')//遇到空格則跳過(guò)該空格
    {
        (*i)++;
        return NULL;
    }
    // 建立節(jié)點(diǎn)
    BTNode *root=(BTNode *)malloc(sizeof(BTNode));
    //節(jié)點(diǎn)的值為當(dāng)前下標(biāo)指向的字符
    rot->data=arr[(*i)++];
    //調(diào)用遞歸,并用節(jié)點(diǎn)的左指針接收
    root->left=TreeBuild(arr,i);
    //調(diào)用遞歸,并用節(jié)點(diǎn)的左指針接收
    root->right=TreeBuild(arr,i);
    return root;
}

2.2前序遍歷

前序遍歷的過(guò)程在前面已經(jīng)介紹,我們按照過(guò)程設(shè)計(jì)相應(yīng)的函數(shù)

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則直接返回,先打印當(dāng)前節(jié)點(diǎn)的值,再將自己的左子樹(shù)作為參數(shù)調(diào)用遞歸遍歷,最后將自己的右子樹(shù)作為參數(shù)調(diào)用遞歸遍歷

代碼:

void PreOrder(BTNode* root)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則直接返回
		return NULL;
	printf("%d ", root->data);//打印當(dāng)前節(jié)點(diǎn)的值
	PreOrder(root->left);//遞歸遍歷左子樹(shù)
	PreOrder(root->right);//遞歸調(diào)用右子樹(shù)
}

2.3中序遍歷

中序遍歷的過(guò)程在前面已經(jīng)介紹,我們按照過(guò)程設(shè)計(jì)相應(yīng)的函數(shù)

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則直接返回,先將自己的左子樹(shù)作為參數(shù)調(diào)用遞歸遍歷,再打印當(dāng)前節(jié)點(diǎn)的值,最后將自己的右子樹(shù)作為參數(shù)調(diào)用遞歸遍歷

代碼:

void InOrder(BTNode* root)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則直接返回
		return NULL;
	InOrder(root->left);//遞歸遍歷左子樹(shù)
	printf("%d ", root->data);//打印當(dāng)前節(jié)點(diǎn)的值
	InOrder(root->right);//遞歸調(diào)用右子樹(shù)
}

2.4后序遍歷

后序遍歷的過(guò)程在前面已經(jīng)介紹,我們按照過(guò)程設(shè)計(jì)相應(yīng)的函數(shù)

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則直接返回,先將自己的左子樹(shù)作為參數(shù)調(diào)用遞歸遍歷,再將自己的右子樹(shù)作為參數(shù)調(diào)用遞歸遍歷,最后打印當(dāng)前節(jié)點(diǎn)的值

void PostOrder(BTNode* root)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則直接返回
		return NULL;
	PostOrder(root->left);//遞歸遍歷左子樹(shù)
	PostOrder(root->right);//遞歸調(diào)用右子樹(shù)
	printf("%d ", root->data);//打印當(dāng)前節(jié)點(diǎn)的值
}

2.5層序遍歷

層序遍歷的過(guò)程在前面已經(jīng)介紹,我們按照過(guò)程設(shè)計(jì)相應(yīng)的函數(shù)

代碼設(shè)計(jì)思路:

利用隊(duì)列,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則直接返回。把第一個(gè)節(jié)點(diǎn)的指針入隊(duì),然后進(jìn)去循環(huán)(循環(huán)條件是隊(duì)列不為空),定義一個(gè)指針拿到隊(duì)列的第一個(gè)節(jié)點(diǎn),然后出隊(duì)并打印節(jié)點(diǎn)的值,出隊(duì)之后將節(jié)點(diǎn)的左右孩子入隊(duì),如果節(jié)點(diǎn)的左孩子存在,則將左孩子指針入隊(duì),如果節(jié)點(diǎn)的右孩子存在,則將右孩子指針入隊(duì),然后又繼續(xù)取隊(duì)頭元素打印,直到隊(duì)列為空

代碼:

void LevelOrder(BTNode *root)
{
	Queue q;//定義一個(gè)隊(duì)列
	QueueInit(&q);//隊(duì)列初始化
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則返回
		return;
	QueuePush(&q, root);//將第一個(gè)節(jié)點(diǎn)指針入隊(duì)
	while (!(QueueEmpty(&q)))//循環(huán)條件是隊(duì)列不為空,隊(duì)列為空則結(jié)束
	{
		BTNode* front = QueueFront(&q);//取隊(duì)頭節(jié)點(diǎn)
		printf("%d ", front->data);//打印節(jié)點(diǎn)的值
		QueuePop(&q);//出隊(duì)
		if (front->left)//左孩子存在,則將左孩子指針入隊(duì)
		{
			QueuePush(&q, front->left);
		}
		if (front->right)//右孩子存在,則將右孩子指針入隊(duì)
		{
			QueuePush(&q, front->right);
		}
	}
	QueueDestroy(&q);//銷(xiāo)毀隊(duì)列
}

2.6銷(xiāo)毀

銷(xiāo)毀的過(guò)程:先從最后一層開(kāi)始銷(xiāo)毀,先銷(xiāo)毀左子樹(shù),再銷(xiāo)毀右子樹(shù),最后銷(xiāo)毀根,即用到后序遍歷的思想,遞歸銷(xiāo)毀

代碼設(shè)計(jì)思路:

利用后序遍歷的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則返回。先將左孩子指針作為參數(shù)調(diào)用遞歸,再將左孩子指針作為參數(shù)調(diào)用遞歸,最后將根節(jié)點(diǎn)釋放

代碼:

void BinaryTreeDestory(BTNode* root)
{
	if(root == NULL)//為空則返回
		return;
	BinaryTreeDestory(root->left);//遞歸銷(xiāo)毀左子樹(shù)
	BinaryTreeDestory(root->right);//遞歸銷(xiāo)毀右子樹(shù)
	free(root);//最后銷(xiāo)毀根節(jié)點(diǎn)
}

2.7求節(jié)點(diǎn)個(gè)數(shù)

一顆樹(shù)的節(jié)點(diǎn)個(gè)數(shù)可以分為左子樹(shù)的節(jié)點(diǎn)數(shù)加上右子樹(shù)的節(jié)點(diǎn)數(shù)再加1即根節(jié)點(diǎn),同樣是遞歸求節(jié)點(diǎn)個(gè)數(shù)

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則返回0,然后將左孩子指針作為參數(shù)調(diào)用遞歸,再將右孩子指針作為參數(shù)調(diào)用遞歸,最后將兩者的值加1返回,即節(jié)點(diǎn)個(gè)數(shù)等于左子樹(shù)的節(jié)點(diǎn)個(gè)數(shù)+右子樹(shù)的節(jié)點(diǎn)個(gè)數(shù)+1

 代碼:

int  TreeSize(BTNode* root)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則返回0
		return 0;
	//遞歸左子樹(shù)和右子樹(shù),然后將兩者的和加1返回
	return TreeSize(root->left) + TreeSize(root->right) + 1;
}

2.8求葉子節(jié)點(diǎn)個(gè)數(shù)

一顆樹(shù)的葉子節(jié)點(diǎn)個(gè)數(shù)可以分為左子樹(shù)的葉子節(jié)點(diǎn)個(gè)數(shù)+右子樹(shù)的葉子節(jié)點(diǎn)個(gè)數(shù),即同樣利用遞歸求葉子節(jié)點(diǎn)個(gè)數(shù)

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則返回0,然后判斷當(dāng)前節(jié)點(diǎn)是否為葉子結(jié)點(diǎn),左孩子和右孩子都為空的節(jié)點(diǎn)即為葉子節(jié)點(diǎn),為葉子節(jié)點(diǎn)則返回1,接著遞歸左子樹(shù)和右子樹(shù),并返回兩者的和

代碼:

int TreeLeafSize(BTNode* root)
{
	if (root ==NULL)//當(dāng)前節(jié)點(diǎn)為空則返回0
		return 0;
	if (root->left == NULL && root->right == NULL)//當(dāng)前節(jié)點(diǎn)為葉子結(jié)點(diǎn)則返回1
		return 1;
	//遞歸左子樹(shù)和右子樹(shù),并返回兩者的和
	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

2.9求二叉樹(shù)的深度

一顆樹(shù)的深度等于左右子樹(shù)的較大的深度加1(加根節(jié)點(diǎn)),即利用遞歸求左右子樹(shù)的深度,將左右子樹(shù)較大的深度加1返回

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則返回0,再判斷當(dāng)前節(jié)點(diǎn)是否為葉節(jié)點(diǎn),是葉節(jié)點(diǎn)則返回1,接著遞歸左子樹(shù)和右子樹(shù),取較大的深度加1返回

代碼:

int TreeHeight(BTNode* root)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則返回空
		return 0;
	if (root->left == NULL && root->right == NULL)//當(dāng)前節(jié)點(diǎn)為葉節(jié)點(diǎn)則返回1
		return 1;
	int left = TreeHeight(root->left);//遞歸左子樹(shù)
	int right = TreeHeight(root->right);//遞歸右子樹(shù)
	return left > right ? left + 1 : right + 1;//將左右子樹(shù)較大的深度加1返回
}

2.10求第K層節(jié)點(diǎn)個(gè)數(shù)

整顆樹(shù)的第k層可以看成第二層的第k-1層,第三層的k-2層,第k層的第1層,即整棵樹(shù)的第k層的節(jié)點(diǎn)數(shù)等于左右子樹(shù)的第k-1層節(jié)點(diǎn)子樹(shù),即利用遞歸求左右子樹(shù)的k-1層節(jié)點(diǎn)個(gè)數(shù)

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則返回0,再判斷當(dāng)前層數(shù)是否為1,為1則返回1,然后遞歸左子樹(shù),傳左子樹(shù)指針和k-1,然后遞歸右子樹(shù),傳右子樹(shù)指針和k-1,最后返回兩者的和

代碼:

int TreeLevelKSize(BTNode* root, int k)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則返回0
		return 0;
	if (k == 1)//當(dāng)前層數(shù)為1則返回1
		return 1;
	//遞歸左子樹(shù)和右子樹(shù),返回兩者的值
	return TreeLevelKSize(root->left, k - 1) + TreeLevelKSize(root->right, k - 1);
}

2.11查找

查找值為x的節(jié)點(diǎn),并返回節(jié)點(diǎn)的指針

代碼設(shè)計(jì)思路:

利用遞歸的思想,首先判斷當(dāng)前節(jié)點(diǎn)是否為空,為空則返回空,不為空則判斷當(dāng)前節(jié)點(diǎn)的值是否等于x,等于則返回該節(jié)點(diǎn),然后遞歸查找左子樹(shù),如果遞歸左子樹(shù)返回的值不為空說(shuō)明找到則返回該值,接著遞歸右子樹(shù),如果遞歸右子樹(shù)返回的值不為空說(shuō)明找到則返回該值,遞歸左右子樹(shù)都未找到說(shuō)明x不存在,返回空

代碼:

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則返回空
		return NULL;
	if (root->data == x)//當(dāng)前節(jié)點(diǎn)的值等于x則返回該節(jié)點(diǎn)
		return root;
	//遞歸左子樹(shù)查找
	BTNode* left = BinaryTreeFind(root->left,x);
	//返回的值不為空說(shuō)明已找到,返回該值
	if (left)
		return left;
	//遞歸右子樹(shù)查找
	BTNode* right = BinaryTreeFind(root->right, x);
	//返回的值不為空說(shuō)明已找到,返回該值
	if (right)
		return right;
	//遞歸左右子樹(shù)均為找到,則趕回空
	return NULL;
}

2.12判斷是否為完全二叉樹(shù)

上一篇文章介紹了完全二叉樹(shù)的概念,完全二叉樹(shù)可以看成是滿(mǎn)二叉樹(shù)以最后一層開(kāi)始從右往左挖去了幾個(gè)節(jié)點(diǎn)而成,即完全二叉樹(shù)的倒數(shù)第二層是滿(mǎn)的,倒數(shù)第一層不可能存在只有右孩子而沒(méi)有左孩子的情況

代碼設(shè)計(jì)思路:

類(lèi)似于層序遍歷的思想,利用隊(duì)列,首先判斷第一個(gè)節(jié)點(diǎn)是否為空,為空則返回,然后將第一個(gè)節(jié)點(diǎn)入隊(duì),接著進(jìn)入循環(huán)(循環(huán)條件為隊(duì)列不為空),取隊(duì)頭元素并出隊(duì),如果取到的隊(duì)頭元素為空,說(shuō)明此時(shí)已經(jīng)此時(shí)二叉樹(shù)剛好遍歷結(jié)束,則退出循環(huán)檢查后面隊(duì)列值地情況如果是完全二叉樹(shù),則隊(duì)列后面應(yīng)該都是空,如果存在不為空的元素則證明不是完全二叉樹(shù)。如果取到的隊(duì)頭元素不為空,則將其左右孩子(為空也一樣)入隊(duì),如果循環(huán)正常結(jié)束,則證明是完全二叉樹(shù)

代碼:

bool BinaryTreeComplete(BTNode* root)
{
	Queue q;//定義一個(gè)隊(duì)列
	QueueInit(&q);//隊(duì)列初始化
	if (root == NULL)//當(dāng)前節(jié)點(diǎn)為空則返回
		return;
	QueuePush(&q, root);//將第一個(gè)節(jié)點(diǎn)入隊(duì)
	while (!(QueueEmpty(&q)))
	{
		//取隊(duì)頭元素并出隊(duì)
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		//取到的隊(duì)頭元素為空則退出循環(huán),檢查隊(duì)列后面值地情況
		if (front==NULL)
		{
			break;
		}
		else//不為空則將左右孩子入隊(duì)
		{
			QueuePush(&q, front->left);
			QueuePush(&q, front->right);
		}
	}
	//檢查隊(duì)列后面的值的情況
	while (!(QueueEmpty(&q)))
	{
		BTNode* front = QueueFront(&q);//取隊(duì)頭元素并出隊(duì)
		QueuePop(&q);
		if (front != NULL)//如果有不為空的元素則證明不是完全二叉樹(shù)
		{
			QueueDestroy(&q);
			return false;
		}
	}
	QueueDestroy(&q);//銷(xiāo)毀隊(duì)列
	return true;//循環(huán)正常結(jié)束則返回true
}

好啦,關(guān)于鏈?zhǔn)蕉鏄?shù)就先學(xué)到這里,如果對(duì)您有所幫助,歡迎一鍵三連~

到此這篇關(guān)于數(shù)據(jù)結(jié)構(gòu)之鏈?zhǔn)蕉鏄?shù)詳解的文章就介紹到這了,更多相關(guān)C語(yǔ)言 鏈?zhǔn)蕉鏄?shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++11新特性之智能指針(shared_ptr/unique_ptr/weak_ptr)

    C++11新特性之智能指針(shared_ptr/unique_ptr/weak_ptr)

    這篇文章主要介紹了C++11新特性之智能指針,包括shared_ptr, unique_ptr和weak_ptr的基本使用,感興趣的小伙伴們可以參考一下
    2016-08-08
  • C++未定義行為(undefined behavior)

    C++未定義行為(undefined behavior)

    對(duì)于未定義行為,C++標(biāo)準(zhǔn)沒(méi)有明確規(guī)定編譯器們應(yīng)該怎么做,那么執(zhí)行的結(jié)果就是不可預(yù)料的。下面我們來(lái)詳細(xì)探討下
    2017-02-02
  • C++實(shí)現(xiàn)中綴轉(zhuǎn)后綴的示例詳解

    C++實(shí)現(xiàn)中綴轉(zhuǎn)后綴的示例詳解

    這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)中綴轉(zhuǎn)后綴的問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • FFmpeg獲取網(wǎng)絡(luò)攝像頭數(shù)據(jù)解碼

    FFmpeg獲取網(wǎng)絡(luò)攝像頭數(shù)據(jù)解碼

    這篇文章主要為大家詳細(xì)介紹了FFmpeg獲取網(wǎng)絡(luò)攝像頭數(shù)據(jù)解碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • C++中的模板template小結(jié)

    C++中的模板template小結(jié)

    這篇文章主要介紹了C++中的模板template的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 深入C++中API的問(wèn)題詳解

    深入C++中API的問(wèn)題詳解

    本篇文章是對(duì)C++中API的問(wèn)題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++經(jīng)典楊輝三角問(wèn)題解決方案

    C/C++經(jīng)典楊輝三角問(wèn)題解決方案

    楊輝三角形,又稱(chēng)帕斯卡三角形、賈憲三角形、海亞姆三角形,它的排列形如三角形。本文將為大家介紹通過(guò)C++/C語(yǔ)言實(shí)現(xiàn)打印楊輝三角形的示例代碼,需要的可以參考一下
    2023-02-02
  • C++中STL容器的主要使用及含義說(shuō)明

    C++中STL容器的主要使用及含義說(shuō)明

    這篇文章主要介紹了C++中STL容器的主要使用及含義說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++輸出斐波那契數(shù)列的兩種實(shí)現(xiàn)方法

    C++輸出斐波那契數(shù)列的兩種實(shí)現(xiàn)方法

    以下是對(duì)C++中輸出斐波那契數(shù)列的兩種實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-10-10
  • C語(yǔ)言用棧模擬實(shí)現(xiàn)隊(duì)列問(wèn)題詳解

    C語(yǔ)言用棧模擬實(shí)現(xiàn)隊(duì)列問(wèn)題詳解

    本片文章帶你分析如何用兩個(gè)棧,并且只使用棧的基本功能來(lái)模擬實(shí)現(xiàn)隊(duì)列,其中同樣只實(shí)現(xiàn)隊(duì)列的基本功能,感興趣的朋友來(lái)看看吧
    2022-04-04

最新評(píng)論

马公市| 柏乡县| 陇川县| 郯城县| 墨竹工卡县| 多伦县| 菏泽市| 莱阳市| 肇东市| 扎赉特旗| 苏尼特左旗| 济宁市| 广州市| 章丘市| 牡丹江市| 景谷| 丰镇市| 民乐县| 新丰县| 锡林浩特市| 江华| 永登县| 夏津县| 博乐市| 淳化县| 贵溪市| 收藏| 微山县| 八宿县| 鄂伦春自治旗| 军事| 炉霍县| 新晃| 鸡西市| 汝南县| 弥勒县| 迁西县| 盐亭县| 定西市| 新营市| 永济市|