二叉查詢樹(BST)及二叉樹的遍歷

2021-09-27 01:52:22 字數 3891 閱讀 2051

一、二叉查詢樹(bst)

1、二叉查詢樹的特徵

二叉查詢樹(bst)也稱為二叉搜尋樹或二叉排序樹。二叉查詢樹的節點包含鍵值key。二叉查詢樹或者是一棵空樹,否則要求:

若它的左子樹不為空,那麼左子樹上所有節點的key都小於根節點的key。

若它的右子樹不為空,那麼右子樹上所有節點的key都大於根節點的key。

它的左右子樹也分別為二叉排序樹。

2、二叉查詢樹的建立、查詢、插入和刪除

(1)遞迴建立二叉查詢樹

btree creat_tree(btree root, int val)

else if (root->data < val)//如果新值比節點值大,遞迴地建立右子樹

root->right = creat_tree(root->right, val);

else if (root->data > val)//如果新值比節點值小,遞迴地建立左子樹

root->left = creat_tree(root->left, val);

else

exit(-1);

return root;

}

(2)查詢節點

btree search_tree(btree ptr, int val)

}//查詢值最小的節點

btree findmin_tree(btree root)

//查詢值最大的節點

btree findmax_tree(btree root)

(3)插入節點

btree insert_tree(btree root, int val)

}

(4)刪除節點

二、二叉樹的遍歷

遍歷二叉樹,就是以某種方式逐個「訪問」二叉樹的每乙個節點。「訪問」是指對節點的進行某種操作,例如輸出節點的值。根據訪問樹根的順序,我們有三種方式遍歷二叉樹:

前序遍歷:樹根->左子樹->右子樹

中序遍歷:左子樹->樹根->右子樹

後序遍歷:左子樹->右子樹->樹根

1、前序遍歷

先訪問根節點,再遍歷左子樹,最後遍歷右子樹;並且在遍歷左右子樹時,仍需先訪問根節點,然後遍歷左子樹,最後遍歷右子樹。

例如下圖中二叉樹前序遍歷節點訪問順序為abdghceif:

2、中序遍歷

先遍歷左子樹、然後訪問根節點,最後遍歷右子樹;並且在遍歷左右子樹的時候。仍然是先遍歷左子樹,然後訪問根節點,最後遍歷右子樹。

例如前圖中二叉樹中序遍歷節點訪問順序為gdhbaeicf:

3、後序遍歷

先遍歷左子樹,然後遍歷右子樹,最後訪問根節點;同樣,在遍歷左右子樹的時候同樣要先遍歷左子樹,然後遍歷右子樹,最後訪問根節點。前圖後序遍歷結果如下。

例如前圖中二叉樹後序遍歷節點訪問順序為ghdbiefca:

4、確定唯一的二叉樹

在二叉樹的三種遍歷方式中,如果有中序與前序的遍歷結果或者中序與後序的遍歷結果,即可從這些結果中得到唯一的二叉樹。

確定唯一二叉樹的方式:

首先根據前序遍歷的首元素或者後序遍歷的尾元素,在中序遍歷確定根節點。

隨後根據該根節點在中序遍歷中確定左右子樹。

三、前序、中序、後序遍歷的遞迴和非遞迴實現

1、遞迴實現

void inorder(btree ptr)//中序(輸出根節點次序)遍歷(遞迴實現)

}void preorder(btree ptr)//前序遍歷(遞迴實現)

}void postorder(btree ptr)//後序遍歷(遞迴實現)

}

2、非遞迴實現(使用棧)

//非遞迴中序遍歷(左節點->根節點->右節點)思想:即用棧實現  

// 因為中序遍歷二叉樹的特點,所以在當前節點cur不為空或棧不為空的條件下(在該條件下的原因:該條件說明

// 未遍歷完二叉樹),開始執行迴圈體,進行遍歷:

//(1)從當前節點cur開始,以cur為迴圈條件,當cur不為空時,將cur入棧,然後以cur=cur->_left跟進,直至

