数据结构 查找 动态查找表一

本文详细介绍了二叉查找树与平衡二叉树的基本概念、特点及操作实现,包括查找、插入、删除等核心算法,并通过具体示例展示了它们的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   动态查找表的特点:表结构本身实在查找过程中动态生成的,即对于给定值key,若表中存在关键字等于key的记录,则查找成功返回,否则插入关键字等于key的记录。

(1)二叉排序树(binary sort tree,或二叉查找树)

中序遍历二叉树可以得到一个关键字的有序序列。构造树的过程即是对无序序列进行排序的过程。当先后插入的关键字有序时,构成的二叉排序树蜕变为单枝树。在随机的情况下,二叉排序树的平均查找长度和logn是等量的。

插入、删除、查找代码:

#define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
#define LQ(a, b) ((a) <= (b))

typedef 
int KeyType;

typedef 
struct {
    KeyType key;
}
ElemType;

//binary tree node
typedef struct BNode{
    ElemType data;
    
struct BNode *left;
    
struct BNode *right;
}
BNode, *BTree;

源文件:

#include "dsearch.h"
#include 
"stdio.h"
#include 
"stdlib.h"

/**
 * search the binary search tree
 * if find it, p point to it,
 * if not find, p point to the last of the path.
 * f is the parent of tree.
 
*/

bool searchBST(BTree tree, KeyType key, BTree f, BTree &p){
    
if(!tree){
        p 
= f;
        
return 0;
    }
else{
        
if(EQ(tree->data.key, key)){
            p 
= tree;
            printf(
"find %d ", key);
            
return 1;
        }
else{
            
if(LT(key, tree->data.key)){
                
return searchBST(tree->left, key, tree, p);
            }
else{
                
return searchBST(tree->right, key, tree, p);
            }

        }

    }

}


//insert the node
bool insertBST(BTree &T, ElemType e){
    BTree p;
    
if(!searchBST(T, e.key, NULL, p)){
        BTree s 
= (BTree)malloc(sizeof(BNode));
        s
->data = e;
        s
->left = s->right = NULL;
        
if(!p){
            T 
= s;
        }
else{
            
if(LT(e.key, p->data.key)){
                p
->left = s;
            }
else{
                p
->right = s;
            }

        }

        printf(
"insert %d ", e.key);
        
return 1;
    }
else{
        
return 0;
    }

}


int deleteNode(BTree &p){
    BTree q, s;
    
if(!p->right){
        printf(
"%d's right is null, delete %d ", p->data, p->data);
        q 
= p;
        p 
= p->left;
        free(q);
    }
else{
        
if(!p->left){
            printf(
"%d's left is null, delete %d ", p->data, p->data);
            q 
= p;
            p 
= p->right;
            free(q);
        }
else{
            
//both the left and right are not null
            printf("%d's left and right are not null, delete %d ", p->data, p->data);
            q 
= p;
            s 
= p->left;
            
while(s->right){
                q 
= s;
                s 
= s->right;
            }

            p
->data = s->data;

            
if(q != p){
                q
->right = s->left;
            }
else{
                q
->left = s->left;
            }


            free(s);
            
        }

    }

    
return 1;
}


//delete a node
int deleteBST(BTree &T, KeyType key){
    
if(!T){
        
return 0;
    }
else{
        
if(EQ(key, T->data.key)){
            
return deleteNode(T);
        }
else{
            
if(LT(key, T->data.key)){
                
return deleteBST(T->left, key);
            }
else{
                
return deleteBST(T->right, key);
            }

        }

        
return 1;
    }

}


void main(){
    
/**
     * when use this stmt: BTree tree;
     * program will run error, why?
     * see the first stmt of searchBST.
     
*/

    BTree tree 
= NULL;
    ElemType e;
    
int w[] = {45245345122490};

    
for(int i = 0; i < 7; i++){
        e.key 
= w[i];
        insertBST(tree, e);
    }


    deleteBST(tree, 
24);
    deleteBST(tree, 
53);
    deleteBST(tree, 
45);
}

程序的执行结果:

insert 45
insert 
24
insert 
53
find 
45
insert 
12
find 
24
insert 
90
24's right is null, delete 24
53's left is null, delete 53
45's left and right are not null, delete 45

(2)平衡二叉树

左右子树的深度之差的绝对值不超过1。

结论:

a. 无论哪种情况,在经过平衡旋转处理之后,以*b或者*c为根的新子树为平衡二叉树,而且它的深度和插入之前以*a为根的子树相同。

b. 当平衡的二叉树因为插入新的节点而失去平衡时,只需要调整最小不平衡子树即可。

c.在平衡树上进行查找的时间复杂度为O(log(n))。

