国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

這篇具有很好參考價值的文章主要介紹了【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

??write in front??
??所屬專欄:初階數(shù)據(jù)結(jié)構(gòu)
???博客主頁:睿睿的博客主頁
???代碼倉庫:??VS2022_C語言倉庫
??您的點贊、關(guān)注、收藏、評論,是對我最大的激勵和支持!?。?br>關(guān)注我,關(guān)注我,關(guān)注我你們將會看到更多的優(yōu)質(zhì)內(nèi)容??!

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

前言

??在之前的二叉樹的順序結(jié)構(gòu)中我們發(fā)現(xiàn),該二叉樹對于堆(一種完全二叉樹)非常實用,但是對于非完全二叉樹就會出現(xiàn)以下的結(jié)構(gòu),造成空間浪費:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
??所以這里我們還是要通過鏈?zhǔn)浇Y(jié)構(gòu)來實現(xiàn)二叉樹。但是其實普通二叉樹是沒有什么意義的,增刪查改沒有多大的意義。真正有意義的是搜索二叉樹:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
??搜索二叉樹的特點是左子樹比根大/小,右子樹比根小/大。這里的二叉樹可以用來搜索,也可以用來進行插入,刪除等操作,擁有實際的意義。所以對于普通二叉樹,我們不用學(xué)習(xí)他的增刪查改,只用學(xué)習(xí)他的遍歷等操作,并且復(fù)習(xí)一下遞歸的相關(guān)知識。

一.二叉樹的理解:

我們先回顧一下回顧下二叉樹的概念,二叉樹是:

  1. 空樹
  2. 非空:根節(jié)點,根節(jié)點的左子樹、根節(jié)點的右子樹組成的。

??對于一顆二叉樹,我們看到它就要把他分為:根,左子樹,右子樹。對于左子樹,在把他分為:根,左子樹,右子樹。對于右子樹,在把他分為:根,左子樹,右子樹……以此類推直到左右子樹都為空才停止。
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
??從概念中可以看出,二叉樹定義是遞歸式的,因此后序基本操作中基本都是按照該概念實現(xiàn)的。

二.二叉樹的遍歷:

??學(xué)習(xí)二叉樹結(jié)構(gòu),最簡單的方式就是遍歷。所謂二叉樹遍歷(Traversal)是按照某種特定的規(guī)則,依次對二叉樹中的每個節(jié)點進行相應(yīng)的操作,并且每個節(jié)點只操作一次。訪問結(jié)點所做的操作依賴于具體的應(yīng)用問題。 遍歷是二叉樹上最重要的運算之一,也是二叉樹上進行其它運算的基礎(chǔ)。

??按照規(guī)則,二叉樹的遍歷有:前序/中序/后序遞歸結(jié)構(gòu)遍歷。我們以這顆二叉樹為例:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

創(chuàng)建二叉樹:

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

BTNode* BuyNode(BTDataType x)
{
	BTNode* node = (BTNode*)malloc(sizeof(BTNode));
	if (node == NULL)
	{
		perror("malloc::fail");
		return;
	}

	node->left = NULL;
	node->right = NULL;
	node->data = x;

	return node;
}


BTNode* CreatTree()
{
	BTNode* node1 = BuyNode(1);
	BTNode* node2 = BuyNode(2);
	BTNode* node3 = BuyNode(3);
	BTNode* node4 = BuyNode(4);
	BTNode* node5 = BuyNode(5);
	BTNode* node6 = BuyNode(6);
	BTNode* node7 = BuyNode(7);


	node1->left = node2;
	node1->right = node4;
	node2->left = node3;
	node4->left = node5;
	node4->right = node6;
	node3->right = node7;


	return node1;
}

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

1.前序遍歷:

??前序遍歷的順序是:根,左子樹,右子樹。

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
代碼實現(xiàn):

void PreOrder(BTNode* root)
{
	if (root = NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%d ", root->data);
	PreOrder(root->left);
	PreOrder(root->right);
}

結(jié)果:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

2.中序遍歷:

??中序遍歷的順序是:左子樹,根,右子樹。
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
代碼實現(xiàn):

void InOrder(BTNode* root)
{

	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%d ", root->data);
	InOrder(root->right);
}

結(jié)果:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

3.后序遍歷:

??后序遍歷的順序是:左子樹,右子樹,根。
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
代碼實現(xiàn):

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%d ", root->data);
}

