演算法之二叉樹各種遍歷

2021-07-02 00:28:37 字數 3365 閱讀 2481

**:

樹形結構是一類重要的非線性資料結構,其中以樹和二叉樹最為常用。

二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作「左子樹」(left subtree)和「右子樹」(right subtree)。二叉樹常被用作二叉查詢樹和二叉堆或是二叉排序樹。二叉樹的每個結點至多只有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2的 i -1次方個結點;深度為k的二叉樹至多有2^(k) -1個結點;對任何一棵二叉樹t,如果其終端結點數(即葉子結點數)為n0,度為2的結點數為n2,則n0 = n2 + 1。

二叉樹的鏈式儲存結構是一類重要的資料結構,其形式定義如下:

[cpp]view plain

copy

//二叉樹結點

typedef

struct

bitnodebitnode,*bitree;  

二叉樹的建立:

通過讀入乙個字串,建立二叉樹的演算法如下:

[cpp]view plain

copy

//按先序序列建立二叉樹

intcreatebitree(bitree &t)  

else

return

0;  

}  

二叉樹的遍歷:

遍歷是對樹的一種最基本的運算,所謂遍歷二叉樹,就是按一定的規則和順序走遍二叉樹的所有結點,使每乙個結點都被訪問一次,而且只被訪問一次。由於二叉樹是非線性結構,因此,樹的遍歷實質上是將二叉樹的各個結點轉換成為乙個線性序列來表示。

遞迴演算法:

[cpp]view plain

copy

//輸出

void

visit(bitree t)  

}  //先序遍歷

void

preorder(bitree t)  

}  //中序遍歷

void

inorder(bitree t)  

}  //後序遍歷

void

postorder(bitree t)  

}  

非遞迴演算法:

<1>先序遍歷:

【思路】:訪問t->data後,將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,再先序遍歷t的右子樹。

[cpp]view plain

copy

/* 先序遍歷(非遞迴)

思路:訪問t->data後,將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,再先序遍歷t的右子樹。

*/void

preorder2(bitree t)  

else

}//while

}  

<2>中序遍歷

【思路】:t是要遍歷樹的根指標,中序遍歷要求在遍歷完左子樹後,訪問根,再遍歷右子樹。

先將t入棧,遍歷左子樹;遍歷完左子樹返回時,棧頂元素應為t,出棧,訪問t->data,再中序遍歷t的右子樹。

[cpp]view plain

copy

void

inorder2(bitree t)  

else

}//while

}  

<3>後序遍歷

【思路】:t是要遍歷樹的根指標,後序遍歷要求在遍歷完左右子樹後,再訪問根。需要判斷根結點的左右子樹是否均遍歷過。

[cpp]view plain

copy

//後序遍歷(非遞迴)

typedef

struct

bitnodepostbitnodepost,*bitreepost;  

void

postorder2(bitree t)  

//左右子樹訪問完畢訪問根節點

while

(!stack.empty() && (stack.top())->tag == 

'r')  

//遍歷右子樹

if(!stack.empty())  

}//while

}  

<4>層次遍歷

【思路】:按從頂向下,從左至右的順序來逐層訪問每個節點,層次遍歷的過程中需要用佇列。

[cpp]view plain

copy

//層次遍歷

void

levelorder(bitree t)  

//右子樹不空,將右子樹入隊

if(p->rchild != null)  

}  }  

測試用例:

輸入:abc##de#g##f###

輸出:

已知先序和中序求後序的演算法:(已知後序和中序求先序的演算法類似,但已知先序和後序無法求出中序)

[cpp]view plain

copy

intfind(

char

c,char

a,int

s,int

e) /* 找出中序中根的位置。 */

/* 其中pre表示先序序,pre_s為先序的起始位置,pre_e為先序的終止位置。 */

/* 其中in表示中序,in_s為中序的起始位置,in_e為中序的終止位置。 */

/* pronum()求出pre[pre_s~pre_e]、in[in_s~in_e]構成的後序序列。 */

void

pronum(

char

pre,

intpre_s,

intpre_e,

char

in,int

in_s,

intin_e)  

c=pre[pre_s]; /* c儲存根節點。 */

k=find(c,in,in_s,in_e); /* 在中序中找出根節點的位置。 */

pronum(pre,pre_s+1,pre_s+k-in_s,in,in_s,k-1); /* 遞迴求解分割的左子樹。 */

pronum(pre,pre_s+k-in_s+1,pre_e,in,k+1,in_e); /* 遞迴求解分割的右子樹。 */

printf("%c"

,c); 

/* 根節點輸出。 */

}  main()    

演算法之二叉樹各種遍歷

樹形結構是一類重要的非線性資料結構,其中以樹和二叉樹最為常用。二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作 左子樹 left subtree 和 右子樹 right subtree 二叉樹常被用作二叉查詢樹和二叉堆或是二叉排序樹。二叉樹的每個結點至多只有二棵子樹 不存在度大於2的結點 ...

演算法之二叉樹各種遍歷

樹形結構是一類重要的非線性資料結構,其中以樹和二叉樹最為常用。二叉樹是每個結點最多有兩個子樹的有序樹。通常子樹的根被稱作 左子樹 left subtree 和 右子樹 right subtree 二叉樹常被用作二叉查詢樹和二叉堆或是二叉排序樹。二叉樹的每個結點至多只有二棵子樹 不存在度大於2的結點 ...

演算法之二叉樹各種遍歷

樹形結構是一類重要的非線性資料結構,當中以樹和二叉樹最為經常使用。二叉樹是每乙個結點最多有兩個子樹的有序樹。通常子樹的根被稱作 左子樹 left subtree 和 右子樹 right subtree 二叉樹常被用作二叉查詢樹和二叉堆或是二叉排序樹。二叉樹的每乙個結點至多僅僅有二棵子樹 不存在度大於...