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

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

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

· CSDN的uu們,大家好。這里是C語言數(shù)據(jù)結(jié)構(gòu)的第十講。
· 目標(biāo):前路坎坷,披荊斬棘,扶搖直上。
· 博客主頁:?@姬如祎
· 收錄專欄:?數(shù)據(jù)結(jié)構(gòu)與算法

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)?

?

目錄

1.?函數(shù)接口一覽

2.?函數(shù)接口的實現(xiàn)

2.1 BTNode* BuyNode(BTDataType x)?的實現(xiàn)

2.2?BTNode* CreateTree()?的實現(xiàn)

?2.3?void TreeDestroy(BTNode* root)?的實現(xiàn)

2.4?void PrevOrder(BTNode* root)?的實現(xiàn)

2.5?void InOrder(BTNode* root)?的實現(xiàn)

2.6?void PostOrder(BTNode* root)?的實現(xiàn)

2.7?void LevelOrder(BTNode* root)?的實現(xiàn)

2.7?int TreeSize(BTNode* root)?的實現(xiàn)

2.8?int TreeHeight(BTNode* root)?的實現(xiàn)

2.9?int TreeLevel(BTNode* root, int k)?的實現(xiàn)

?2.10?BTNode* TreeFind(BTNode* root, BTDataType x)?的實現(xiàn)

說明:因為是數(shù)據(jù)結(jié)構(gòu)初階,所以二叉樹的創(chuàng)建方式我們選擇直接開辟節(jié)點,然后手動鏈接。二叉樹真正的創(chuàng)建方式在高階的數(shù)據(jù)結(jié)構(gòu)再來實現(xiàn)。因為我們實現(xiàn)的二叉樹只是普通的二叉樹,增刪改查沒有什么意義。像哪些特殊的二叉樹,紅黑樹等的增刪改查才有意義。這里這是通過常見接口的講解來理解二叉樹遞歸的性質(zhì)。

1.?函數(shù)接口一覽


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

//開辟一個節(jié)點
BTNode* BuyNode(BTDataType x);

//二叉樹的手動創(chuàng)建
BTNode* CreateTree();

//二叉樹的銷毀
void TreeDestroy(BTNode* root);

//二叉樹的前序遍歷
void PrevOrder(BTNode* root);

//二叉樹的中序遍歷
void InOrder(BTNode* root);

//二叉樹的后序遍歷
void PostOrder(BTNode* root);

//二叉樹的層序遍歷
void LevelOrder(BTNode* root);

//二叉樹的節(jié)點個數(shù)
int TreeSize(BTNode* root);

//二叉樹的深度
int TreeHeight(BTNode* root);

//二叉樹第K層的節(jié)點個數(shù)
int TreeLevel(BTNode* root, int k);

//二叉樹查找節(jié)點值為X的節(jié)點
BTNode* TreeFind(BTNode* root, BTDataType x);

2.?函數(shù)接口的實現(xiàn)

2.1 BTNode* BuyNode(BTDataType x)?的實現(xiàn)

這個函數(shù)和鏈表中申請節(jié)點的作用相同,均是為了方便構(gòu)建數(shù)據(jù)結(jié)構(gòu)。在向堆區(qū)申請空間后需要將該節(jié)點的左右孩子的指針初始化為NULL。

//開辟一個節(jié)點
BTNode* BuyNode(BTDataType x)
{
	//堆區(qū)開辟節(jié)點
	BTNode* newNode = (BTNode*)malloc(sizeof(BTNode));
	if (newNode == NULL)
	{
		perror("BuyNode::malloc");
		exit(-1);
	}
	else
	{
		//節(jié)點初始化
		newNode->data = x;
		newNode->left = NULL;
		newNode->right = NULL;
		return newNode;
	}
}

2.2?BTNode* CreateTree()?的實現(xiàn)

文章開頭我們就說明了,我們學(xué)的是最普通的二叉樹,因此為了?方便起見,我們選擇手動進(jìn)行二叉樹的構(gòu)建。方法很簡單,你只需要開辟你所需要構(gòu)建的樹的節(jié)點個數(shù),然后將指針鏈接起來即可。這里我們構(gòu)建一顆如下圖所示的完全二叉樹。

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

