1.問題描述:
二叉樹結點值為大寫字母,輸入二叉樹的前序遍歷和中序遍歷序列,生成此二叉樹,輸出該二叉樹的後序遍歷和按層次遍歷序列。輸入某結點值,在二叉樹中查詢該結點,若該結點存在,則輸出從根到該結點的路徑,否則給出不存在資訊。
2.演算法思路:
樹的建立:將樹的前序序列和中序序列分別存入兩個陣列中,前序序列的第乙個值為樹的根節點,在中序序列裡找到該值,便可知道根節點的左子樹的結點數和右子樹的結點數。根據左子樹的結點數和右子樹的結點數可以將這兩個陣列分割為左子樹部分和右子樹部分,繼續分別建立樹。採用遞迴便可完成。(注:為方便後續使用,樹的結點有左孩,右孩,父母三個指標。)
後序遍歷:用遞迴即可實現,注意為空的情況。
層次遍歷:採用佇列進行層次遍歷。先將樹根入佇列,然後進入迴圈。每齣佇列中的乙個節點,就將該節點的左孩,右孩先**佇列,直到佇列中沒有節點為止。
查詢結點:用前序遞迴遍歷樹,每遍歷乙個結點就對該結點值與查詢值進行比對,一旦相同則返回該結點指標,否則繼續遍歷,沒有則返回空。
輸出樹根到結點的路徑:根據結點指標,沿它的父母指標向上遞迴遍歷,出口為根節點的父母指標為空。先遍歷祖先,再輸出結點值,便可以得到從樹根到結點的路徑。
3.演算法描述:
1.結點的結構體中除了字元資料,還有它的左孩子,右孩子,父母的指標。
2.creat(樹的建立函式):
傳入:樹的前序序列陣列pre,樹的中序序列陣列in,樹的前序序列陣列的起始點a和結束點b,樹的中序序列陣列的起始點c和結束點d.
返回:樹的根節點的指標(node *)
函式內容:
動態申請根節點空間,賦根植,若前序陣列中只有乙個值,即該樹只有根節點,將根結點的左右孩子均賦為空,返回根節點。在中序序列裡找到根節點並記錄其位置,就可以得到左子樹的結點數和右子樹的結點數,然後將陣列劃分為左子樹和右子樹部分。如果左子樹為空,則根節點左孩子賦為空,否則繼續呼叫本函式,根據左子樹的結點數對陣列界限進行修改,將返回值賦即左子樹的根結點指標賦給根結點的左孩子,並且賦根結點的值給左孩子的父母指標。右邊類似。
3.levelorder(按層次遍歷函式):
需要傳入:樹的根結點指標(node *),無返回值
函式內容:建立佇列,並將根節點入佇列。進入迴圈(出乙個佇列中的元素,並將其輸出,然後將該元素的左孩子,右孩子先**佇列),出口條件為隊列為空。
4.postorder(後序遍歷函式):
需要傳入:樹的根結點指標(node *) ,void
函式內容:根結點不為空時,遞迴呼叫本函式後序遍歷左子樹,繼續呼叫本函式後序遍歷右子樹,然後輸出根結點值。
5.search(查詢結點函式):
需要傳入:樹的根結點指標(node *) ,返回:找到結點的指標(node *),沒有則返回空(null)
函式內容:若根結點為空則返回空。根結點不為空時判斷根結點是否為待找結點,是則返回。若不是則繼續呼叫本函式查詢左子樹,若返回值不為空則返回該返回值,否則繼續呼叫本函式查詢右子樹,並將返回值返回。
6.path(輸出根到結點的路徑函式):
需要傳入:結點指標(node *) 無返回值
函式內容:結點指標不為空時,呼叫該函式以輸出該結點的父母指標的路徑,然後輸出該結點的值。
7.主函式:將樹的前序序列和中序序列讀入並存入字元陣列中,依次呼叫creat(建立樹函式),display(輸出樹函式),postorder(後序遍歷樹函式),levelorder(層次遍歷樹函式),search(查詢節點函式),path(輸出從根到結點的路徑函式),完成該程式。
4.源程式:
#include
node *
creat
(char pre[maxnode]
,char in[maxnode]
,int
a,int b,
int c,
int d)
for(i=c;in[i]
!=pre[a]
;i++);
if(i!=c)
else
ptr->lc=
null;if
(i!=d)
else
ptr->rc=
null
;return
ptr;
}//建立樹
void
display
(node *ptr,
int level)
}//輸出樹
void
postorder
(node *ptr)
}//後序遍歷樹
void
initqueue
(queue &s)
//初始化佇列
void
enqueue
(queue &s,node *ptr)
else}}
//入佇列
node *
dequeue
(queue &s)
//出佇列
void
levelorder
(node *ptr)
}//層次遍歷
node *
search
(node *ptr,
char c)
else
return
null;}
//查詢結點
void
path
(node *ptr)
}//輸出根到節點的路徑
intmain()
return0;
}
5.結果分析:
基本實現程式要求功能,對樹為空,只有乙個結點等問題都具有健壯性
6.心得體會:
1.scanf之前要使用getchar除去之前輸入時遺留在緩衝區內的\n,使得正確讀入。
2.對於樹的遞迴建立,最後要專門給根結點指標的父母指標賦為空。
3.對於有關樹的函式,都是在樹根非空的基礎上進行操作,故一進函式就對根結點進行判斷,不為空時才有後序操作。
4.用前序遞迴法建立樹最簡單。
5.若要將二叉樹的前序遍歷改為逆前序,中序遍歷改為逆中序,後序遍歷改為逆後序,只需將左右孩子指標的引用次序調換即可。
6.除了用父母指標得到根到某一結點的路徑,還可以用查詢遞迴的方法實現,即判斷結點左右子樹中是否有待查詢結點,將有結點的孩子指標插入路徑中,不斷遞迴即可,但是效率較為低下。
資料結構 二叉樹練習題
求二叉樹的高度 只能彙總思想 int getheight node root int left getheight root.left int right getheight root.right return math.max left,right 1 求二叉樹第k層結點的個數 彙總 1.利用遞迴...
資料結構 二叉樹 反轉二叉樹
include using namespace std define maxsize 1000 struct binary tree node class queue queue queue void queue push binary tree node btn binary tree node ...
《資料結構》 二叉樹
二叉樹 是 n個結點的有限集,它或為空集,或由乙個根結點及兩棵互不相交的 分別稱為該根的左子樹和右子樹的二叉樹組成。二叉樹不是樹的特殊情況,這是兩種不同的資料結構 它與無序樹和度為 2的有序樹不同。二叉樹的性質 1 二叉樹第 i層上的結點數最多為 2 i 1 2 深度為 k的二叉樹至多有 2 k 1...