查詢之二叉排序樹(Binary Sort Tree)及其C實現
阿新 • • 發佈:2019-02-13
大話資料結構學習筆記 - 查詢之二叉排序樹(Binary Sort Tree
)及其C
實現
二叉排序樹
二叉排序樹(Binary Sort Tree
):又稱為 二叉查詢樹, 它或者是一個空樹,或者是具有下列性質的二叉樹
- 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值
- 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值
- 它的左、右子樹也分別為二叉排序樹
二叉排序樹主要是為了提高查詢和插入刪除關鍵字的速度
二叉樹結構
/* 二叉樹的二叉連結串列結點結構定義 */
typedef struct BiTNode /* 結點結構 */
{
int data; /* 結點資料 */
struct BiTNode *lchild, *rchild; /* 左右孩子指標 */
}BiTNode, *BiTree;
查詢
/*
* 遞迴查詢二叉排序樹 T 中是否存在 key, 指標 f 指向 T 的雙親, 其初始呼叫值是 NULL. 若查詢成功, 則指標 p 指向該資料元素結點, 並返回 TRUE
* 否則 指標 p 指向查詢路徑上訪問的最後一個結點並返回 FALSE
*
*/
Status SearchBST(BiTree T, int key, BiTNode *f, BiTNode **p)
{
if (!T) /* 查詢不成功 */
{
*p = f;
return FALSE;
}
else if(key == T->data) /* 查詢成功 */
{
*p = T;
return TRUE;
}
else if(key < T->data)
return SearchBST(T->lchild, key, T, p); /* 在左子樹中繼續查詢 */
else
return SearchBST(T->rchild, key, T, p); /* 在右子樹中繼續查詢 */
}
插入
/*
* 當二叉排序樹 T 中不存在關鍵字等於 key 的資料元素時, 插入 key 並返回 TRUE, 否則返回 FALSE
*/
Status InsertBST(BiTree *T, int key)
{
BiTNode *p, *s;
if(!SearchBST(*T, key, NULL, &p)) /* 查詢不成功 */
{
s = CreateBiTNode(key);
if(!p)
*T = s; /* 插入 s 為新的根節點 */
else if(key < p->data)
p->lchild = s; /* 插入 s 為左孩子 */
else
p->rchild = s; /* 插入 s 為右孩子 */
return TRUE;
}
return FALSE; /* 樹中已有關鍵字相同的結點, 不再插入 */
}
刪除
/*
* 從二叉排序樹中刪除節點 p, 並重接它的左或右子樹
*/
Status Delete(BiTNode **p)
{
BiTNode *q, *s;
if((*p)->lchild == NULL) /* 若右子樹為空,則只需重接它的左子樹 */
{
q = *p;
*p = (*p)->rchild;
free(q);
}
else if((*p)->rchild == NULL) /* 若左子樹為空,則只需重接它的右子樹 */
{
q = *p;
*p = (*p)->lchild;
free(q);
}
else /* 左右子樹均不空 */
{
q = *p;
s = (*p)->lchild; /* s 為其左子樹 */
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);
}
return TRUE;
}
/*
* 若二叉排序樹 T 中存在關鍵字等於 key 的資料元素時, 則刪除該資料元素結點, 並返回 TRUE; 否則返回 FALSE.
*/
Status DeleteBST(BiTree *T, int key)
{
if(!(*T)) /* 不存在關鍵字等於 key 的資料元素 */
return FALSE;
else if(key == (*T)->data) /* 找到關鍵字等於 key 的資料元素 */
return Delete(T);
else if(key < (*T)->data)
return DeleteBST(&(*T)->lchild, key);
else
return DeleteBST(&(*T)->rchild, key);
}
複雜度
若二叉排序樹比較平衡,即其深度與完全二叉樹相同,均為,類似於上圖左圖 那麼查詢的時間複雜度就為, 近似於折半查詢。若插入序列以排好序,則最壞情況類似於上圖右圖,時間複雜度為, 等同於順序查詢。
程式碼
結語
如上覆雜度分析,二叉排序樹的超照效能取決於二叉排序樹的形狀,但其形狀不確定,取決於輸入序列。如何構建一個平衡的二叉排序樹呢?請看下節文章 平衡二叉樹