二叉搜尋樹

2021-08-19 18:12:48 字數 2786 閱讀 1285

以下皆用下面這棵樹作為藍本

二叉搜尋樹是資料結構中的重要搜尋結構,相比順序結構來說複雜度較低,當需要在海量資料中尋找資料時很有優勢。相比雜湊等結構來說沒有雜湊因為需要避免雜湊衝突從而浪費的空間。而且二叉搜尋樹對於新手來說便於理解樹形結構。可是二叉搜尋樹相比平衡樹與紅黑樹來說複雜度為o(n)較高,體現在二叉搜尋樹容易形成高度很高的樹。

接下來為二叉搜尋數的基本介面實現。由於較為簡單,我們用遞迴與非遞迴兩種方式來實現。

我們這裡選用二叉鏈,二叉鏈相比三叉鏈維護成本低,較容易控制。三叉鏈在實現介面時容易實現,各有優勢。

先定義二叉搜尋樹的結構

typedef struct bstreenode

bstreenode;

建立搜尋二叉樹的節點
bstreenode* buybstreenode(datatype x)

列印該樹,這裡用的中序的邏輯,先走左子樹再列印根節點然後在走右子樹,不斷遞迴從而中序列印整棵樹。

void bstreeprint(bstreenode* tree)

bstreeprint(tree->_left);

printf("%d ", tree->_data);

bstreeprint(tree->_right);

}

接下來為非遞迴版本的介面實現

非遞迴插入。當為空樹時,直接創造乙個新的節點。當不為空樹時,通過不斷迭代與根節點比較從而找到插入的位置。這裡接下來有兩種情況,當需要插入的資料已經存在時,插入失敗,返回0.當插入的資料不存在時,建立節點鏈結上乙個父親節點。返回1插入成功。

int bstreeinsert(bstreenode** tree, datatype x)

while (str)

if (str->_data < x)

else

}if (prev->_data < x)

else

return 1;

}

非遞迴查詢。通過與根節點比較從而不斷迭代直到找到資料位置,若資料存在返回該節點,不存在則返回空。
const bstreenode* bstreefind(bstreenode* tree, datatype x)

if (str->_data < x)

else

}return null;

}

非遞迴刪除。先通過與根節點比較從而找到需要刪除的資料節點位置。然後分為三種情況。

1.目標節點無子樹

2.目標節點只有左子樹

3.目標節點只有右子樹

4.目標節點既有左子樹又有右子樹

第一種情況可以看做第二種或者第三種情況的一種,第二種情況我們只需要將目標節點的右子樹連線到目標節點的父親節點即可。然後刪除目標節點。第三種情況與第二種情況邏輯相同。第四種情況我們可以先從目標節點開始,找到左子樹的最右或者右子樹的最左,讓目標節點的資料等於該值,再將左子樹的最右或者右子樹的最左刪除即可,刪除方法與第二種或者第三種情況類似。需要注意的是,當目標節點與父親節點相同時,不會進入迴圈。分情況討論。

int bstreeremove(bstreenode** tree, datatype x)

if (parents->_right == str)

}else if (str->_right == null)//目標數右子數

if (parents->_right == str)

}else//左子樹與右子數均不為空

if (cur == str)

else

}} parents = str;

if (str->_data < x)

else

}return 0;

}

銷毀樹。這裡用後序的邏輯,先走左子樹再走右子樹,然後銷毀根節點,直到整棵樹為空樹即可
void bstreedestory(bstreenode* tree)

bstreedestory(tree->_left);

bstreedestory(tree->_right);

tree->_left = null;

tree->_right = null;

free(tree);

}

接下來是遞迴版本的插入查詢刪除

遞迴插入。這裡由於是二級指標所以直接返回下乙個節點就鏈上了

int bstreeinsertr(bstreenode** tree, datatype x)

else if ((*tree)->_data == x)

else

else}}

遞迴查詢
const bstreenode* bstreefindr(bstreenode* tree, datatype x)

else

else

}return null;

遞迴刪除。邏輯與非遞迴相同
int bstreeremover(bstreenode** tree, datatype x)

else if ((*tree)->_data > x)

else

else if ((*tree)->_right == null)

else

if (parents == *tree)

else}}}

本文僅實現了二叉搜尋樹的基礎介面,更為複雜的介面留作後面部落格討論。

二叉搜尋樹 二叉搜尋樹

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

樹 二叉樹 二叉搜尋樹

給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 13輸出 true 示例 2 輸入 5 14 3 6輸出 false 解釋 輸入為 ...