//二叉樹的手動創(chuàng)建
BTNode* CreateTree()
{
	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);
	BTNode* node8 = BuyNode(8);
	BTNode* node9 = BuyNode(9);

	node1->left = node2;
	node1->right = node3;

	node2->left = node4;
	node2->right = node5;

	node3->left = node6;
	node3->right = node7;

	node4->left = node8;
	node4->right = node9;

	return node1;
}

?2.3?void TreeDestroy(BTNode* root)?的實現(xiàn)

二叉樹的初階內(nèi)容不涉及數(shù)據(jù)的增刪改查,我們學(xué)習(xí)的主要內(nèi)容就是理解二叉樹的遞歸特性。為將來學(xué)習(xí)特殊的二叉樹打好基礎(chǔ)。因此下面開始的函數(shù)均選擇使用遞歸來實現(xiàn)。

這個函數(shù)的實現(xiàn)比較簡單,但是釋放節(jié)點的順序還是有講究的,如下圖,我們要對這三個節(jié)點進(jìn)行釋放,我們有三個選擇:先釋放4;先釋放8;先釋放9。顯然我們不會選擇先釋放4,因為如果你想要先釋放4,那么你還需要用變量先保存4的左右孩子,這樣就顯得比較麻煩啦。至于是先釋放8.還是先釋放9,就沒有優(yōu)劣之差啦。

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

?在釋放樹的節(jié)點時,顯然只能從葉子節(jié)點開始釋放,這恰恰符合了遞歸遞去歸來的特性,因此我們選擇使用遞歸來實現(xiàn)。通過遞歸,先到達(dá)葉子節(jié)點,我們不妨先釋放左孩子,再釋放右孩子,如果左右孩子不為空,我們就釋放他們,然后再釋放左右孩子的雙親節(jié)點,釋放完成后逐步向上返回,直到將根結(jié)點釋放。下圖展示了8這個節(jié)點的銷毀過程,請結(jié)合代碼進(jìn)行理解。

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

//二叉樹的銷毀
void TreeDestroy(BTNode* root)
{
	if (root == NULL)
		return;
	TreeDestroy(root->left);
	TreeDestroy(root->right);

	free(root);
	root = NULL;
}

2.4?void PrevOrder(BTNode* root)?的實現(xiàn)

?前序遍歷,就是在遍歷二叉樹時先訪問根結(jié)點,在訪問左子樹,最后訪問右子樹。二叉樹的遞歸邏輯都是相似的,可以結(jié)合下面的這張圖來理解前序遍歷。

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

?在進(jìn)行前序遍歷的時候,他的本質(zhì)是會去訪問葉子節(jié)點左右孩子的那兩個NULL指針的,因此在訪問到NULL時,我們可以將NULL打印出來,這樣能更加深刻的理解前序遍歷的本質(zhì)。

//二叉樹的前序遍歷
void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%d ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);

}

2.5?void InOrder(BTNode* root)?的實現(xiàn)

中序遍歷就是在遍歷二叉樹的時候先訪問左子樹,再訪問根結(jié)點,最后訪問右子樹。思路就是二叉樹的遞歸思路,代碼只需要將前序遍歷代碼的順序交換一下即可。

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

}

2.6?void PostOrder(BTNode* root)?的實現(xiàn)

后續(xù)遍歷就是指在遍歷二叉樹時先訪問左子樹,再訪問右子樹,最后訪問根結(jié)點。

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

}

2.7?void LevelOrder(BTNode* root)?的實現(xiàn)

層序遍歷就是將一棵樹按照每一層每一層的方式進(jìn)行遍歷,下圖中的二叉樹的層序遍歷結(jié)果就是:1 2 3 4 5 6 7 8 9

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

這該怎么做呢?其實很簡單,我們只需要維護一個隊列,?一開始呢,先將根結(jié)點入隊列。然后進(jìn)入一個循環(huán),循環(huán)繼續(xù)的條件就是隊列不為空,然后逐步取出隊頭的元素,如果隊頭元素的左右孩子有不為空的,就將其入隊列,依次類推,節(jié)點從隊列中出來的順序就是層序遍歷的結(jié)果。

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

至于隊列的選擇,我們選擇使用數(shù)組模擬實現(xiàn)隊列,因為C語言嘛,不像其他語言那么方便。

