二叉排序樹

2022-07-13 21:42:30 字數 4103 閱讀 5711

首先要對陣列和鍊錶儲存結構的優缺點進行分析:

對於未排序的陣列:插入速度快(直接在尾部插入),但是查詢速度慢(時間複雜度為o(n)),需要依次遍歷。

對於有序陣列:查詢時間通過二分查詢,時間複雜度為o(logn)。可是當查詢到查詢到值後,需要將後續的值依次後移,時間複雜度為o(n)。

對於有序陣列的插入時間複雜度證明如下:查詢o(logn)+後移o(n) = o(n)

對於無序鍊錶:查詢的時間複雜度為o(n),插入的時間複雜度為o(1)

對於有序鍊錶:查詢和插入的時間複雜度均為o(n)

而陣列和鍊錶的刪除操作時間複雜度均為o(n)

而對於樹儲存結構來說:平均查詢,插入和刪除的時間複雜度均為o(log(n)),並且構建容易,使用穩定。

二叉排序樹需要滿足這樣的條件:對於樹中任意乙個非葉子節點,左子節點一定比當前節點值小,右子節點一定比當前節點值大。

首先建立節點類:

屬性如下:

class

node

實現插入方法:

public void add(node node)

if(this.value > node.value)else

}elseelse}}

中序遍歷:

public

void

infixorder()

system.out.println(

this

.value);

if(this.right!=null

) }

根據value搜尋相應的結點:

/*

思想類似於二分查詢。比如:如果搜尋的值比當前結點的值大,則往其右子樹遞迴查詢。

*/public node search(int

value)

else

if(this.value

else

}else

else}}

根據value值搜尋相應結點的父節點:

在進行搜尋的時候會有幾種情況需要分類討論:

搜尋值:value   當前值:this.*.value *代表left或right

case0:  value = this.*.value

case1:value>this.*.value,右子結點存在時,需往右遞迴

case2:   valuecase3:  其他情況均不滿足,比如value>this.*.value,而右子結點不存在,左子結點存在時。

/**

* *

@param

value

* @return

如果該結點的左子結點或右子結點的值等於value則返回

*/public node getparentnode(int

value)

else

if(this.value < value && this.right != null

) else

if(this.value >= value && this.left != null

)else

}

尋找當前結點右子樹中value最小的結點:

該方法是為了刪除方法作鋪墊

/*

因為左子結點的值一定小於右子結點的值,所以當前結點的右子樹中最小值需要一直往左遞迴得到

結合圖看思路很清晰

*/public

intgetrightminvaluenode()

return

target.value;

}

接著構造二叉搜尋樹:

public

class

binarysorttreedemo

通過呼叫node物件的方法實現二叉搜尋樹的search,getparent,delrightminvaluenode(刪除右子樹最小結點):

public node search(int

value)

else

}public node getparent(int

value)

else

}public

intdelrightminvaluenode(node node)

delnode(target.value);

return

target.value;

}

樹新增新結點和中序遍歷的方法:

public

void

add(node node)

else

}public

void

infixorder()

else

}

需要考慮以下情況:

設刪除的結點為:cur

其父結點為 :parent

根結點 :root

由易到難,我們首先考慮根節點的特殊情況:

case0 :  root = null;直接返回

case1:只存在root乙個結點,則root.left = null; root.right = null;

接著考慮更一般化的情況:

case2: 當結點為葉子結點時,無需考慮葉子結點的左右結點,只需要判斷parent.left.value == value 還是

parent.right.value == value 為true;相應地,將parent.left設定為null即可完成刪除操作

case3:當結點有且僅有乙個子結點(左結點或者右節點),那麼分類討論:

1.當該結點存在左子結點時:

(a) 如果cur為父結點的左子結點,那麼通過parent.left = cur.left完成刪除

(b) 如果cur為父節點的右子節點時,因為cur右子樹的value一定大於cur的value也大於parent.value,

所以通過parent.right = cur.left完成刪除

2.當該結點存在右子結點時,該類情況與1類似,不做展開。

case4: 當結點的左右結點均存在時。需要在該結點的子樹中找到乙個結點來替換。

如下圖所示,假如刪除的node.value為15,我們需要在紅框內找乙個結點,其值能完美替代15。

刪除的node的value需要滿足比右子樹所有值小,比左子樹所有值大

那麼可以選擇左子樹中值最大的結點 :一直向右遞迴,得到node1

或者選擇右子樹中值最小的結點:一直向左遞迴,得到node1

找到上述結點node1後,將其值賦給要刪除的結點,並刪除結點node1完成刪除操作

二叉排序樹

在複習資料結構,把這個東西總結一下。這種結構是動態查詢表,這種動態是相對靜態查詢 順序查詢,折半查詢,分塊查詢等 來說的。對於各種靜態鍊錶,要達到查詢複雜度為o logn 必須要求有序 而要使插入刪除複雜度為o 1 必須是鍊錶儲存。動態查詢表就可以同時滿足這兩者。動態查詢表的特點是表結構本身在查詢過...

二叉排序樹

name 二叉排序樹相關操作 author unimen date 2011 10 8 13 14 21 刪除結點比較麻煩,總結如下 4大種情況 1 結點p無右孩子 將該點的左孩子變為其在雙親中的同位孩子 1 p為其雙親的左孩子時將其的左孩子變為雙親的左孩子 2 p為其雙親的右孩子時將其的左孩子變為...

二叉排序樹

include include include include struct tree node void insert node struct tree node int void pre order struct tree node void in order struct tree node ...