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

   动态查找表的特点:表结构本身实在查找过程中动态生成的,即对于给定值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

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值