BST二叉排序樹的查詢和刪除的完整C程式碼
二叉排序樹的查詢演算法
假定二叉排序樹的根節點指標為root,給定的關鍵字值為key,則查詢演算法可描述為:
- 置初值:p = root ;
- 如果 key = p -> data ,則查詢成功,演算法結束;
- 否則,如果key < p->data ,而且 p 的左子樹非空,則將 p 的左子樹根送 p ,轉步驟 2 ;否則,查詢失敗,演算法結束;
- 否則,如果 key > p->data ,而且 p 的右子樹非空,則將 p 的右子樹根送 p ,轉步驟 2 ;否則,查詢失敗,演算法結束。
//BST的遞迴查詢 void SearchBST( BiTree t, Elemtype key ) { BiTree p; p = t; if( p ) { if( key == p->data ) printf("查詢成功!\n"); else if( (key < p->data) && (NULL != p->lchild) ) SearchBST( p->lchild , key ); else if( (key > p->data) && (NULL != p->rchild) ) SearchBST( p->rchild , key ); else printf("無此元素!\n"); } }
//BST的迭代查詢
void _SearchBST( BiTree t, Elemtype key )
{
BiTree p;
p = t;
while( NULL != p && key != p->data ) {
if( key < p->data )
p = p->lchild ;
else
p = p->rchild ;
}
if( NULL != p )
printf("查詢成功!\n");
else
printf("無此元素!\n");
}
二叉排序樹上結點的刪除演算法
假設要刪除的結點為 p ,結點 p 的雙親結點為 q ,下面分三種情況討論:
- 若 p 為葉子結點,則可直接將其刪除:
//情況1:結點p的雙親結點為q,且p為葉子結點,則直接將其刪除。 if( NULL == p->lchild && NULL == p->rchild ) { if( p == q->lchild ) q->lchild = NULL; if( p == q->rchild ) q->rchild = NULL; free(p); p = NULL; }
- 若 p 結點只有左子樹,或只有右子樹,則可將 p 的左子樹或右子樹直接改為其雙親結點 q 的左子樹或右子樹:
//情況2:結點p的雙親結點為q,且p只有左子樹或只有右子樹,則可將p的左子樹或右子樹直接改為其雙親結點q的左子樹或右子樹。 else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子樹 if( p == q->lchild ) q->lchild = p->lchild ; else if( p == q->rchild ) q->rchild = p->lchild ; free(p); p = NULL; } else if( NULL == p->lchild && NULL != p->rchild ) { //p只有右子樹 if( p == q->lchild ) q->lchild = p->rchild ; if( p == q->rchild ) q->rchild = p->rchild ; free(p); p = NULL; }
- 若 p 既有左子樹,又有右子樹。則先儲存p 結點的直接前驅(或直接後繼)s 的 data ,然後再從二叉排序樹中刪除 s ,最後將儲存起來的 s 結點的 data 賦值給 p 的 data 。
該步驟難點在於準確理解 p 結點的直接前驅或直接後繼的概念。
這裡的 p 的直接前驅是指BST的中序遍歷序列中,緊挨在 p 結點之前一個的結點 s ,在BST中,s 位於 p 結點的左子樹的最右下方,用 s 的資料代替 p 的資料,該二叉樹依然是一個二叉排序樹。
同理,p 的直接後繼是指BST的中序遍歷序列中,緊挨在 p 結點之後一個的結點 s , 在BST中, s 位於 p 結點的右子樹的最左下方,用 s 的資料代替 p 的資料,該二叉樹依然是一個二叉排序樹。//情況3:結點p的雙親結點為q,且p既有左子樹又有右子樹。本程式碼使用直接前驅(也可以直接後繼) else if( NULL != p->lchild && NULL != p->rchild ) { BiTree s, sParent; sParent = p; s = sParent->lchild ; while( NULL != s->rchild ) { //找到p的直接前驅 sParent = s; s = s->rchild ; } temp = s->data ; DelBSTNode( t, temp ); p->data = temp; }
BST查詢和刪除結點的完整C程式碼
/* 二叉排序樹的查詢演算法的C程式碼實現 */
#include <stdio.h>
#include <stdlib.h>
typedef int Elemtype;
typedef struct BiTNode{
Elemtype data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
//在給定的BST中插入結點,其資料域為element
void BSTInsert( BiTree *t, Elemtype element )
{
if( NULL == *t ) {
(*t) = (BiTree)malloc(sizeof(BiTNode));
(*t)->data = element;
(*t)->lchild = (*t)->rchild = NULL;
}
if( element == (*t)->data )
return ;
else if( element < (*t)->data )
BSTInsert( &(*t)->lchild, element );
else
BSTInsert( &(*t)->rchild, element );
}
//建立BST
void CreateBST( BiTree *t, Elemtype *a, int n )
{
(*t) = NULL;
for( int i=0; i<n; i++ )
BSTInsert( t, a[i] );
}
//BST的遞迴查詢
void SearchBST( BiTree t, Elemtype key )
{
BiTree p;
p = t;
if( p ) {
if( key == p->data )
printf("查詢成功!\n");
else if( (key < p->data) && (NULL != p->lchild) )
SearchBST( p->lchild , key );
else if( (key > p->data) && (NULL != p->rchild) )
SearchBST( p->rchild , key );
else
printf("無此元素!\n");
}
}
//BST的迭代查詢
void _SearchBST( BiTree t, Elemtype key )
{
BiTree p;
p = t;
while( NULL != p && key != p->data ) {
if( key < p->data )
p = p->lchild ;
else
p = p->rchild ;
}
if( NULL != p )
printf("查詢成功!\n");
else
printf("無此元素!\n");
}
//BST結點的刪除
void DelBSTNode( BiTree t, Elemtype key )
{
BiTree p, q;
p = t;
Elemtype temp;
while( NULL != p && key != p->data ) {
q = p;
if( key < p->data )
p = p->lchild ;
else
p = p->rchild ;
}
if( NULL == p )
printf("無此元素!\n");
else {
//情況1:結點p的雙親結點為q,且p為葉子結點,則直接將其刪除。
if( NULL == p->lchild && NULL == p->rchild ) {
if( p == q->lchild )
q->lchild = NULL;
if( p == q->rchild )
q->rchild = NULL;
free(p);
p = NULL;
}
//情況2:結點p的雙親結點為q,且p只有左子樹或只有右子樹,則可將p的左子樹或右子樹直接改為其雙親結點q的左子樹或右子樹。
else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子樹
if( p == q->lchild )
q->lchild = p->lchild ;
else if( p == q->rchild )
q->rchild = p->lchild ;
free(p);
p = NULL;
}
else if( NULL == p->lchild && NULL != p->rchild ) { //p只有右子樹
if( p == q->lchild )
q->lchild = p->rchild ;
if( p == q->rchild )
q->rchild = p->rchild ;
free(p);
p = NULL;
}
//情況3:結點p的雙親結點為q,且p既有左子樹又有右子樹。本程式碼使用直接前驅(也可以直接後繼)
else if( NULL != p->lchild && NULL != p->rchild ) {
BiTree s, sParent;
sParent = p;
s = sParent->lchild ;
while( NULL != s->rchild ) { //找到p的直接前驅
sParent = s;
s = s->rchild ;
}
temp = s->data ;
DelBSTNode( t, temp );
p->data = temp;
}
}
}
//中序遍歷列印BST
void PrintBST( BiTree t )
{
if( t ) {
PrintBST( t->lchild );
printf("%d ", t->data);
PrintBST( t->rchild );
}
}
int main()
{
int n;
int *a;
Elemtype key;
BiTree t;
printf("請輸入二叉查詢樹的結點數:\n");
scanf("%d", &n);
a = (int *)malloc(sizeof(int)*n);
printf("請輸入二叉找樹的結點資料:\n");
for( int i=0; i<n; i++ )
scanf("%d", &a[i]);
CreateBST( &t, a, n );
printf("當前二叉查詢樹的中序遍歷結果為:\n");
PrintBST( t );
printf("\n##############################################\n");
printf("請輸入要查詢的元素:\n");
scanf("%d", &key);
printf("BST遞迴查詢結果:\n");
SearchBST( t, key ); //遞迴查詢
printf("##############################################\n");
printf("請輸入要刪除的元素:\n");
scanf("%d", &key);
DelBSTNode( t, key );
printf("當前二叉查詢樹的中序遍歷結果為:\n");
PrintBST( t );
printf("\n##############################################\n");
printf("請輸入要查詢的元素:\n");
scanf("%d", &key);
printf("BST迭代查詢結果:\n");
_SearchBST( t, key ); //迭代查詢
return 0;
}
測試資料以及測試結果
9個元素:5 8 2 1 4 7 9 6 3
生成的BST:
測試結果:
測試通過。
相關推薦
BST二叉排序樹的查詢和刪除的完整C程式碼
二叉排序樹的查詢演算法 假定二叉排序樹的根節點指標為root,給定的關鍵字值為key,則查詢演算法可描述為: 置初值:p = root ;如果 key = p -> data ,則查詢成功,演算法結束;否則,如果key < p->data ,而且 p 的
索引順序表查詢和二叉排序樹查詢
二叉排序樹(BST)的定義為:二叉排序樹或者是空樹,或者是滿足下列性質的二叉樹: (1) :若左子樹不為空,則左子樹上所有結點的值(關鍵字)都小於根結點的值; (2) :若右子樹不為空,則右子樹上所有結點的值(關鍵字)都大於根結點的值; (3) :左、右子樹都分別是二叉
C++實現二叉排序樹BSTree --插入刪除摧毀查詢等操作
#ifndef _BSTREE_H #define _BSTREE_H #include <iostream> #include <assert.h> using namespace std; template <typename T> class BSTree; t
程式設計基礎79 給定二叉排序樹結構和陣列求整棵樹
1099 Build A Binary Search Tree (30 分) A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: T
二叉排序樹查詢演算法之php實現
二叉排序樹,又稱為二叉查詢樹。它或者是一棵空樹,或者是具有下列性質的二叉樹。 1.若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值 2.若它的右子樹不空,則右子樹上所有結點的值均小於它
二叉排序樹查詢效率最高的是哪個?
1.平衡二叉樹:它是一棵空樹或者它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。 如上圖:平衡二叉樹 2.二叉查詢樹:二叉排序樹,又稱二叉查詢樹,或者稱為二叉搜尋樹。
BST二叉搜尋樹(查詢樹)實現 程式碼+詳解(C/C++)
寫了一下午,終於把這個整理完了,也相當於複習了一波資料結構吧。。。 概念 二叉查詢樹(Binary Search Tree),又被稱為二叉搜尋樹,二叉排序樹。 為什麼叫二叉查詢樹呢,因為它一般的樹不同,它具有如下性質 若它的左子樹不空,則左子樹上所有結點的
手寫二叉排序樹(查詢樹、搜尋樹)
二叉排序樹(查詢樹,搜尋樹)或者是一顆空樹,或者是一顆具有如下性質的樹: 1)若左子樹不為空,那麼左子樹上面的所有節點的關鍵字值都比根節點的關鍵字值小 2)若右子樹不為空,那麼右子樹上面的所有節點的關鍵字值都比根節點的關鍵字值大 3)左右子樹都為二叉樹 4)沒有重複值(這一點在實際中可以忽略)
查詢-二叉排序樹查詢
二叉排序樹的性質: (1)若某節點的左子樹非空,則左子樹上所有元素的值都小於該元素的值。 (2)若某節點的右子樹非空,則右子樹上所有元素的值都大於該元素的值。 問題:在二叉排序樹種,原則上各元素關
二叉排序樹的結點刪除
8 3 9 2 6 10 1 4 7 5 上面是1到10的二叉排序樹。 如何實現二叉排序樹的節點刪除呢?假設我們刪除結點6,先尋找前驅結點或者後繼節點,6的前驅結點是5,後繼是7,想象一下
資料結構 折半遞迴查詢,二叉排序樹查詢
實驗題目: 查詢演算法實現與分析 實驗環境: Visual C++ 6.0 實驗專案七:查詢演算法實現與分析 實驗目的:1.掌握順序表的查詢方法,尤其是二分查詢方法。
查詢之二叉排序樹(Binary Sort Tree)及其C實現
大話資料結構學習筆記 - 查詢之二叉排序樹(Binary Sort Tree)及其C實現 二叉排序樹 二叉排序樹(Binary Sort Tree):又稱為 二叉查詢樹, 它或者是一個空樹,或者是具有下列性質的二叉樹 若它的左子樹不空,則左子樹上
java實現順序查詢、二分查詢、雜湊表查詢、二叉排序樹查詢
順序查詢、二分查詢、雜湊表查詢、二叉排序樹查詢這幾種查詢演算法是面試中常被問到的幾種演算法。 1. 順序查詢 對於陣列,按順序比較給定的值,時間複雜度0(n),,以下是實現: public static int Linear_Search(int[] data, i
二叉排序樹基本功能實現(C++)
二叉排序樹(Binary Sort Tree )也稱二叉搜尋樹(Binary Search Tree),以下簡稱BST。 它的特點是左小右大(左子樹小於根,右子樹大於根),令人困惑的是他不允許相等存在,一定要分個高低。這個特點與二叉堆排序有所不同,堆是允許存在相同關鍵字
二叉排序樹的操作(建立、插入、刪除和查詢)
二叉排序樹的建立、插入、刪除和查詢 #include <stdio.h> #include <stdlib.h> typedef struct node { int key; struct node *lchild,*rchild
【資料結構樹表的查詢】二叉排序樹詳解和程式碼(生成、插入、查詢、最大值、最小值、刪除、中序遍歷、銷燬)
二叉排序樹(簡稱BST)又稱二叉查詢(搜尋)樹,其定義為:二叉排序樹或者是空樹,或者是滿足如下性質的二叉樹: (1)若它的左子樹非空,則左子樹上所有記錄的值均小於根記錄的值; (2)若它的右子樹非空,則右子樹上所有記錄的值均大於根記錄的值;
查詢(3)——二叉排序樹的建立、結點的查詢和刪除
#include <stdio.h> #include <stdlib.h> typedef struct node{ int data; node * lchild; node * rchild; }BTree
二叉排序樹(二叉查詢樹)BST構造,節點插入,節點查詢,節點刪除(java)
二叉排序樹(BST)的構造,節點插入,節點查詢,節點刪除(java) 高度最小BST(同樣資料,順序可能不一樣) package ccnu.offer.tree; import java.util.ArrayList; import java.ut
BST(二叉排序樹)的插入與刪除
最小值 temp def oot gpo 一個 記錄 通過 如果 值得一說的是刪除操作,刪除操作我們分為三種情況: 1.要刪的節點有兩個孩子: 找到左子樹中的最大值或者右子樹中的最小值所對應的節點,記為node,並把node的值賦給要刪除的節點del,然後刪除node
【模板】二叉搜尋樹(二叉排序樹,二叉查詢樹,BST)
二叉搜尋樹其實就是滿足左結點小於根,右結點大於根這類規則的樹形結構。 1 int n; 2 int a[MAX_N]; 3 int lt[MAX_N], rt[MAX_N]; 4 // 沒有則為-1 5 // 預設a[0]為根結點 6 7 void Insert(int