結(jié)果:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
??其實上面的三種遍歷就是通過s三句代碼的順序?qū)е陆Y(jié)果的不同,當(dāng)然他們的遞歸過程都能用下面這張圖來代表:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

4.層序遍歷:

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

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
??那么如何實現(xiàn)層序遍歷呢?這里我們就要用到我們之前所學(xué)的隊列了!
??在這里,我們將二叉樹的根先進隊列,然后將其出隊列,每出一次,就讓其左右子結(jié)點進入隊列,隨后在出一個隊列,將其左右子節(jié)點加入隊列……這樣通過隊列的push和pop就能實現(xiàn)層序遍歷

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

我們首先將隊列的代碼導(dǎo)入即可,就可以創(chuàng)建隊列了:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
代碼實現(xiàn):

void LevelOrder(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
	{
		QueuePush(&q, root);
	}
	
	while (!QueueEmpty(&q))
	{
		BTNode* front= QueueFront(&q);
		QueuePop(&q);
		printf("%d ", front->data);
		if (front->left)
		{
			QueuePush(&q, front->left);
		}
		if (front->right)
		{
			QueuePush(&q, front->right);
		}
	}
	QueueDestroy(&q);
}

注意:
??這里我們放入隊列的不是要打印的數(shù)據(jù),而是樹結(jié)點的指針,為什么呢?如果我們存入的是要打印的數(shù)據(jù)(整形數(shù)據(jù)),那么我們無法找到他們的子節(jié)點!所以我們每次pop出一個指針,然后push這個指針(結(jié)點)的子節(jié)點即可。圖解如下:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)

三.判斷二叉樹是否為完全二叉樹:

我們先來看看這張圖:
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
??我們會發(fā)現(xiàn),通過層序遍歷的方法,滿二叉樹在層序遍歷時的非空結(jié)點一定是連續(xù)的空結(jié)點也是連續(xù)的,所以我們只要在層序遍歷的基礎(chǔ)上把空結(jié)點存入,然后判斷空結(jié)點是否連續(xù)即可。

代碼實現(xiàn):

// 判斷二叉樹是否是完全二叉樹
bool TreeComplete(BTNode* root)
{
	Queue q;
	QueueInit(&q);
	if (root)
		QueuePush(&q, root);

	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		if (front == NULL)
		{
			break;
		}
		else
		{
			QueuePush(&q, front->left);
			QueuePush(&q, front->right);
		}
	}

	// 判斷是不是完全二叉樹
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);

		// 后面有非空,說明非空節(jié)點不是完全連續(xù)
		if (front)
		{
			QueueDestroy(&q);
			return false;
		}
	}

四.二叉樹結(jié)點數(shù)量:

??如果我們要計算結(jié)點的數(shù)量,通過上面所學(xué)的遍歷的方式當(dāng)然可以計算出結(jié)點數(shù)量。
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
這就是遍歷的方法,但是事實上我們用分治的方法更多一些:

分治和遍歷的區(qū)別:

拿學(xué)校人口統(tǒng)計作為例子,遍歷法與分治法的區(qū)別如下:

遍歷法,做法如下:
校長自己一個人帶著一個本子,跑遍全校查人數(shù)

分治法,做法如下:
校長想知道人數(shù),就找來院長統(tǒng)計每個院的人數(shù)相加,院長找來系主任統(tǒng)計每個系的人數(shù)相加……這樣校長就不用親自動手了。其實遞歸就是把任務(wù)交給打工人(嗚嗚)。
【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)
那么我們?nèi)绾螌崿F(xiàn)分治法呢?
總體思路就是 返回:左子樹數(shù)量+右子樹數(shù)量+1
代碼實現(xiàn):

int TreeSize(BTNode* root)
{
	return root == NULL ? 0 : 
	TreeSize(root->left) 
	+ TreeSize(root->right) + 1;
}

五.二叉樹的高度(深度):

在這里要求二叉樹的高度,我們也是用分治的思想:

int TreeHeight(BTNode* root)
{
	if (root == NULL)
	{
		return 0;
	}
	int leftHeight = TreeHeight(root->left);
	int rightHeight = TreeHeight(root->right);

	return leftHeight > rightHeight ? leftHeight+1 : rightHeight+1;
}

