首先要對陣列和鍊錶儲存結構的優缺點進行分析:
對於未排序的陣列:插入速度快(直接在尾部插入),但是查詢速度慢(時間複雜度為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根據value搜尋相應的結點: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 當前值:this.*.value *代表left或right
case0: value = this.*.value
case1:value>this.*.value,右子結點存在時,需往右遞迴
case2: valuecase3: 其他情況均不滿足,比如value>this.*.value,而右子結點不存在,左子結點存在時。
/**尋找當前結點右子樹中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
}
該方法是為了刪除方法作鋪墊
/*接著構造二叉搜尋樹:因為左子結點的值一定小於右子結點的值,所以當前結點的右子樹中最小值需要一直往左遞迴得到
結合圖看思路很清晰
*/public
intgetrightminvaluenode()
return
target.value;
}
public通過呼叫node物件的方法實現二叉搜尋樹的search,getparent,delrightminvaluenode(刪除右子樹最小結點):class
binarysorttreedemo
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 ...