二叉搜索樹

二叉搜索樹

經典的數據結構
二叉查找樹(BinarySearch Tree,也叫二叉搜索樹,或稱二叉排序樹BinarySort Tree)或者是一棵空樹,或者是具有下列性質的二叉樹:(1)若它的左子樹不為空,則左子樹上所有結點的值均小于它的根結點的值;(2)若它的右子樹不為空,則右子樹上所有結點的值均大于它的根結點的值;(3)它的左、右子樹也分别為二叉查找樹。[1]
  • 中文名:二叉搜索樹
  • 外文名:Binary Search Tree
  • 别名:
  • 表達式:
  • 提出者:
  • 适用領域:
  • 學科:計算機
  • 分類:二叉樹

查找過程

二叉排序樹的查找過程和次優二叉樹類似,通常采取二叉鍊表作為二叉排序樹的存儲結構。

中序遍曆二叉排序樹可得到一個關鍵字的有序序列,一個無序序列可以通過構造一棵二叉排序樹變成一個有序序列,構造樹的過程即為對無序序列進行排序的過程。每次插入的新的結點都是二叉排序樹上新的葉子結點,在進行插入操作時,不必移動其它結點,隻需改動某個結點的指針,由空變為非空即可。搜索,插入,删除的複雜度等于樹高,O(log(n)).

算法實現

1二叉排序樹的查找算法

2在二叉排序樹插入結點的算法

3在二叉排序樹删除結點的算法

4二叉排序樹性能分析

查找算法

在二叉排序樹b中查找x的過程為:

若b是空樹,則搜索失敗,否則:

若x等于b的根結點的數據域之值,則查找成功;否則:

若x小于b的根結點的數據域之值,則搜索左子樹;否則:

查找右子樹。

StatusSearchBST(BiTreeT,KeyTypekey,BiTreef,BiTree&*p){

//在根指針T所指二叉排序樹中遞歸地查找其關鍵字等于key的數據元素,若查找成功,

//則指針p指向該數據元素結點,并返回TRUE,否則指針指向查找路徑上訪問的最後

//一個結點并返回FALSE,指針f指向T的雙親,其初始調用值為NULL

if(!T){p=f;returnFALSE;}//查找不成功

elseifEQ(key,T->data.key){P=T;returnTRUE;}//查找成功

elseifLT(key,T->data.key)

returnSearchBST(T->lchild,key,T,p);//在左子樹中繼續查找

elsereturnSearchBST(T->rchild,key,T,p);//在右子樹中繼續查找

pascal語言實現

type

Link=^tree;

Tree=record

D:longint;

Left:link;

Right:link;

End;

functionsearch(n:longint;t:link):boolean;

Begin

Ift^.d

Ift^.right=nilthenexit(false)elseexit(search(n,t^.right));

End;

Ift^.d>nthenbegin

Ift^.left=nilthenexit(false)elseexit(search(n,t^.left));

End;

Exit(true);

End;

插入算法

向一個二叉排序樹b中插入一個結點s的算法,過程為:

若b是空樹,則将s所指結點作為根結點插入,否則:

若s->data等于b的根結點的數據域之值,則返回,否則:

若s->data小于b的根結點的數據域之值,則把s所指結點插入到左子樹中,否則:

把s所指結點插入到右子樹中。

/*當二叉排序樹T中不存在關鍵字等于e.key的數據元素時,插入e并返回TRUE,否則返回FALSE*/

StatusInsertBST(BiTree&T,ElemTypee)

{if(!SearchBST(T,e.key,NULL,p)

{s=(BiTree*)malloc(sizeof(BiTNode));

s->data=e;s->lchild=s->rchild=NULL;

if(!p)T-s;

//被插結點*s為新的根結點

elseifLT(e.key,p->data.key)p->lchld=s;

//被子插結點*s為左孩子

else->rchild=s;

//被插結點*s為右孩子

returnTRUE;}

else

returnFALSE;

樹中已有關鍵字相同的結點,不再插入}

pascal代碼:

procedurepush(n:longint;vart:link);

VarP,q:link;

Begin

Ift^.d

Ift^.right=nilthenbegin

New(p);

P^.d:=n;

P^.right:=nil;

P^.left:=nil;

T^.right:=p;

Endelsepush(n,t^.right);

Endelsebegin

Ift^.left=nilthenbegin

New(p);

P^.d:=n;

P^.right:=nil;

P^.left:=nil;

T^.left:=p;

Endelsepush(n,t^.left);End。

情況讨論

在二叉排序樹删去一個結點,分三種情況讨論:

若*p結點為葉子結點,即PL(左子樹)和PR(右子樹)均為空樹。由于删去葉子結點不破壞整棵樹的結構,則隻需修改其雙親結點的指針即可。

若*p結點隻有左子樹PL或右子樹PR,此時隻要令PL或PR直接成為其雙親結點*f的左子樹或右子樹即可,作此修改也不破壞二叉排序樹的特性。

若*p結點的左子樹和右子樹均不空。在删去*p之後,為保持其它元素之間的相對位置不變,可按中序遍曆保持有序進行調整,可以有兩種做法:其一是令*p的左子樹為*f的左子樹,*s為*f左子樹的最右下的結點,而*p的右子樹為*s的右子樹;其二是令*p的直接前驅(或直接後繼)替代*p,然後再從二叉排序樹中删去它的直接前驅(或直接後繼)。在二叉排序樹上删除一個結點的算法如下:

StatusDeleteBST(BiTree&T,KeyTypekey){

//若二叉排序樹T中存在關鍵字等于key的數據元素時,則删除該數據元素,并返回

//TRUE;否則返回FALSE

if(!T)returnFALSE;//不存在關鍵字等于key的數據元素

else{if(EQ(key,T->data.key)){returnDelete(T)};找到關鍵字等于key的數據元素

elseif(LT(key,T->data.key))returnDeleteBST(T->lchild,key);

elsereturnDeleteBST(T->rchild,key)}

StatusDelete(BiTree&p){//從二叉排序樹中删除結點p,并重接它的左或右子樹if(!p->rchild){//右子樹空則隻需重接它的左子樹q=p;p=p->lchild;free(q);}

elseif(!p->lchild){//左子樹空隻需重接它的右子樹q=p;p=p->rchild;free(q);}

else{//左右子樹均不空

q=p;

s=p->lchild;

while(s->rchild){

q=s;

s=s->rchild}//轉左,然後向右到盡頭

p->data=s->data;//s指向被删結點的“前驅”

if(q!=p)

q->rchild=s->lchild;//重接*q的右子樹

else

q->lchild=s->lchild;//重接*q的左子樹

free(s);}

returnTRUE

相關詞條

相關搜索

其它詞條