樹是一種相對比較複雜的資料結構,它要麼為空,要麼具有乙個值並具有零個或多個孩子,每個孩子本身就是樹,這是乙個遞迴的定義,二叉樹是樹的一種特殊形式,也是資料結構中最常用到的形式,二叉樹又可以根據左右孩子節點與跟節點的大小關係分為很多種,這裡以二叉搜尋樹為例學習,二叉搜尋樹有乙個額外的特點:每乙個節點的值比它的左子樹的所有節點的值都要大,但比它的右子樹的所有節點的值都要小,這個定義排除了樹中存在值相同的節點的可能性。二叉搜尋樹是一種關鍵值快速查詢資料的優秀工具。
和分析堆疊、佇列一樣我們首先還是分析二叉搜尋樹提供的介面,首先就是資料的插入insertbst()、資料的刪除deletebst()。既然它是乙個查詢資料的優秀工具那麼必不可少的就是查詢介面了serchbst(),和堆疊和佇列不同,二叉樹並沒有限制只能訪問某乙個值,因此二叉樹具有乙個基本操作遍歷。除此之外,那就是二叉搜尋樹的建立與銷毀。
介面如下:
建立乙個二叉樹實際上就是乙個不斷插入新值的過程,因為這個新值必須插入到乙個合適的位置才能繼續保持二叉搜尋樹的特性。插入的基本思路如下:
如果樹為空:
把新值作為跟節點插入
否則:如果新值小於當前節點的值:
把新值插入到當前節點的左子樹
否則:把新值插入當前節點的右子樹
這個演算法是按照搜尋二叉樹的定義來完成的,可以看書這個演算法也是乙個遞迴,並且是乙個尾部遞迴,因此可以很容易使用迭代來代替遞迴提高程式的效率。
從二叉搜尋樹刪除乙個值是比較困難的,從一顆數的中部刪除乙個節點將導致它的的子樹和屬的其餘部分斷開,我們必須重新鏈結他們,並且面臨三種處理情況:刪除沒有孩子的節點;刪除有乙個孩子的節點;刪除有兩個孩子的節點。第一種情況比較簡單,直接刪除該節點就可以了不會導致子樹斷開,因為這個節點已經沒有子樹了,刪除有乙個孩子的節點時把這個節點的雙親節點和它的孩子連線起來就可以了,最後一種情況是比較困難的,因為乙個節點有兩個孩子,它的雙親不能鏈結到它的兩個孩子,解決這個問題的乙個策略是刪除它的左子樹最大的那個值,並用這個值代替原先被刪除的那個節點的值。
由於二叉搜尋樹的有序性,所以在樹中查詢乙個也定的值是比較容易的,同意是乙個遞迴的演算法:
如果樹為空:
這個值不存在於樹中
否則:如果這個值和根節點的值相等:
成功找到這個值
否則:如果這個值小於根幾點的值:
查詢左子樹
否則:查詢右子樹
這也是乙個尾部遞迴可以使用迭代代替提高演算法的效率。
遍歷樹的節點有幾種不同的次序,最常用的是前序、中序、後序和層次遍歷。所有型別的遍歷都是從樹的跟節點或你希望開始遍歷的子樹的根節點開始。
前序遍歷:簡單點記就是「根左右」,先檢視根節點然後遍歷左子樹,遍歷左子樹也是「根左右」的方式,當做子樹遍歷完成以後開始遍歷右子樹也是以「根左右」的方式,也就是說遍歷也是乙個遞迴的方式。
層次遍歷:層次遍歷先從跟節點開始,同一層從左向右開始遍歷。一種比較普遍的做法是使用佇列來實現層次遍歷,當訪問某給節點時首先將這個節點的左右孩子進入佇列,然後依次從佇列中出列遍歷。
接下來就是實現二叉搜尋樹的各種是介面了,還是堆疊和佇列一樣,使用靜態陣列、動態陣列、鏈式結構來分別實現。
靜態陣列的實現比較簡單,某個節點的左右孩子很容易計算處理,可以使用陣列的下標來代替指標,因此不需要額外的空間來儲存指向左右節點的指標,計算公式如下:
節點n的雙親節點為: n/2 (注意這裡沒有問題,因為整數的除法會截去小數部分)
節點n的左孩子節點為: 2*n
節點n的右孩子節點為: 2*n+1
注意這個規則是建立在根節點是陣列下標為1的元素,但是實際上陣列都是以下標0開始的,如果不想忽略陣列的第0個空間,可以將公式稍微修改一下:
節點n的雙親節點為: (n+1)/2 -1
節點n的左孩子節點為: 2*n + 1
節點n的右孩子節點為: 2*n + 2
由於陣列元素的個數是預先確定的,不管二叉樹有沒有只有這個空間這個空間已經分配,因此必須使用乙個特殊的值用於標識這個值是否被使用,這裡我們使用0值作為此節點未被使用的標識。
具體的實現方式如下:
動態陣列的實現只是多了乙個建立陣列的過程,其他實現方式和靜態陣列的實現完全一樣。
二叉搜尋樹 二叉搜尋樹
題目 二叉搜尋樹 time limit 2000 1000 ms j a others memory limit 32768 32768 k j a others total submission s 6945 accepted submission s 3077 problem descripti...
二叉搜尋樹的實現
binarysearchtree.h inte ce for the binarysearchtree class.include binarytreenode.h include binarytree1.h if defined afx binarysearchtree h 1cd2ff9d 73...
二叉搜尋樹的實現
includeusing namespace std 二叉搜尋樹左兒子的值比當前節點小,右兒子的數值比當前節點大 struct node 建立樹 node insert node p,int x else return p 查詢 bool find node p,int x else return ...