其實對于遞歸內(nèi)容,我們只需要考慮:

  • 將問題分為子問題,子問題的解決方式和總問題的解決方式的方式一樣
  • 有中止的條件

六.二叉樹第k層節(jié)點個數(shù)

現(xiàn)在我們把他分為子問題:

當(dāng)前樹的第k層個數(shù)=左子樹的第k-1層個數(shù)+右子樹的第k-1層個數(shù)
代碼如下:

int TreeKLevel(BTNode* root, int k)
{
	if (root == NULL)
	{
		return 0;
	}
	if (k == 1)
	{
		return 1;
	}
	int leftklevel = TreeKLevel(root->left, k - 1);
	int rightklevel = TreeKLevel(root->right, k - 1);

	return leftklevel + rightklevel;
}

總結(jié)

??更新不易,辛苦各位小伙伴們動動小手,??三連走一走???? ~ ~ ~ 你們真的對我很重要!最后,本文仍有許多不足之處,歡迎各位認真讀完文章的小伙伴們隨時私信交流、批評指正!

專欄訂閱:
每日一題
c語言學(xué)習(xí)
算法
智力題
初階數(shù)據(jù)結(jié)構(gòu)
更新不易,辛苦各位小伙伴們動動小手,??三連走一走???? ~ ~ ~ 你們真的對我很重要!最后,本文仍有許多不足之處,歡迎各位認真讀完文章的小伙伴們隨時私信交流、批評指正!

【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)文章來源地址http://www.zghlxwxcb.cn/news/detail-435174.html

