数据结构 查找 动态查找表一
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
(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
相关文章推荐
- 数据结构编程笔记二十五:第九章 查找 二叉排序树(动态查找表)查找算法的实现
- 数据结构_查找_动态查找表_二叉排序树
- 数据结构学习笔记 --- 查找(静态查找表)
- 数据结构中的查找算法-动态查找表(2)
- 数据结构学习笔记 --- 查找(静态查找表)
- 数据结构学习笔记 --- 二叉排序树和平衡二叉树(动态查找表)
- 数据结构--查找(静态查找表)
- 初学数据结构---动态查找之二叉排序树
- 数据结构大总结系列之折半查找与动态查找树
- 【查找--动态查找表】简单的二叉查找树(又称二叉排序树)
- 数据结构 查找 动态查找表二
- 数据结构 JAVA描述(十五) 动态查找表 二叉排序树 二叉平衡树
- 数据结构 查找 静态查找表
- 数据结构 JAVA描述(十六) 动态查找 B-树 B+树 红黑树
- 数据结构与算法之整体有序数组的查找
- 动态查找之平衡二叉树(AVL)
- 算法|动态查找
- 浅谈算法和数据结构: 平衡查找树之红黑树
- 【数据结构】静态查找之顺序查找
- 算法与数据结构基础1:C++实现动态数组