二叉樹的應用—二叉樹遍歷的應用

2021-02-21 C語言三人行+

在各類的遍歷算法中,訪問結點的數據域信息,即操作Visite(bt->data)具有更一般的意義,需根據具體問題,對bt 數據進行不同的操作。下面介紹幾個遍歷操作的典型應用。

1.查找數據元素


Search(bt,x)在bt 為二叉樹的根結點指針的二叉樹中查找數據元素x。查找成功時返回該結點的指針;查找失敗時返回空指針。

算法實現如下,注意遍歷算法中的Visite(bt->data)等同於其中的一組操作步驟。
BiTree Search(BiTree bt,elemtype x)
{/*在bt 為根結點指針的二叉樹中查找數據元素x*/
BiTree p;
if (bt->data==x) return bt; /*查找成功返回*/
if (bt->lchild!=NULL) return(Search(bt->lchild,x));
/*在bt->lchild 為根結點指針的二叉樹中查找數據元素x*/
if (bt->rchild!=NULL) return(Search(bt->rchild,x));
/*在bt->rchild 為根結點指針的二叉樹中查找數據元素x*/
return NULL; /*查找失敗返回*/
}
算法6.21

2.統計出給定二叉樹中葉子結點的數目


(1)順序存儲結構的實現
int CountLeaf1(SqBiTree bt,int k)
{/*一維數組bt[2k-1]為二叉樹存儲結構,k 為二叉樹深度,函數值為葉子數。*/
total=0;
for(i=1;i<=2k-1;i++)
{ if (bt[i]!=0)
{ if ((bt[2i]==0 && bt[2i+1]==0) || (i>(2k-1)/2))
total++;
}
}
return(total);
}
算法6.22

(2)二叉鍊表存儲結構的實現
int CountLeaf2(BiTree bt)
{/*開始時,bt 為根結點所在鏈結點的指針,返回值為bt 的葉子數*/
if (bt==NULL) return(0);
if (bt->lchild==NULL && bt->rchild==NULL) return(1);
return(CountLeaf2(bt->lchild)+CountLeaf2(bt->rchild));
}
算法6.23

3.創建二叉樹二叉鍊表存儲,並顯示。


設創建時,按二叉樹帶空指針的先序次序輸入結點值,結點值類型為字符型。輸出按中序輸出。

CreateBinTree(BinTree *bt)是以二叉鍊表為存儲結構建立一棵二叉樹T 的存儲,bt為指向二叉樹T 根結點指針的指針。設建立時的輸入序列為:AB0D00CE00F00。建立如圖6.3 (b)所示的二叉樹存儲。

InOrderOut(bt)為按中序輸出二叉樹bt 的結點。算法實現如下,注意在創建算法中,遍歷算法中的Visite(bt->data)被讀入結點、申請空間存儲的操作所代替;在輸出算法中,遍歷算法中的Visite(bt->data)被c 語言中的格式輸出語句所代替。

void CreateBinTree(BinTree *T)
{/*以加入結點的先序序列輸入,構造二叉鍊表*/
char ch;
scanf("\n%c",&ch);
if (ch=='0') *T=NULL; /*讀入0 時,將相應結點置空*/
else {*T=(BinTNode*)malloc(sizeof(BinTNode)); /*生成結點空間*/
(*T)->data=ch;
CreateBinTree(&(*T)->lchild); /*構造二叉樹的左子樹*/
CreateBinTree(&(*T)->rchild); /*構造二叉樹的右子樹*/
}
}
void InOrderOut(BinTree T)
{/*中序遍歷輸出二叉樹T 的結點值*/
if (T)
{ InOrderOut(T->lchild); /*中序遍歷二叉樹的左子樹*/
printf("%3c",T->data); /*訪問結點的數據*/
InOrderOut(T->rchild); /*中序遍歷二叉樹的右子樹*/
}
}
main()
{BiTree bt;
CreateBinTree(&bt);
InOrderOut(bt);
}
算法6.24

4.表達式運算


我們可以把任意一個算數表達式用一棵二叉樹表示,圖6.15 所示為表達式3x2+x-1/x+5的二叉樹表示。在表達式二叉樹中,每個葉結點都是操作數,每個非葉結點都是運算符。對於一個非葉子結點,它的左、右子樹分別是它的兩個操作數。


對該二叉樹分別進行先序、中序和後序遍歷,可以得到表達式的三種不同表示形式。

前綴表達式+-+*3*xxx/1x5
中綴表達式3*x*x+x-1/x+5
後綴表達式3xx**x+1x/-5+


中綴表達式是經常使用的算術表達式,前綴表達式和後綴表達式分別稱為波蘭式和逆波蘭式,它們在編譯程序中有著非常重要的作用。