头文件:

#define EQ(a, b) ((a) == (b))
#define LT(a, b) ((a) < (b))
#define LQ(a, b) ((a) <= (b))

#define LH 1
#define EH 0
#define RH -1

typedef 
int KeyType;

typedef 
struct {
    KeyType key;
}
ElemType;

//binary tree node
typedef struct BSTNode{
    ElemType data;
    
//the balance factor
    int bf;
    
struct BSTNode *left;
    
struct BSTNode *right;
}
BSTNode, *BSTree;

源文件:

#include "avl.h"
#include 
"stdio.h"
#include 
"stdlib.h"

void r_rotate(BSTree &p){
    BSTree lc 
= p->left;
    p
->left = lc->right;
    lc
->right = p;
    p 
= lc;
}


void l_rotate(BSTree &p){
    BSTree rc 
= p->right;
    p
->right = rc->left;
    rc
->left = p;
    p 
= rc;
}


void leftBalance(BSTree &T){
    BSTree lc 
= T->left;
    
switch(lc->bf){
    
case LH:
        printf(
"right ");
        T
->bf = lc->bf = EH;
        r_rotate(T);
        
break;
    
case RH:
        printf(
"left right ");
        BSTree rd 
= lc->right;
        
switch(rd->bf){
        
case LH:
            T
->bf = RH;
            lc
->bf = EH;
            
break;
        
case EH:
            T
->bf = lc->bf = EH;
            
break;
        
case RH:
            T
->bf = EH;
            lc
->bf = LH;
            
break;
        }

        rd
->bf = EH;
        l_rotate(T
->left);
        r_rotate(T);
        
break;        
    }

}


void rightBalance(BSTree &T){
    BSTree rc 
= T->right;
    
switch(rc->bf){
    
case RH:
        printf(
"left ");
        T
->bf = rc->bf = EH;
        l_rotate(T);
        
break;
    
case LH:
        printf(
"right left ");
        BSTree ld 
= rc->left;
        
switch(ld->bf){
        
case RH:
            T
->bf = LH;
            rc
->bf = EH;
            
break;
        
case EH:
            T
->bf = rc->bf = EH;
            
break;
        
case LH:
            T
->bf = EH;
            rc
->bf = RH;
            
break;
        }

        ld
->bf = EH;
        r_rotate(T
->right);
        l_rotate(T);
        
break;        
    }

}


/**
 * if e does not exists in t, insert it and return 1, 
 * ortherwise return 0;
 * taller: is the tree get higher?
 
*/

int insertAVL(BSTree &T, ElemType e, int &taller){
    
if(!T){
        
//insert the new node
        printf("insert a new node:%d ", e.key);
        T 
= (BSTree)malloc(sizeof(BSTNode));
        T
->data = e;
        T
->left = T->right = NULL;
        T
->bf = EH;
        taller 
= 1;
    }
else{
        
//there is the same key in the tree, need no insert.
        if(EQ(e.key, T->data.key)){
            printf(
"the node %d is in the tree ", e.key);
            taller 
= 0;
            
return 0;
        }


        
//insert in the left of t
        if(LT(e.key, T->data.key)){
            
//not insert
            if(!insertAVL(T->left, e, taller)){
                
return 0;
            }


            
if(taller){
                
switch(T->bf){
                
case LH:
                    
//left was higher than right, and 
                    
//insert in the left, no balance again.
                    leftBalance(T);
                    taller 
= 0;
                    
break;
                
case EH:
                    T
->bf = LH;
                    taller 
= 1;
                    
break;
                
case RH:
                    T
->bf = EH;
                    taller 
= 0;
                    
break;
                }

            }

        }
else{
            
//insert in the right of t

            
//not insert.
            if(!insertAVL(T->right, e, taller)){
                
return 0;
            }


            
if(taller){
                
switch(T->bf){
                
case LH:
                    T
->bf = EH;
                    taller 
= 0;
                    
break;
                
case EH:
                    T
->bf = RH;
                    taller 
= 1;
                    
break;
                
case RH:
                    rightBalance(T);
                    taller 
= 0;
                    
break;
                }

            }

        }

    }

    
return 1;
}


void main(){
    BSTree tree 
= NULL;
    ElemType e;
    
int taller;
    
int w[] = {42135846};
    
    
for(int i = 0; i < 8; i++){
        e.key 
= w[i];
        insertAVL(tree, e, taller);
    }

}

程序执行结果如下:

insert a new node:4
insert a 
new node:2
insert a 
new node:1
right
insert a 
new node:3
insert a 
new node:5
insert a 
new node:8
left
the node 
4 is in the tree
insert a 
new node:6
right left
Press any key to 
continue

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值