關(guān)于數(shù)組模擬實現(xiàn)隊列,請參考:數(shù)據(jù)模擬實現(xiàn)隊列

2.7?int TreeSize(BTNode* root)?的實現(xiàn)

你可能會想,我們維護一個變量Size,然后將二叉樹遍歷一遍,每遍歷到一個節(jié)點就將Size++,這樣就能求出二叉樹的節(jié)點個數(shù)了。這沒問題,很好,只不過這種方法有一點值得注意,如果你不使用全局或者靜態(tài)變量,而是將Size作為參數(shù)傳遞給TreeSize函數(shù),那么,一定記得傳指針哦!具體原因想必大家都懂啦!俺們都是C語言學(xué)完的人了!但是這里不推薦使用全局和靜態(tài)的變量。如果你要對多棵樹調(diào)用該方法,那么你還得重新初始化這個全局變量,比較麻煩。

這里我們就不對上面的這種方法做實現(xiàn)啦!這里還有一種方法:整個二叉樹節(jié)點的個數(shù)就等于左子樹節(jié)點的個數(shù) +?右子樹節(jié)點的個數(shù) + 1 (這個1就是根節(jié)點啦)。這便是分治思想。將大的問題拆解成小的問題(說實話還有一點動態(tài)規(guī)劃的味道)。

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

2.8?int TreeHeight(BTNode* root)?的實現(xiàn)

我們理解了求解TreeSize的思路,TreeHeight就是信手拈來的事情。同樣地,我們利用分治的思想:樹的深度 =?左右子樹中深度較大的那一個 + 1,是不是很簡單嘞。

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

2.9?int TreeLevel(BTNode* root, int k)?的實現(xiàn)

求解二叉樹第K層的節(jié)點個數(shù),怎么用分治的思想解決呢?上圖解

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)

?這下是不是有思路了呢?當(dāng)我們遞歸到所求節(jié)點總數(shù)的那一層時,對于K = 1,而這個時候呢,我們就不要向下遞歸啦!這層有節(jié)點的話,遞歸到此層的每一個節(jié)點返回1就行啦!

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

?2.10?BTNode* TreeFind(BTNode* root, BTDataType x)?的實現(xiàn)

咦,不是說普通的二叉樹不學(xué)增刪改查嗎!哈哈,勉強看一個吧,這里有一個地方值得注意,TreeFind函數(shù)的返回值不是bool值而是查找到的節(jié)點,如果有修改的需要,我們就能夠在查找的同時對節(jié)點的值進(jìn)行修改啦!是不是很方便。

怎么實現(xiàn)這個函數(shù)呢?其實很簡單,我們先對每一層遞歸的根結(jié)點進(jìn)行判斷,如果這個時候根結(jié)點的data就等于x那么直接返回結(jié)果就行。如果根結(jié)點的data值不等于x呢?

我們就在根結(jié)點的左子樹中去找,也就是往左子樹遞歸、如果在左子樹找的結(jié)果不為空,說明在左子樹中找到了data值為x的節(jié)點,返回該節(jié)點即可!

如果左子樹沒找到,就在右子樹中去找,也就是往右子樹去遞歸。如果在右子樹找的結(jié)果不為空,說明在右子樹中找到了data值為x的節(jié)點,返回該節(jié)點即可!如果在右子樹中沒有找到嘞,說明左右子樹都沒找到,返回NULL即可。

BTNode* TreeFind(BTNode* root, BTDataType x)
{
	if (root == NULL)
	{
		return NULL;
	}
	if (root->data == x)
		return root;
	BTNode* left = TreeFind(root->left, x);
	if (left)
		return left;

	BTNode* right = TreeFind(root->right, x);
	if (right)
		return right;
	
	return NULL;
}

C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)文章來源地址http://www.zghlxwxcb.cn/news/detail-402740.html

到了這里,關(guān)于C語言數(shù)據(jù)結(jié)構(gòu)初階(10)----二叉樹的實現(xiàn)的文章就介紹完了。如果您還想了解更多內(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ìn)行投訴反饋,一經(jīng)查實,立即刪除!

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