相關焦點

  • 二叉樹的前序非遞歸遍歷
    二叉樹的遍歷是二叉樹數據結構的重要操作之一,對於遍歷我們首先想到的就是遞歸,遞歸操作思想簡潔,操作簡單,但是在複雜的高度較大的二叉樹應用中使用遞歸算法,可能會造成性能的浪費,本文來介紹二叉樹的前序非遞歸遍歷。
  • 一個套路搞定二叉樹遍歷
    ,所謂遍歷二叉樹,就是按照一定的規則和順序不重複地走遍二叉樹所有的結點。二叉樹是每個節點最多有兩個結點的樹結構,通常由左右兩棵子樹組成。一棵簡單二叉樹小套路:上圖的二叉樹是由左右兩棵子樹組成,那麼我們將每一個節點都拆分為左右子樹,先遍歷整棵樹的根結點,然後遍歷整棵左子樹,最後遍歷整棵右子樹。遍歷子樹時同樣遵循根結點-左結點-右結點的順序。實戰過程剖析:1、先訪問根結點A。然後訪問A的左子樹。
  • LeetCode 例題精講 | 11 二叉樹轉化為鍊表:二叉樹遍歷中的相鄰結點
    Convert Binary Tree to Sorted Doubly Linked List 二叉樹轉化為鍊表(Medium)本文將介紹二叉樹問題中一個特殊的技巧:「在二叉樹的前/中/後序遍歷時對相鄰結點進行操作」。這種方法不適用於大多數題目,但在一些特定的題目中使用這個技巧,能起到「秒殺」的效果。
  • 二叉樹遍歷就是這麼簡單(必殺)
    看起來很刺激,不要謊,讓我慢慢道來。什麼是二叉樹學習二叉樹我們想,為什麼叫做二叉樹呢?類比樹,我們這個結構是不是有樹根樹杈呢?然後,我們再聲明一個二維指針,用來指向樹的根節點BinTreeNode** t;當這個樹雛形出來了後,我們需要做的就是完善這個二叉樹
  • 二叉樹的實現、遍歷及面試題
    樹還有兩種特殊類型,叫做「滿二叉樹」和「完全二叉樹」。滿二叉樹和完全二叉樹完全二叉樹是指「最底層的葉子節點全都集中在左邊,且其它層的節點數達到最大值」的樹,當完全二叉樹最底層的葉子結點樹也達到最大時,該樹被稱為滿二叉樹
  • 數據結構學習筆記:樹與樹的表示、二叉樹及其遍歷、二叉搜索樹、平衡二叉樹、堆、哈夫曼樹、集合及其運算
    2、二叉樹及存儲結構二叉樹的定義二叉樹T:一個有窮的結點集合    這個集合可以為空    若不為空,則它是由根結點和稱為其左子樹TL和右子樹TR的兩個不相交的二叉樹組成特殊二叉樹斜二叉樹(Skewed Binary
  • (二叉樹)
    「注意這個周末總結和系列總結還是不一樣的(二叉樹還遠沒有結束),這個總結是針對留言疑問以及刷題群裡討論內容的歸納。」周一本周我們開始講解了二叉樹,在關於二叉樹,你該了解這些!中講解了二叉樹的理論基礎。文章中我給出了leetcode上三道二叉樹的前中後序題目,但是看完二叉樹:一入遞歸深似海,從此offer是路人,依然可以解決n叉樹的前後序遍歷,在leetcode上分別是大家可以再去把這兩道題目做了。
  • 二叉樹的中序非遞歸遍歷
    二叉樹的中序遍歷順序是左子節點->根節點->右子節點。二叉樹如下圖所示:1 過程我們選用棧來存放需要處理的二叉樹節點,出棧順序即二叉樹的遍歷順序。首先要進行棧的初始化,很顯而易見的,如果二叉樹的根節點為空,那麼不需要任意遍歷直接結束;如果二叉樹的根節點不為空,使用current指向當前要處理的元素,此時current代表根節點1,如下圖所示:入棧規則:首先我們需要獲取棧頂元素current,注意該地方獲取指拿到棧頂元素,並不是將棧頂元素出棧,檢測棧頂是否有左孩子,如果有那麼需要一直將左孩子入棧,直到棧頂的元素不再有左孩子為止
  • 二叉樹的所有遍歷非遞歸實現
    前言:二叉樹的遍歷形式有很多,比如前序、中序、後序、層序遍歷,在最近的一次面試中,面試官要求手寫層序遍歷代碼(非遞歸的形式),由此可見遍歷的重要性.本篇博客我們就來看一下二叉樹的幾種遍歷方式.本篇博客語言均採用java實現:目錄:一:二叉樹簡介二:前序遍歷三:中序遍歷
  • 結構與算法:二叉樹與多叉樹
    >一、樹狀結構1、數組與鍊表數組結構數組存儲是通過下標方式訪問元素,查詢速度快,如果數組元素是有序的,還可使用二分查找提高檢索速度;如果添加新元素可能會導致多個下標移動,效率較低;鍊表結構鍊表存儲元素,對於元素添加和刪除效率高,但是遍曆元素每次都需要從頭結點開始
  • 二叉樹的後序非遞歸遍歷
    二叉樹的後序遍歷順序是左子節點->右子節點->根節點。二叉樹如下圖所示:1 過程後序遍歷與前序和中序不同的是:前序遍歷時,不需要檢測是否含有左子樹和右子樹子直接輸出當前節點;中序遍歷只需要查看當前節點是否含有左子樹並處理完畢後才能輸出當前節點;後序遍歷必須要查看左右子樹並且都處理完成後才能輸出,這也是非遞歸遍歷中後序遍歷的難點
  • 「算法與數據結構」二叉樹之美
    我們可以根據維基百科的依據來作為分類的標準👇無序樹:樹中任意節點的子節點之間沒有順序關係,這種樹稱為無序樹,也稱為自由樹;有序樹:樹中任意節點的子節點之間有順序關係,這種樹稱為有序樹;完全二叉樹:對於一顆二叉樹,假設其深度為d(d>1)。
  • 數據結構(八)--平衡二叉樹
    該來的總會來,平衡二叉樹果然又來了....出現背景前文已經研究過普通的二叉樹,為什麼要用二叉樹呢?因為二叉樹的結構可以實現二分法查找的效果。你比如前文介紹的滿二叉樹:如下圖所示,如果你想要查找4號元素,你只需要遍歷3次即可。所以在理想情況下,二叉樹可以優化遍歷。
  • 深入理解樹(二叉、二叉搜索樹)
    (B的高度為2,B—F—J);樹的高度:是樹中所有結點高度的最大值,樹的深度是樹中所有結點深度的最大值,對於同一棵樹,其深度和高度是相同的,但是對於各個結點,其深度和高度不一定相同;二叉樹如果一棵樹中的每個結點有0,1或者2個孩子結點,那麼這棵樹就稱為二叉樹;空樹也是一顆有效的二叉樹,一顆二叉樹可以看做是由根節點和兩棵不相交的子樹
  • 完整的二叉樹創建、遍歷、高度、葉子節點數的求法(附代碼)
    承接上一篇文章,本文將對二叉樹的創建、遍歷(前中後序遍歷)、樹的高度、樹的葉子節點數的求法進行代碼實現,以C++為例,如果有不懂的可以評論區留言討論。c++實現二叉樹節點類定義createTree(Node*& node); //創建二叉樹的函數void treeDelete(Node*& node); //刪除二叉樹的函數void preFind(const Node* node); //前序遍歷函數void midFind
  • 二叉查找樹之 Java的實現【上】
    二叉查找樹(Binary Search Tree),又被稱為二叉搜索樹。它是特殊的二叉樹:對於二叉樹,假設x為二叉樹中的任意一個結點,x節點包含關鍵字key,節點x的key值記為key[x]。如果y是x的左子樹中的一個結點,則key[y] <= key[x];如果y是x的右子樹的一個結點,則key[y] >= key[x]。那麼,這棵樹就是二叉查找樹。如下圖所示:
  • 幾道和「二叉樹」有關的算法面試題
    二叉樹的詳細講解請戳這:懵逼樹上懵逼果:學習二分搜索樹1. 二叉樹的前序遍歷題目來源於 LeetCode 第 144 號問題:二叉樹的前序遍歷。題目描述 給定一個二叉樹,返回它的 前序 遍歷。題目解析 用棧(Stack)的思路來處理問題。
  • 【數據結構與算法圖文動畫詳解】終於可以徹底弄懂:紅黑樹、B-樹、B+樹、B*樹、滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜索樹
    <E> right; public TreeNode(E e) { element = e; }}二叉樹的遍歷方式:先序遍歷:先根節點->遍歷左子樹->遍歷右子樹中序遍歷:遍歷左子樹->根節點->遍歷右子樹後序遍歷:遍歷左子樹->遍歷右子樹
  • 二叉樹的鋸齒形層序遍歷
    【題目】給定一個二叉樹,返回其節點值的鋸齒形層序遍歷。(即先從左往右,再從右往左進行下一層遍歷,以此類推,層與層之間交替進行)。
  • 二叉查找樹 Java實現
    它是特殊的二叉樹:對於二叉樹,假設x為二叉樹中的任意一個結點,x節點包含關鍵字key,節點x的key值記為key[x]。如果y是x的左子樹中的一個結點,則key[y] <= key[x];如果y是x的右子樹的一個結點,則key[y] >= key[x]。那麼,這棵樹就是二叉查找樹。