當(dāng)我們面對一個(gè)樹結(jié)構(gòu)時(shí),常常需要對其進(jìn)行遍歷以獲取其中的節(jié)點(diǎn)信息。其中一種常用的遍歷方式是層序遍歷,也稱為廣度優(yōu)先搜索(BFS)。本篇博客將詳細(xì)介紹層序遍歷的原理和實(shí)現(xiàn)方法。
1.層序遍歷的原理
層序遍歷以樹的根節(jié)點(diǎn)開始,按照從上到下、從左到右的順序逐層遍歷樹中的節(jié)點(diǎn)。這意味著在遍歷當(dāng)前層的節(jié)點(diǎn)之前,需要先遍歷完上一層的節(jié)點(diǎn)。層序遍歷基于隊(duì)列的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),它的過程可以描述如下:
1.1.創(chuàng)建一個(gè)隊(duì)列,并將根節(jié)點(diǎn)入隊(duì)。
1.2.當(dāng)隊(duì)列不為空時(shí),執(zhí)行以下步驟:
- 從隊(duì)列中取出一個(gè)節(jié)點(diǎn),訪問該節(jié)點(diǎn)。
- 將該節(jié)點(diǎn)的所有子節(jié)點(diǎn)(如果存在)依次入隊(duì)。
1.3如果隊(duì)列為空,則表示遍歷結(jié)束。
由于隊(duì)列的特性,首先入隊(duì)的節(jié)點(diǎn)會(huì)先被訪問,保證了按照層級(jí)順序遍歷節(jié)點(diǎn)。
2.層序遍歷的實(shí)現(xiàn)
1
/ \
2 3
/ \ \
4 5 6
首先,我們創(chuàng)建一個(gè)空隊(duì)列,并將根節(jié)點(diǎn)1入隊(duì)。然后按照隊(duì)列非空的條件,執(zhí)行以下步驟:
- 取出隊(duì)列中的第一個(gè)節(jié)點(diǎn)1,并訪問它。
- 將節(jié)點(diǎn)1的子節(jié)點(diǎn)2和3依次入隊(duì)。
- 隊(duì)列變?yōu)閇2, 3]。
- 取出隊(duì)列中的第一個(gè)節(jié)點(diǎn)2,并訪問它。
- 將節(jié)點(diǎn)2的子節(jié)點(diǎn)4和5依次入隊(duì)。
- 隊(duì)列變?yōu)閇3, 4, 5]。
- 取出隊(duì)列中的第一個(gè)節(jié)點(diǎn)3,并訪問它。
- 將節(jié)點(diǎn)3的子節(jié)點(diǎn)6入隊(duì)。
- 隊(duì)列變?yōu)閇4, 5, 6]。
- 取出隊(duì)列中的第一個(gè)節(jié)點(diǎn)4,并訪問它。此時(shí)該節(jié)點(diǎn)沒有子節(jié)點(diǎn)入隊(duì)。
- 隊(duì)列變?yōu)閇5, 6]。
- 取出隊(duì)列中的第一個(gè)節(jié)點(diǎn)5,并訪問它。此時(shí)該節(jié)點(diǎn)沒有子節(jié)點(diǎn)入隊(duì)。
- 隊(duì)列變?yōu)閇6]。
- 取出隊(duì)列中的第一個(gè)節(jié)點(diǎn)6,并訪問它。此時(shí)該節(jié)點(diǎn)沒有子節(jié)點(diǎn)入隊(duì)。
- 隊(duì)列為空,遍歷結(jié)束。
按照上述步驟,我們可以得到層序遍歷的結(jié)果為:[1, 2, 3, 4, 5, 6]。
void BinaryTreeLevelOrder(BTNode* root)
{
// 定義一個(gè)隊(duì)列
Queue q;
QueueInit(&q); // 初始化隊(duì)列
if (root != NULL) // 如果根節(jié)點(diǎn)不為空,將其入隊(duì)
QueuePush(&q, root);
while (!isEmptyQueue(&q)) // 當(dāng)隊(duì)列不為空時(shí)循環(huán)
{
// 取出隊(duì)頭元素
BTNode* front = QueueFront(&q);
printf("%c ", front->_data); // 輸出該節(jié)點(diǎn)的值
// 如果該節(jié)點(diǎn)有左子節(jié)點(diǎn),將其加入隊(duì)列
if (front->_left != NULL)
QueuePush(&q, front->_left);
// 如果該節(jié)點(diǎn)有右子節(jié)點(diǎn),將其加入隊(duì)列
if (front->_right != NULL)
QueuePush(&q, front->_right);
QueuePop(&q); // 出隊(duì)隊(duì)頭元素
}
printf("\n");
QueueDestroy(&q); // 銷毀隊(duì)列
}
3.層序遍歷的應(yīng)用
層序遍歷在樹的分析和處理中有廣泛的應(yīng)用。以下是一些常見的應(yīng)用場景:
- 獲取樹的層級(jí)信息:層序遍歷可以按照層級(jí)將樹的節(jié)點(diǎn)進(jìn)行分組,方便進(jìn)行樹的層級(jí)分析。
- 尋找最短路徑:在樹或圖中,層序遍歷可以用于尋找最短路徑,因?yàn)樗缺闅v完當(dāng)前層的節(jié)點(diǎn),再遍歷下一層的節(jié)點(diǎn),從而保證了尋找最短路徑的準(zhǔn)確性。
- 構(gòu)建二叉樹:層序遍歷可以根據(jù)給定的節(jié)點(diǎn)值列表,按照從上到下、從左到右的順序構(gòu)建二叉樹。
除了以上應(yīng)用,層序遍歷還可以用于樹的序列化和反序列化、樹的復(fù)制等操作。
用層序遍歷判斷是不是
層序遍歷實(shí)現(xiàn)判斷二叉樹是否為完全二叉樹
完全二叉樹:在二叉樹中,如果除了最后一層外,其它層的節(jié)點(diǎn)數(shù)都達(dá)到最大值,并且最后一層的節(jié)點(diǎn)都靠左排列,那么這棵二叉樹就是完全二叉樹。完全二叉樹在實(shí)際應(yīng)用中有著廣泛的應(yīng)用,因此判斷一棵二叉樹是否為完全二叉樹是一個(gè)常見的問題。
層序遍歷實(shí)現(xiàn)判斷完全二叉樹的思路:
層序遍歷是一種按照從上到下、從左到右的順序訪問二叉樹節(jié)點(diǎn)的方法。通過層序遍歷,我們可以逐層遍歷二叉樹的節(jié)點(diǎn),并在遍歷過程中進(jìn)行判斷,從而確定二叉樹是否為完全二叉樹。
具體實(shí)現(xiàn)步驟如下:
首先,將二叉樹的根節(jié)點(diǎn)入隊(duì)。
開始循環(huán),直到隊(duì)列為空。
在每次循環(huán)中,取出隊(duì)列的首個(gè)節(jié)點(diǎn)。
當(dāng)取出的節(jié)點(diǎn)為空時(shí),停止入隊(duì)操作。
如果在上一步中發(fā)現(xiàn)了空節(jié)點(diǎn),那么此時(shí)應(yīng)該檢查隊(duì)列中是否還有非空節(jié)點(diǎn)。如果有非空節(jié)點(diǎn),則說明該二叉樹不是完全二叉樹。
繼續(xù)循環(huán),將當(dāng)前節(jié)點(diǎn)的左右子節(jié)點(diǎn)入隊(duì)。
最后,在循環(huán)結(jié)束后,再次檢查隊(duì)列中是否還有非空節(jié)點(diǎn)。
如果有非空節(jié)點(diǎn),則說明該二叉樹不是完全二叉樹。
如果隊(duì)列中沒有非空節(jié)點(diǎn),則說明該二叉樹是完全二叉樹。文章來源:http://www.zghlxwxcb.cn/news/detail-776096.html
bool isBinaryTreeComplete(BTNode* root)
{
if (root == NULL)
{
return true;
}
BTNode* front = root;
Queue q;
QueueInit(&q);
if (front != NULL)
QueuePush(&q, front);
while (!isEmptyQueue(&q))
{
front = QueueFront(&q);
if (front == NULL)
{
// 如果取出的節(jié)點(diǎn)為空,則停止入隊(duì)操作,開始檢查隊(duì)列中是否還有非空節(jié)點(diǎn)
break;
}
// 將當(dāng)前節(jié)點(diǎn)的左右子節(jié)點(diǎn)入隊(duì)
QueuePush(&q, front->_left);
QueuePush(&q, front->_right);
QueuePop(&q);
}
while (!isEmptyQueue(&q))
{
// 循環(huán)結(jié)束后,檢查隊(duì)列中是否還有非空節(jié)點(diǎn)
front = QueueFront(&q);
QueuePop(&q);
if (front != NULL)
{
// 如果存在非空節(jié)點(diǎn),則說明該二叉樹不是完全二叉樹
QueueDestroy(&q);
return false;
}
}
QueueDestroy(&q);
return true;
}
總結(jié)
層序遍歷是一種廣度優(yōu)先搜索的遍歷方式,適用于樹結(jié)構(gòu)。通過利用隊(duì)列實(shí)現(xiàn)層序遍歷,我們可以按照從上到下、從左到右的順序逐層遍歷樹中的節(jié)點(diǎn)。層序遍歷廣泛應(yīng)用于樹的分析、最短路徑尋找、二叉樹的構(gòu)建等場景。掌握層序遍歷的原理和實(shí)現(xiàn)方法將對解決相關(guān)問題非常有幫助。文章來源地址http://www.zghlxwxcb.cn/news/detail-776096.html
到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)】二叉樹的層序遍歷的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!