相關(guān)文章

  • 【初階數(shù)據(jù)結(jié)構(gòu)】樹結(jié)構(gòu)與二叉樹的基礎(chǔ)概念

    【初階數(shù)據(jù)結(jié)構(gòu)】樹結(jié)構(gòu)與二叉樹的基礎(chǔ)概念

    君兮_的個人主頁 勤時當(dāng)勉勵 歲月不待人 C/C++ 游戲開發(fā) Hello,米娜桑們,這里是君兮_,今天帶來數(shù)據(jù)結(jié)構(gòu)里的重點內(nèi)容也是在筆試,面試中的常見考點——樹與二叉樹,其中二叉樹又分為很多種,我們先來講講基礎(chǔ)的內(nèi)容帶大家一步步入門 在介紹二叉樹之前,我們得先知道什

    2024年02月08日
    瀏覽(29)
  • 【初階數(shù)據(jù)結(jié)構(gòu)】二叉樹的幾種遍歷詳解

    【初階數(shù)據(jù)結(jié)構(gòu)】二叉樹的幾種遍歷詳解

    君兮_的個人主頁 勤時當(dāng)勉勵 歲月不待人 C/C++ 游戲開發(fā) Hello,米娜桑們,這里是君兮_,有了我們之前介紹的樹結(jié)構(gòu)與二叉樹的基礎(chǔ)概念,今天我們來講講對二叉樹的基本使用——遍歷 我們自己先簡單鏈?zhǔn)竭B接幾個結(jié)點來創(chuàng)建一個二叉樹方便我們之后對遍歷的講解 好了,有了

    2024年02月08日
    瀏覽(27)
  • 數(shù)據(jù)結(jié)構(gòu)初階之二叉樹的詳細(xì)解析

    數(shù)據(jù)結(jié)構(gòu)初階之二叉樹的詳細(xì)解析

    個人主頁:點我進(jìn)入主頁 專欄分類:C語言初階? ? ??C語言程序設(shè)計————KTV? ? ? ?C語言小游戲? ? ?C語言進(jìn)階 C語言刷題? ? ? ?數(shù)據(jù)結(jié)構(gòu)初階? ??Linux 歡迎大家點贊,評論,收藏。 一起努力,共赴大廠。 目錄 1.前言? 2.二叉樹各個功能代碼實現(xiàn) 2.1二叉樹結(jié)構(gòu)體 2.2二叉

    2024年02月05日
    瀏覽(26)
  • 初階數(shù)據(jù)結(jié)構(gòu)之---二叉樹鏈?zhǔn)浇Y(jié)構(gòu)(二叉樹的構(gòu)建,二叉樹的前序,中序,后序和層序遍歷,計算二叉樹結(jié)點個數(shù),第k層結(jié)點個數(shù),葉子結(jié)點個數(shù),判斷是否為完全二叉樹)

    初階數(shù)據(jù)結(jié)構(gòu)之---二叉樹鏈?zhǔn)浇Y(jié)構(gòu)(二叉樹的構(gòu)建,二叉樹的前序,中序,后序和層序遍歷,計算二叉樹結(jié)點個數(shù),第k層結(jié)點個數(shù),葉子結(jié)點個數(shù),判斷是否為完全二叉樹)

    本篇博客是初階數(shù)據(jù)結(jié)構(gòu)樹的收尾,將會講掉 基本二叉樹鏈?zhǔn)浇Y(jié)構(gòu)的具體內(nèi)容和實現(xiàn),包括二叉樹的構(gòu)建,前序遍歷,中序遍歷,后序遍歷和層序遍歷,計算二叉樹結(jié)點個數(shù),第k層結(jié)點個數(shù),二叉樹葉子結(jié)點個數(shù),以及判斷一個二叉樹是否為完全二叉樹 。話不多說,開始我

    2024年03月24日
    瀏覽(28)
  • 二叉樹的實現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

    二叉樹的實現(xiàn)(C語言數(shù)據(jù)結(jié)構(gòu))

    目錄 一、以下是我們需要實現(xiàn)的功能 二、以下是我們具體功能的實現(xiàn) 1.創(chuàng)建新的結(jié)點 2.通過數(shù)組生成二叉樹 ?3.先序遍歷 4.中序遍歷 5.后序遍歷? ?6.層序遍歷 7.計算二叉樹的結(jié)點個數(shù) 8.查找指定值為x的結(jié)點 9.查找第K層的結(jié)點個數(shù) 10.統(tǒng)計二叉樹葉子結(jié)點的個數(shù) 11.判斷是否為

    2024年02月04日
    瀏覽(18)
  • 【C語言 數(shù)據(jù)結(jié)構(gòu)】二叉樹的遍歷

    【C語言 數(shù)據(jù)結(jié)構(gòu)】二叉樹的遍歷

    所謂先序遍歷二叉樹,指的是從根結(jié)點出發(fā),按照以下步驟訪問二叉樹的每個結(jié)點: 訪問當(dāng)前結(jié)點; 進(jìn)入當(dāng)前結(jié)點的左子樹,以同樣的步驟遍歷左子樹中的結(jié)點; 遍歷完當(dāng)前結(jié)點的左子樹后,再進(jìn)入它的右子樹,以同樣的步驟遍歷右子樹中的結(jié)點; 先序遍歷這棵二叉樹的過

    2024年02月04日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)初階之基礎(chǔ)二叉樹(C語言實現(xiàn))

    數(shù)據(jù)結(jié)構(gòu)初階之基礎(chǔ)二叉樹(C語言實現(xiàn))

    ?? 博客主頁: 小鎮(zhèn)敲碼人 ?? 熱門專欄:數(shù)據(jù)結(jié)構(gòu)與算法 ?? 歡迎關(guān)注:??點贊 ????留言 ??收藏 ?? 任爾江湖滿血骨,我自踏雪尋梅香。 萬千浮云遮碧月,獨傲天下百堅強。 男兒應(yīng)有龍騰志,蓋世一意轉(zhuǎn)洪荒。 莫使此生無痕度,終歸人間一捧黃。?????? ?? 什么

    2024年03月19日
    瀏覽(24)
  • 【數(shù)據(jù)結(jié)構(gòu)】二叉樹的前中后序遍歷(C語言)

    【數(shù)據(jù)結(jié)構(gòu)】二叉樹的前中后序遍歷(C語言)

    [二叉樹] 顧名思義就是有 兩個分支節(jié)點的樹,不僅如此,除了葉子外的所有節(jié)點都具有兩個分支節(jié)點; 由于結(jié)構(gòu)像一棵倒立的樹,顧名思義為二叉樹 ; 如下圖所示,該圖即為一棵 野生的二叉樹 ; 既然二叉樹為樹,固然有著和樹一樣的部分( 葉子、根、分支… ) 這些也成為

    2024年02月17日
    瀏覽(26)
  • 二叉樹的基本操作-C語言實現(xiàn)-數(shù)據(jù)結(jié)構(gòu)作業(yè)

    二叉樹的基本操作-C語言實現(xiàn)-數(shù)據(jù)結(jié)構(gòu)作業(yè)

    目錄 ?(1)二叉樹的創(chuàng)建; (2)二叉樹的先序、中序和后序遍歷輸出; (3)輸出二叉樹的葉子節(jié)點和度為2的節(jié)點的數(shù)量; (4)輸出二叉樹的深度; (5)將二叉樹所有節(jié)點的左右子樹互換(左子樹變右子樹,右子樹變左子樹); (6)參考書上,二叉樹按層次輸出(一行輸出一層); (7)刪除二

    2024年02月04日
    瀏覽(21)
  • 數(shù)據(jù)結(jié)構(gòu)實驗報告,二叉樹的基本操作(C語言)

    數(shù)據(jù)結(jié)構(gòu)實驗報告,二叉樹的基本操作(C語言)

    作者:命運之光 專欄:數(shù)據(jù)結(jié)構(gòu) 實驗六 二叉樹的基本操作 實驗環(huán)境:Visual C++或Dev C++ 實驗?zāi)康模?1、掌握二叉樹創(chuàng)建; 2、掌握二叉樹的遍歷及常用算法。 實驗內(nèi)容: 通過完全前序序列創(chuàng)建一棵二叉樹,完成如下功能: 1)輸出二叉樹的前序遍歷序列; 2)輸出二叉樹的中序遍

    2024年02月09日
    瀏覽(24)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包