模擬實現二叉搜尋樹

2021-10-01 09:08:09 字數 4463 閱讀 6989

二叉搜尋樹又稱二叉排序樹,它或者是一棵空樹,或者是具有以下性質的二叉樹:二叉搜尋樹的查詢:

//非遞迴查詢

node*

find

(const k& key)

else

if(cur-

>_key > key)

else

}return

nullptr;}

//遞迴查詢

node*

_findr

(node* root,

const k& key)

if(root-

>_key == key)

else

if(root-

>_key < key)

else

if(root-

>_key > key)

} node*

findr

(const k& key)

二叉搜尋樹的插入:
//遞迴插入

bool

_insertr

(node*

& root,

const k& key)

//加上引用才可以插入進去

if(root-

>_key < key)

else

if(root-

>_key > key)

else

}bool

insertr

(const k& key)

//非遞迴插入

bool

insert

(const k& key)

node* cur = _root;

node* parent =

nullptr

;//注意要在這裡定義乙個parent儲存前乙個結點,最後在連線上才能實現插入

while

(cur)

else

if(cur-

>_key > key)

else

} cur =

newnode

(key);if

(parent-

>_key < key)

else

return

true

;}

注意(可以看上述**實現):

二叉搜尋樹的刪除:

首先查詢元素是否在二叉搜尋樹中,如果不存在,則返回, 否則要刪除的結點可能分下面四種情況:

其實上面四種情況總體上來算就只有三種情況,因為 a 情況可以算是 b 或者 c 情況。則刪除方法只有三種分別為:

else

if(cur-

>right ==

nullptr

)else

else

}}

其中又有兩種情況:

①:被刪除節點的父親結點的左孩子是該刪除結點(比如下圖要刪除 1 )

②:被刪除節點的父親結點的右孩子是該刪除結點(比如下圖刪除 7 )

此外,還應該注意,剛開始要判斷刪除的結點的父親是否為空,防止根節點的左孩子為空且要刪除根節點的時候,後面對 parent 操作會出錯,比如 要刪除 5, 5 是根節點,此時就應該直接 將 7 作為根節點(後附**):

//這裡的 lessparent 不能為初始化為空,應該考慮循壞如果不進去的時候就會出錯

node* lessright = cur-

>right;

while

(lessright-

>left)

cur-

>_key = lessright-

>_key;

del = lessright;

if(lessparent-

>left == lessright)

//用來替換應該刪除結點的結點可能還有右孩子

else

整個實現完整源**:

template

<

class

k>

struct bstreenode};

template

<

class

k>

class

bstree

//遞迴插入

bool

_insertr

(node*

& root,

const k& key)

//加上引用才可以插入進去

if(root-

>_key < key)

else

if(root-

>_key > key)

else

}bool

insertr

(const k& key)

//非遞迴插入

bool

insert

(const k& key)

node* cur = _root;

node* parent =

nullptr

;//注意要在這裡定義乙個parent儲存前乙個結點,最後在連線上才能實現插入

while

(cur)

else

if(cur-

>_key > key)

else

} cur =

newnode

(key);if

(parent-

>_key < key)

else

return

true;}

//中序遍歷

void

inorder()

//呼叫遞迴時候,需要再次定義乙個_inorder(),因為物件在類外面無法傳參

void

_inorder

(node* root)

_inorder

(root-

>left)

; cout << root-

>_key <<

" ";

_inorder

(root-

>right);}

//非遞迴查詢

node*

find

(const k& key)

else

if(cur-

>_key > key)

else

}return

nullptr;}

//遞迴查詢

node*

_findr

(node* root,

const k& key)

if(root-

>_key == key)

else

if(root-

>_key < key)

else

if(root-

>_key > key)

} node*

findr

(const k& key)

//刪除

bool

erase

(const k& key)

else

if(cur-

>_key > key)

else

else

else}}

//2.右為空(裡面也包含兩種小情況)

else

if(cur-

>right ==

nullptr

)else

else}}

//3.左右都不為空

else

cur-

>_key = lessright-

>_key;

del = lessright;

if(lessparent-

>left == lessright)

//用來替換應該刪除結點的結點可能還有右孩子

else

}delete del;

return

true;}

}return

false;}

private

: node* _root;

};

二叉搜尋樹的模擬實現與總結

二叉搜尋樹又稱二叉排序樹。空樹也是一顆二叉搜尋樹 搜尋二叉搜尋樹的中序遍歷一定是乙個有序的資料集合。二叉搜尋樹的最左邊節點一定是最小的節點。二叉搜尋樹的最右邊節點一定是最大的節點。二叉搜尋樹的插入和刪除都必須先查詢,因此,查詢效率便代表了二叉搜尋樹中各個操作的效能。假設有乙個n個節點的二叉搜尋樹,若...

二叉搜尋樹 二叉搜尋樹

題目 二叉搜尋樹 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...

二叉搜尋樹 修剪二叉搜尋樹

第一反應是重構,看來別人的解答發現,其實不用重構那麼複雜。treenode trimbst treenode root,int low,int high if root val high 下一層處理完左子樹的結果賦給root left,處理完右子樹的結果賦給root right。root left ...