資料結構與演算法之二叉搜尋樹

2021-09-14 03:34:16 字數 3725 閱讀 4195

看到有個傢伙寫的很好:二叉查詢樹(二)之 c++的實現

二叉搜尋樹的定義:一棵二叉樹,可能為空;一棵非空的二叉搜尋樹滿足以下特徵:

每個元素有乙個關鍵字,並且任意兩個元素的關鍵字都不同,因此,所有的關鍵字都是唯一的。

在根節點的左子樹中,元素的關鍵字(如果有的話)都小於根節點的關鍵字。

在根節點的右子樹中,元素的關鍵字(如果有的話)都大於根節點的關鍵字。

根節點的左、右子樹也都是二叉搜尋樹。

索引二叉搜尋樹:源自普通二叉搜尋樹,只是在每個節點中新增乙個leftsize域。這個域的值是該節點左子樹的元素個數。

二叉搜尋樹的操作與實現:類binarysearchtree是從linkedbinarytree派生而來的。元素型別是乙個偶對pair,其中k是關鍵字型別,e是相應的元素的資料型別。

templateclass binarytree

virtual bool empty() const=0;

virtual int size() const=0;

virtual void preorder(void(*)(t*)) = 0;

virtual void inorder(void(*)(t*)) = 0;

virtual void postorder(void (*)(t*)) = 0;

virtual void levelorder(void (*)(t*)) =0;

}templateclass linkedbinarytree:public binarytree>

~linkedbinarytree()

bool empty() const

int size() const

void preorder(void(*thevisit)(binarytreenode*))

void inorder(void(*thevisit)(binarytreenode*))

void postorder(void (*thevisit)(binarytreenode*))

void levelorder(void(*)(binarytreenode*));

void erase()

private:

binarytreenode*root; //指向根的指標

int treesize;

static void (*visit)(binarytreenode*); //訪問函式

static void preorder(binarytreenode*t);

static void inorder(binarytreenode*t);

static void postorder(binarytreenode*t);

static void dispose(binarytreenode*t)

}

搜尋 :假設要查詢的關鍵字為thekey的元素。先從跟開始查詢。如果根為空的話,那麼二叉搜尋樹不包含任何元素,即查詢失敗。否則,將thekey與根的關鍵字進行比較,如果thekey的值小,那麼只需要查詢左子樹即可。如果thekey的值大,與之相反,只需要查詢右子樹即可。在子樹中的查詢類似。該過程的複雜度為o(h),h為樹的高度。

//二叉搜尋樹的查詢

templatepair* binarysearchtree::find(const k&thekey) const

return null;

}

插入:假設要在二叉搜尋樹中插入乙個新的元素thepair,首先要通過查詢來確定,在樹中是否存在某個元素,其關鍵字與thepair.first相同。若搜尋成功,那麼就用thepair.second替代該元素的值。如果搜尋不成功的話,就將新的元素作為搜尋中斷節點的孩子插入二叉搜尋樹。

//將乙個元素插入二叉搜尋樹

templatevoid binarysearchtree::insert(const pair& thepair)

else

}} //為thepair建立乙個節點,然後與pp鏈結

binarytreenode> *newnode = new binarytreenode>(thepair);

if(root !=null) //樹非空

else

root = newnode; //插入空樹

treesize++;

}

刪除:假設要刪除的節點是p,我們需要考慮三種情況:1)p是樹葉;2)p只有一棵非空子樹;3)p有兩棵非空子樹

要刪除的節點是葉子節點:處理方法是釋放該葉子節點空間,若是根節點,則令根為null。

要刪除的節點p只有一棵子樹:如果p沒有父節點(即p是根節點),則p的唯一子樹的根節點成為新的搜尋樹的根結點。如果p有父節點pp,則修改pp的指標域,使得它指向p的唯一的孩子,然後釋放節點p。

要刪除的節點p具有兩棵非空子樹:我們先將該節點的元素替換為它的左子樹的最大元素或者右子樹的最小元素,然後將替換元素的節點刪除。注:右子樹的最小關鍵子節點(左子樹的最大關鍵字節點)要麼沒有子樹,要麼只有一棵子樹。要在乙個節點的左子樹中查詢關鍵字最大的元素,先移動到左子樹的根,然後沿著右孩子指標移動,直到右孩子指標為null節點為止。類似地,要在乙個節點地右子樹查詢關鍵字最小地元素,先移動到右子樹地根節點,然後沿著左孩子指標移動,直到左孩子指標為null的節點為止。要刪除乙個左右子樹都不為空的元素節點,我們的演算法是:先替換,然後刪除乙個葉子或者乙個僅有單子樹的節點。

以下**實現了刪除演算法。在刪除乙個具有兩個非空子樹的元素時,該程式總是用其左子樹的最大元素進行替換。

//二叉搜尋樹的刪除

templatevoid binarysearchtree::erase(const k& thekey)

if(p== null)

return; //不存在與關鍵字匹配的數對

//重新組織樹結構

//當p有兩個孩子時

if(p->leftchild != null && p->rightchild!=null)

//將最大元素s移到p,但不是簡單的移動

binarytreenode> *q = new binarytreenode>(s->element,p->leftchild,p->rightchild);

if(pp==null)

root = q;

else if(p == pp->leftchild) //如果當前要刪除的節點是其父節點的左子節點

pp->leftchild =q;

else //如果當前要刪除的節點是其父節點的右子節點

pp->rightchild = q;

if(ps ==p) //如果當前要刪除的節點是最大元素的父節點

pp=q;

else

pp=ps;

delete p;

p=s;

} //p最多有乙個孩子

//把孩子指標存放在c

binarytreenode> *c ;

if(p->leftchild !=null)

c = p->leftchild;

else

c = p->rightchild;

//刪除p

if(p==root)

root = c;

else

treesize --;

delete p;

}

演算法與資料結構之二叉搜尋樹

搜尋樹與二叉搜尋樹 搜尋樹是一種可以進行插入 搜尋 刪除等操作的資料結構。它可以用作字典或者優先順序佇列。二叉搜尋樹是最基本的搜尋樹。它的各個結點都有鍵值,並且滿足以下的條件 設x是二叉搜尋樹中的結點,y是它的左子樹中的結點,那麼,y的鍵值 x的鍵值。根據這一特點,我們就能實現一棵二叉搜尋樹。二叉搜...

資料結構之二叉搜尋樹

什麼是二叉搜尋樹呢?它與別的資料結構相比其優勢又是什麼呢?一顆二叉搜尋樹就是以一顆二叉樹來組織和儲存資料的,如圖所示 圖a是包含6個節點 高度為2的二叉樹,圖b是包含相同關鍵字 高度為4的低效二叉樹 對比博文前面所介紹的鍊錶,二叉樹也是可以用結構體來實現,只不過每個節點裡面不僅要儲存資料本身的關鍵字...

資料結構與演算法之二叉樹

樹同時具有鍊錶和陣列的優點,關於樹的術語有 根 樹頂端的節點 葉子節點 沒有子節點的節點 樹那個節點所對應的資料結構 節點物件類,包含資料 public class node 將資料插到樹中 public void inser int id,double dd public boolean dele...