数据结构——二叉树的层次遍历
問題描述:
給你一個二叉樹,請你返回其按 層序遍歷 得到的節(jié)點值。 (即逐層地,從左到右訪問所有節(jié)點)。
示例:
二叉樹:[3,9,20,null,null,15,7]
返回其層次遍歷結(jié)果:
[
[3],
[9,20],
[15,7]
]
通過
來源:力扣(LeetCode)
二叉樹的層序遍歷
目錄
1.非遞歸用循環(huán)隊列
2.遞歸實現(xiàn)層次遍歷
在棧與隊列:匹配問題都是棧的強項中提到,「遞歸的實現(xiàn)就是:每一次遞歸調(diào)用都會把函數(shù)的局部變量、參數(shù)值和返回地址等壓入調(diào)用棧中」,然后遞歸返回的時候,從棧頂彈出上一次遞歸的各項參數(shù),所以這就是遞歸為什么可以返回上一層位置的原因。
知識前提:循環(huán)隊列,二叉樹的基本運算
非遞歸用循環(huán)隊列
//思路
進(jìn)行層次遍歷時構(gòu)建一個輔助隊列,先將二叉樹根節(jié)點入隊,然后出隊,訪問出隊結(jié)點,若它有左子樹,將左子樹根節(jié)點入隊,然后出隊,訪問出隊結(jié)點…,右子樹也同樣如此,循環(huán)往復(fù)直到隊列為空
1.構(gòu)建好輔助隊列Q和二叉樹T;
2.首先將二叉樹的T(根節(jié)點)入隊列;
3.進(jìn)入while循環(huán),退出條件 :隊列為空;
4.循環(huán)內(nèi)部:首先將隊列中的隊首元素出棧,并且輸出他的值;
若隊首元素(剛剛出隊的元素)有左子樹,將其左子樹入隊
若隊首元素(剛剛出隊的元素)有右子樹,將其右子樹入隊
詳細(xì)代碼(可直接運行)
補充:如何讓輸出為一層一行
方法說起來很簡單,只要仔細(xì)想,應(yīng)該都能想出這種方法來。
定義兩個變量curLevelCount和nextLevelCount來分別保存當(dāng)前層和下一層的結(jié)點數(shù)。
顯然,curLevelCount的初始值為1,因為只有一個根結(jié)點,而nextLevelCount由于未知,故置為0.
思路:
1.輸出一行一行的與之前輸出為一行的代碼大體相似
2.構(gòu)建好輔助隊列Q和二叉樹T;
3.再定義兩個變量:curLevelCount用于記錄當(dāng)前層次結(jié)點個數(shù),nextLevelCount用于記錄當(dāng)前層次的下一層結(jié)點的個數(shù)
4.將二叉樹的根節(jié)點入棧,同時curLevelCount=1,nextLevelCount=0;
5.進(jìn)入while循環(huán),退出條件 :隊列為空;
6.循環(huán)內(nèi)部:首先將隊列中的隊首元素出棧,并且輸出他的值;(與此同時,將curLevelCount–);
若隊首元素(剛剛出隊的元素)有左子樹,將其左子樹入隊.(與此同時,將nextLevelCount++);
若隊首元素(剛剛出隊的元素)有右子樹,將其右子樹入隊.(與此同時,將nextLevelCount++);
若curLevelCount減到零:輸出一個換行符,將nextLevelCount賦值給curLevelCount,
nextLevelCount=0;
代碼:非遞歸用循環(huán)隊列
遞歸實現(xiàn)層次遍歷
思路:
1.先利用BiTree_height1(BiTree T)求二叉樹高度算法,求得高度
2.levelOrder( BiTree T)層次遍歷遞歸算法(這個函數(shù)僅一個for循環(huán)),用for()將二叉樹一層一層的輸出,每一層輸出完,再輸出一個換行符。
3.printNodeAtLevel(BiTree T,int level)(真正的遞歸遍歷輸出函數(shù))。
若level==0,輸入此時的T->data;
代碼:遞歸實現(xiàn)(全部代碼)
#include<stdio.h> #include<bits/stdc++.h> typedef char TElemType; typedef int status; typedef struct BiNode {TElemType data;struct BiNode *lchild;struct BiNode *rchild; }BiNode,*BiTree; void CreateBiTree(BiTree &T)//二叉樹的先序創(chuàng)建 {TElemType ch;scanf("%c",&ch);if(ch=='#')T=NULL;else {T=(BiNode*)malloc(sizeof(BiNode));if(!T)exit(-1);T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);} }void DestroyBiTree(BiTree &T)//二叉樹的銷毀算法 {if(T==NULL)exit(-1);else{DestroyBiTree(T->lchild);DestroyBiTree(T->rchild);free(T);} }int preorderTraverse(BiTree T)//二叉樹的先序遞歸遍歷算法 {if(T==NULL)return 0;else {printf("%c ",T->data);preorderTraverse(T->lchild);preorderTraverse(T->rchild);}} int InorderTraverse(BiTree T)//二叉樹的中序遞歸遍歷算法 {if(T==NULL)return 0;else {InorderTraverse(T->lchild);printf("%c ",T->data);InorderTraverse(T->rchild);}}int PostorderTraverse(BiTree T)//二叉樹的后序遞歸遍歷算法 {if(T==NULL)return 0;else {PostorderTraverse(T->lchild);PostorderTraverse(T->rchild);printf("%c ",T->data);}}int BiTree_height1(BiTree T)//求樹的深度算法1 {if(T==NULL)return 0;else{if(BiTree_height1(T->lchild)>BiTree_height1(T->rchild))return 1+BiTree_height1(T->lchild);elsereturn 1+BiTree_height1(T->rchild);}} void printNodeAtLevel(BiTree T,int level) { if(T==NULL||level<0) return; if(level==0) { printf("%c ",T->data);return; } // 左子樹的 level - 1 級 printNodeAtLevel(T->lchild,level-1); // 右子樹的 level - 1 級 printNodeAtLevel(T->rchild,level-1); }void levelOrder(const BiTree T) {if(T==NULL)return;int totalLevel = BiTree_height1(T);for(int i = 0; i< totalLevel; i++){printNodeAtLevel(T, i);printf("\n");//打印完一層,換行} } int main() {BiTree T;printf("創(chuàng)建樹輸入樹T的先序序列(其中使用#代表空節(jié)點)\n");CreateBiTree(T);printf("先序遍歷算法");preorderTraverse(T);printf("\n中序遍歷算法");InorderTraverse(T);printf("\n后序遍歷算法");PostorderTraverse(T);printf("\n二叉樹層次遍歷算法\n");levelOrder(T);}總結(jié)
以上是生活随笔為你收集整理的数据结构——二叉树的层次遍历的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构——二叉树的最小深度算法
- 下一篇: 改装方向盘与安全气囊不匹配,特斯拉汽车(