到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)】二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹之鏈?zhǔn)浇Y(jié)構(gòu)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹之鏈?zhǔn)浇Y(jié)構(gòu)

    ?? 博客主頁 : 小羊失眠啦. ?? 系列專欄 : 《C語言》 《數(shù)據(jù)結(jié)構(gòu)》 《Linux》 《Cpolar》 ?? 感謝大家點贊??收藏?評論?? 在學(xué)習(xí)二叉樹各種各樣的操作前,我們先來回顧一下二叉樹的概念: 二叉樹是度不超過2的樹,由根結(jié)點和左右2個子樹組成,每個子樹也可以看作

    2024年02月04日
    瀏覽(26)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)

    學(xué)習(xí)鏈?zhǔn)蕉鏄湟廊N遍歷方式,便于對二叉樹的節(jié)點以及左子樹和右子樹進行操作。 前序遍歷:根、左子樹、右子樹 中序遍歷:左子樹、根、右子樹 后序遍歷:左子樹、右子樹、根 以下圖為例: 得到的結(jié)果: 前序遍歷:1 2 3 4 5 6 中序遍歷:3 2 1 5 4 6 后序遍歷:3 2

    2024年02月08日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu):二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)

    數(shù)據(jù)結(jié)構(gòu):二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)

    朋友們、伙計們,我們又見面了,本期來給大家解讀一下鏈?zhǔn)蕉鏄涞南嚓P(guān)知識點,如果看完之后對你有一定的啟發(fā),那么請留下你的三連,祝大家心想事成! 數(shù)據(jù)結(jié)構(gòu)與算法專欄 :數(shù)據(jù)結(jié)構(gòu)與算法 個? 人? 主? 頁 :stackY、 C 語 言 專 欄 :C語言:從入門到精通 目錄 前言

    2024年02月07日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)和算法】--- 二叉樹(3)--二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的實現(xiàn)(1)

    【數(shù)據(jù)結(jié)構(gòu)和算法】--- 二叉樹(3)--二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的實現(xiàn)(1)

    在學(xué)習(xí)二叉樹的基本操作前,需先要創(chuàng)建一棵二叉樹,然后才能學(xué)習(xí)其相關(guān)的基本操作。由于現(xiàn)在大家對二叉樹結(jié)構(gòu)掌握還不夠深入,且為了方便后面的介紹,此處手動快速創(chuàng)建一棵簡單的二叉樹,快速進入二叉樹操作學(xué)習(xí),等二叉樹結(jié)構(gòu)了解的差不多時,我們反過頭再來研

    2024年01月25日
    瀏覽(28)
  • 【數(shù)據(jù)結(jié)構(gòu)—二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實現(xiàn)】

    【數(shù)據(jù)結(jié)構(gòu)—二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實現(xiàn)】

    提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言 一、二叉樹的存儲結(jié)構(gòu) 二、二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的實現(xiàn) 2.1手動構(gòu)建一課樹 2.2二叉樹的遍歷 三、二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的實現(xiàn) 3.1前序遍歷(遞歸) 3.2中序遍歷(遞歸) 3.3后序遍歷(遞歸) 3.4層序遍歷(非遞

    2024年02月03日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹 鏈?zhǔn)浇Y(jié)構(gòu)的相關(guān)問題

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹 鏈?zhǔn)浇Y(jié)構(gòu)的相關(guān)問題

    ?本篇文章來詳細介紹一下二叉樹鏈?zhǔn)浇Y(jié)構(gòu)經(jīng)常使用的相關(guān)函數(shù),以及相關(guān)的的OJ題。 目錄 1.前置說明 2.二叉樹的遍歷 2.1 前序、中序以及后序遍歷 2.2 層次遍歷 3.節(jié)點個數(shù)相關(guān)函數(shù)實現(xiàn) 3.1 二叉樹節(jié)點個數(shù) 3.2 二叉樹葉子節(jié)點個數(shù) 3.3 二叉樹第k層節(jié)點個數(shù) 3.4 在二叉樹中查找值

    2024年02月14日
    瀏覽(25)
  • 【數(shù)據(jù)結(jié)構(gòu) —— 二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實現(xiàn)】

    【數(shù)據(jù)結(jié)構(gòu) —— 二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)實現(xiàn)】

    樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),它是由n(n=0)個有限結(jié)點組成一個具有層次關(guān)系的集合。 把它叫做樹是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。 1.有一個 特殊的結(jié)點,稱為根結(jié)點 ,根節(jié)點沒有前驅(qū)結(jié)點 2.除根節(jié)點外, 其余結(jié)點被分成M(M0)個互不相交

    2024年02月05日
    瀏覽(27)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的鏈?zhǔn)酱鎯Y(jié)構(gòu)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的鏈?zhǔn)酱鎯Y(jié)構(gòu)

    前序遍歷,又叫先根遍歷。 遍歷順序:根 - 左子樹 - 右子樹 代碼: 中序遍歷,又叫中根遍歷。 遍歷順序:左子樹 - 根 - 右子樹 代碼 : 后序遍歷,又叫后根遍歷。 遍歷順序:左子樹 - 右子樹 - 根 代碼 : 除了先序遍歷、中序遍歷、后序遍歷外,還可以對二叉樹進行層序遍

    2024年02月09日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)初階--二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)

    數(shù)據(jù)結(jié)構(gòu)初階--二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)

    目錄 一.二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的概念 二.二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的功能實現(xiàn) 2.1.鏈?zhǔn)蕉鏄涞亩x 2.2.鏈?zhǔn)蕉鏄涞臉?gòu)建 2.3.鏈?zhǔn)蕉鏄涞谋闅v 2.3.1.先序遍歷 2.3.2.中序遍歷 2.3.3.后序遍歷 2.3.4.層序遍歷 2.4.鏈?zhǔn)蕉鏄涞那蠖鏄涞慕Y(jié)點數(shù)量 法一:計數(shù)法 法二:分治法 2.5.鏈?zhǔn)蕉鏄涞那蠖?/p>

    2024年02月12日
    瀏覽(28)
  • 數(shù)據(jù)結(jié)構(gòu):二叉樹的鏈?zhǔn)浇Y(jié)構(gòu)的實現(xiàn)

    ? 目錄 ?1.通過前序遍歷構(gòu)建二叉樹 2.?二叉樹的銷毀 ?3.二叉樹的遍歷 4.?二叉樹的節(jié)點個位和二叉樹的葉子節(jié)點個位數(shù) 5.?二叉樹的的k層節(jié)點數(shù)和查找值為x的節(jié)點 6.?判斷二叉樹是否為完全二叉樹和求二叉樹的高度h 二叉樹的前序遍歷 二叉樹的中序遍歷 二叉樹的后序遍歷

    2024年02月12日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包