您的位置:首页 > 理论基础 > 数据结构算法

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

2007-04-11 19:38 399 查看
动态查找表的特点:表结构本身实在查找过程中动态生成的,即对于给定值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[] = ...{45, 24, 53, 45, 12, 24, 90};






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[] = ...{4, 2, 1, 3, 5, 8, 4, 6};






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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: