【数据结构-树】2.二叉树遍历与线索二叉树(图解+代码)
一、二叉樹的定義及其主要特征
1.1 二叉樹的概念
二叉樹是另一種樹形結(jié)構(gòu),其特點(diǎn)是每個(gè)結(jié)點(diǎn)最多含兩棵子樹(也就是說,二叉樹的度≤2)。
二叉樹是一種有序樹,若將其左、右子樹顛倒,則成為另一顆不同的二叉樹。
二叉樹可以為空
1.2 二叉樹和度為2的有序樹
在這里要區(qū)分一個(gè)概念,也就是二叉樹和度為2的有序樹之間的區(qū)別。
1.3 幾種特殊的二叉樹
1. 滿二叉樹
一顆高度為h,且含有2h?12^h-12h?1個(gè)結(jié)點(diǎn)的二叉樹就是一顆滿二叉樹。
滿二叉樹的特點(diǎn):
2. 完全二叉樹
設(shè)有一個(gè)高度為h,有n個(gè)結(jié)點(diǎn)的二叉樹,當(dāng)且僅當(dāng)每個(gè)結(jié)點(diǎn)都與高度為h的滿二叉樹中編號(hào)1~n的結(jié)點(diǎn)一一對(duì)應(yīng)時(shí),就是一顆完全二叉樹
完全二叉樹的特點(diǎn):
3. 二叉排序樹
一棵空樹,或者是具有下列性質(zhì)的二叉樹:
4. 平衡二叉樹
樹上任一結(jié)點(diǎn)的左子樹和右子樹的深度不大于1
二叉樹的存儲(chǔ)結(jié)構(gòu)
順序存儲(chǔ)結(jié)構(gòu):用一組地址連續(xù)的存儲(chǔ)單元存儲(chǔ)。滿二叉樹和完全二叉樹使用較為合適。其他樹使用數(shù)組中可能有空結(jié)點(diǎn)
鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu):用指針指向根結(jié)點(diǎn)的孩子結(jié)點(diǎn)。二叉樹的存儲(chǔ)結(jié)構(gòu)一般有三個(gè)域:1. 數(shù)據(jù)域data,2. 左指針域left,3. 右指針域right
struct BinaryTreeNode{int data;BinaryTreeNode *left;BinaryTreeNode *right; };二叉樹的遍歷
示例樹如下:
1. 先序遍歷
若二叉樹為空,則什么都不做,否則
以先序遍歷方式遍歷示例樹,結(jié)果為:ABDECFG
void preorder(TreeNode *node, int layer) {if(!node) {return;}do something;preorder(node->left, layer + 1);preorder(node->right, layer + 1); }2. 中序遍歷
若二叉樹為空,則什么都不做,否則
以中序遍歷方式遍歷示例樹,結(jié)果為:DBEAFCG
void inorder(TreeNode *node, int layer) {if(!node) {return;}preorder(node->left, layer + 1);do something;preorder(node->right, layer + 1); }3. 后序遍歷
若二叉樹為空,則什么都不做,否則
以后序遍歷方式遍歷示例樹,結(jié)果為:DEBFCGA
void postorder(TreeNode *node, int layer) {if(!node) {return;}preorder(node->left, layer + 1);preorder(node->right, layer + 1);do something; }4. 層次遍歷
要進(jìn)行層次遍歷,需要借助一個(gè)隊(duì)列。先將二叉樹根結(jié)點(diǎn)入隊(duì),然后出隊(duì),若它有左子樹,則將左子樹根結(jié)點(diǎn)入隊(duì);若它有右子樹,則將右子樹根結(jié)點(diǎn)入隊(duì)。然后出隊(duì),對(duì)出隊(duì)結(jié)點(diǎn)訪問,如此反復(fù),直到隊(duì)列為空
以層序遍歷方式遍歷示例樹,結(jié)果為:ABCDEFG
void Sequence(TreeNode *node) {queue<TreeNode *> q;q.push_back(node);while(!q.empty()) {TreeNode *root = node;q.pop();} }反過來討論,給你一個(gè)中序序列和一個(gè)其他遍歷序列能否構(gòu)造出唯一一顆二叉樹。答案是可以的。
如,先序序列:ABDECFG,中序序列:DBEAFCG
線索二叉樹
在二叉樹的結(jié)點(diǎn)上加上線索的二叉樹稱為線索二叉樹,對(duì)二叉樹以某種遍歷方式(如先序、中序、后序或?qū)哟蔚?#xff09;進(jìn)行遍歷,使其變?yōu)榫€索二叉樹的過程稱為對(duì)二叉樹進(jìn)行線索化。
線索鏈表解決了無法直接找到該結(jié)點(diǎn)在某種遍歷序列中的前驅(qū)和后繼結(jié)點(diǎn)的問題,解決了二叉鏈表找左、右孩子困難的問題。
在二叉樹線索化時(shí),通常規(guī)定:若無左子樹,令lchild指向其前驅(qū)結(jié)點(diǎn);若無右子樹,令rchild指向其后繼結(jié)點(diǎn)
線索二叉樹的存儲(chǔ)結(jié)構(gòu):
struct ThreadBinaryTreeNode{int data;ThreadBinaryTreeNode *lchild; // 指向左孩子結(jié)點(diǎn)ThreadBinaryTreeNode *rchild; // 指向右孩子結(jié)點(diǎn)int ltag; // 0表示結(jié)點(diǎn)的左孩子,1 表示結(jié)點(diǎn)的前驅(qū)int rtag; // 0表示結(jié)點(diǎn)的右孩子,1 表示結(jié)點(diǎn)的后繼 };樹轉(zhuǎn)化為二叉樹
樹轉(zhuǎn)換為二叉樹的規(guī)則:每個(gè)結(jié)點(diǎn)左指針指向他的第一個(gè)孩子結(jié)點(diǎn),右指針指向它在樹中的相鄰兄弟結(jié)點(diǎn),可以表示為 “左孩子右兄弟”。
將樹轉(zhuǎn)換成二叉樹的步驟是:
二叉樹轉(zhuǎn)換為樹
二叉樹轉(zhuǎn)換為樹是樹轉(zhuǎn)換為二叉樹的逆過程,其步驟是:
森林轉(zhuǎn)化為二叉樹
森林是由若干棵樹組成,可以將森林中的每棵樹的根結(jié)點(diǎn)看作是兄弟,由于每棵樹都可以轉(zhuǎn)換為二叉樹,所以森林也可以轉(zhuǎn)換為二叉樹。
將森林轉(zhuǎn)換為二叉樹的步驟是:
二叉樹轉(zhuǎn)化為森林
二叉樹轉(zhuǎn)換為森林比較簡(jiǎn)單,其步驟如下:
二叉樹連接起來后得到的二叉樹就是由森林轉(zhuǎn)換得到的二叉樹。
總結(jié)
以上是生活随笔為你收集整理的【数据结构-树】2.二叉树遍历与线索二叉树(图解+代码)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据结构-树】1.树与森林(树的遍历、
- 下一篇: 【数据结构-树】3.详解二叉排序树(理论