// 將該二叉樹的最左節點入棧後,入棧操作結束

//(2)取棧頂節點:先儲存該節點(用top儲存該節點的原因:還要考慮該節點的右孩子)並輸出該節點的值,

// 然後執行棧的pop操作。

//(3)繼續以top->_right為cur值,轉(1)操作.

void inorder2(btree ptr)//中序遍歷的非遞迴實現

btree tp = st.top();

cout << tp -> data << " ";

st.pop();

ptr = tp -> right;

}}//非遞迴先序遍歷(根節點->左節點->右節點)思想:即用棧實現

//遍歷二叉樹的前提條件是:該二叉樹不為空。在滿足該條件的情況下,進行以下步驟:

//1.先將二叉樹的根節點push進棧。

//2.在該棧不為空的條件下,執行乙個迴圈(先用top儲存棧頂元素,再對棧進行pop操作,因為棧具有後進先出的特點

// ,所以先對top->_right進行判斷是否入棧,再對top->_left進行判斷是否入棧)。

//3.當棧為空時,先序遍歷該二叉樹結束。

void preorder2(btree ptr)//前序遍歷的非遞迴實現

while (!st.empty())

}//非遞迴後序遍歷(左節點->右節點->根節點)思想:即用棧實現

//(1)在當前節點cur不為空或棧不為空的條件下(在該條件下的原因:該條件說明未遍歷完二叉樹)。

//(2)從當前節點cur開始,以cur為迴圈條件,當cur不為空時,將cur入棧,然後以cur=cur->_left跟進,直至

// 將該二叉樹的最左節點入棧後,入棧操作結束。取棧頂節點top:先儲存該節點(用top儲存該節點的原因:

// 還要考慮該節點的右孩子),

//(3)若top->_right==null || lastvisited == top->_right,則輸出top->_value,執行棧的pop操作,並執行lastvisited = top(

// 用lastvisited儲存最近乙個所輸出的節點,待到下一次同樣的操作時,若lastvisited == top->_right,則

// 說明top的右節點已經訪問過了,可以訪問top了,否則會陷在cur = top->_right這步操作裡);

//(4)若條件(3)不滿足,則繼續以top->_right為cur值,轉(1)操作.

void postorder2(btree ptr)//後序遍歷的非遞迴實現

btree tp = st.top();

if (tp->right == nullptr || lastvisited == tp->right)

else

ptr = tp->right;}}

參考:

查詢二叉樹(BST)

今天分享一些關於bst的內容 一 基礎知識點 1 一棵樹最上面的節點稱為根節點,如果乙個節點下面連線多個節點,那麼該節點稱為父節點,它下面的節點稱為子節點。乙個節點可以有0個 1個 或多個子節點,沒有任何子節點的節點稱為葉子節點 2 以某種特定的順序訪問樹中所有的節點稱為樹的遍歷 3 樹可以分為幾個...

二叉樹 四 二叉查詢樹 BST

二叉查詢樹 對於二叉查詢樹的任何乙個節點,設這個節點的值為k,這個節點的左子樹的任意乙個節點的值都小於k,右子樹的任何乙個節點的值都大於等於k。對於任何的二叉查詢樹,使用中序遍歷 左根右 可以將值從小到大列印出來。對於二叉查詢樹的檢索,例如圖a,需要檢索32,那麼首先需要檢索根節點,發現37大於32...

二叉樹及二叉樹的遍歷

二叉樹的定義 樹的度為2的樹。二叉樹的遞迴定義 二叉樹或者是一棵空樹,或者是一棵由乙個根結點和兩棵互不相交的左子樹和右子樹所組成的非空樹,而左右子樹又都是一棵二叉樹。1.第i層上至多有2的i 1次方個結點。2.深度為h的二叉樹至多有2的h次方減1個結點。3.每一層都滿的二叉樹稱為滿二叉樹,只在最後一...