开放寻址:hashFunc(data,step);就是在hashFunc(data)得到的哈希值的基础上加step,NULL就插入,!NULL则step++,插入与查找,step初始值与步长相同
二度哈希:和开放寻址类似,只不过在hashFunc(data)上加的是hashFunc2(data),因为加的是哈希值可以避免一整块的槽都是!NULL时需要一直查找到底,hashFunc(data) =
hashFunc1(data) + i * hashFunc2(data); (i>=0)
全域哈希:本来还纠结如何查找的问题,后来才明白,是你拿了一堆哈希函数,每次构建一张哈希表,随便挑一个函数,不至于每次都用到哈希效果最差的函数构建表,不同的表是不同的函数,但随机选择,在构造表之前,没法预测用哪个函数。证明:不会
完美哈希:其实与链表方法类似,就是将链表换成了小一号的哈希表,由链表首到链表尾逐个添加得到冲突的方式,改为了用二度哈希获取一个键值插入第二个哈希表,由于首次哈希和二度哈希所用的哈希函数是随机选择且不同,而且数据必须为静态,因此可以不冲突,但有点感觉不实用啊,这只是个人的拙见愿闻指教。
二叉搜索树
int a[] = {1,3,2,4,6,17,44,6,8,89};
int c[1000];
void walk(int *a,int n)
{
if(a[2*n+1] > 0)
walk(a,2*n+1);
cout<<a[n]<<" ";
if(a[2*(n+1)] > 0)
walk(a,2*(n+1));
}
int Search(int *a,int data,int root)
{
int n = root;
if(a[n] == 0)
return -1;
if(data < a[n])
return Search(a,data,2*n+1);
else if(data == a[n])
return n;
else
return Search(a,data,2*(n+1));
}
int Insert(int *a,int data,int root)
{
int n = root;
if(a[n] == 0)
{
a[n] = data;
return n;
}
if(data < a[n])
return Insert(a,data,2*n+1);
else
return Insert(a,data,2*(n+1));
}
void Swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int bst(int *a,int l,int h,int n)
{
if(l <= h)
{
int i,j;
for(i=l+1,j=l+1;i<=h;++i)
{
if(a[i] < a[l])
Swap(&a[i],&a[j++]);
}
Swap(&a[j-1],&a[l]);
c[n] = a[j-1];
bst(a,l,j-2,2*n+1);
bst(a,j,h,2*(n+1));
}
}
int Max(int *a,int root)
{
int n = root;
if(a[2*(n+1)] == 0)
return a[n];
else
return Max(a,2*(n+1));
}
int Mini(int *a,int root)
{
int n = root;
if(a[2*n+1] == 0)
return a[n];
else
return Mini(a,2*n+1);
}
int main()
{
bst(a,0,9,0);
/*
for(int i=0;i<1000;++i)
{
if(c[i] != 0)
cout<<"val "<<c[i]<<" "<<i+1<<endl;
}*/
cout<<"中序遍历"<<endl;
walk(c,0);
cout<<endl<<endl;
cout<<"search"<<endl;
cout<<"search 6 "<<Search(c,6,0)<<endl;
cout<<"search 44 "<<Search(c,44,0)<<endl;
cout<<"search 666 "<<Search(c,666,0)<<endl<<endl;
cout<<"Insert 45"<<endl;
cout<<Insert(c,45,0)<<endl;
walk(c,0);
cout<<endl<<endl;
cout<<"MINI "<<Mini(c,0)<<endl;
cout<<"MAX "<<Max(c,0)<<endl;
//树状数组没法Delete 只要Search到 调整节点关系
return 0;
}
BST 与 RBT 完整代码
RBT 靠 红父为黑 红子为黑 维持树高 olgn 因此建树 拿出来一个设置RED 插进去 调整
具体的fixup 分三种情况 可以看到到达第三种情况就结束了
而 经过第二种情况 一定会达到第三种情况
而第二 第三种情况 加起来 已经是叔节点是黑色的全集了 所以可解
RBT 删除的第三种情况是最复杂的 删除的第三种情况 就是找右子树中最小的 代替删除节点后 一定满足 左面全小于它 右面全大于它
至于删除后的调整 楼主需要思考。。。
BST:
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
class node
{
public:
int flag;
int data;
struct node *left;
struct node *right;
struct node *fa;
};
node *new_node()
{
node *a = (node*)malloc(sizeof(node));
memset(a, 0, sizeof(node));
return a;
}
void Swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
class BST
{
public:
node *root;
node *leaf;
BST(int *input, int low, int high)
{
leaf = new_node();
root = this->BST_build(input, low, high);
}
node *BST_build(int *a, int l, int h)
{
if (l <= h)
{
int i = l + 1, j = l + 1;
for (; i <= h; ++i)
{
if (a[i] < a[l])
Swap(&a[i], &a[j++]);
}
Swap(&a[l], &a[j - 1]);
node *s = new_node();
s->data = a[j - 1];
s->left = BST_build(a, l, j - 2);
s->right = BST_build(a, j, h);
s->left->fa = s;
s->right->fa = s;
return s;
}
else
return leaf;
}
node *BST_insert(int data)
{
node *p = new_node();
p->data = data;
p->left = leaf;
p->right = leaf;
node *t = root;
while (1)
{
if (data < t->data)
{
if (t->left == leaf)
{
t->left = p;
p->fa = t;
break;
}
t = t->left;
}
else
{
if (t->right == leaf)
{
t->right = p;
p->fa = t;
break;
}
t = t->right;
}
}
return p;
}
node *BST_search(int data)
{
node *t = root;
while (t != leaf)
{
if (t->data == data)
break;
else if (t->data > data)
t = t->left;
else
t = t->right;
}
return t;
}
node *BST_mini(node *_root)
{
if (_root->left != leaf)
return BST_mini(_root->left);
else
return _root;
}
node *BST_max(node *_root)
{
if (_root->right != leaf)
return BST_max(_root->right);
else
return _root;
}
void Transplant(node *_old, node *_new)
{
if (_old->fa == NULL)
root = _new;
else if (_old->fa->left == _old)
_old->fa->left = _new;
else
_old->fa->right = _new;
if (_new != leaf)
_new->fa = _old->fa;
}
bool BST_delete(int data)
{
node *z = BST_search(data);
if (!z)
return false;
else
{
if (z->left == leaf)
Transplant(z, z->right);
else if (z->right == leaf)
Transplant(z, z->left);
else
{
node *y = BST_mini(z->right);
if (y->fa != z)
{
Transplant(y, y->right);
y->right = z->right;
y->right->fa = y;
}
Transplant(z, y);
y->left = z->left;
y->left->fa = y;
}
return true;
}
}
void walk(node *_root)
{
if (_root != leaf)
{
walk(_root->left);
cout << _root->data << " ";
walk(_root->right);
}
}
};
int main()
{
int max = 10;
int a[10] = { 33,66,23,1,535,3,23,5,233,6 };
BST tree(a, 0, max-1);
tree.walk(tree.root);
tree.BST_delete(23);
cout << endl;
tree.walk(tree.root);
system("pause");
return 0;
}
楼主 写RBT时无意测试的数据引起了一个巨大的疑问
楼主 输入数据 33,66,23,1,535,3,23,5,233,6
删除 23 陷入了死循环
观察后发现 其树为这样的形状 删除根节点23后用后继23来替换 叶节点替换该23 可以看到 叶节点的叔节点W为BLACK W的子节点为都为RED 在 Delete_Fixup中根本没有处理这种情况因此而陷入死循环。。楼主又拿了几个别人写的代码 都会陷入死循环。。以下为发生错误的代码。
#include <cstdlib>
#include <cstring>
#include <iostream>
#define BLACK 1
#define RED 0
using namespace std;
class node
{
public:
int flag;
int data;
int rank;
struct node *left;
struct node *right;
struct node *fa;
};
node *new_node()
{
node *a = (node*)malloc(sizeof(node));
memset(a, 0, sizeof(node));
return a;
}
void Swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
class RBT
{
public:
node *root;
node *leaf;
RBT(int *input, int low, int high)
{
root = NULL;
leaf = new_node();
memset(leaf, 0, sizeof(node));
leaf->flag = BLACK;
leaf->rank = 0;
for (int i = low; i <= high; ++i)
this->RB_insert(input[i]);
}
node *RB_insert(int data)
{
//BST_insert
node *p = new_node();
p->data = data;
p->left = leaf;
p->right = leaf;
node *t = root;
if (!t)
{
root = p;
p->flag = BLACK;
return p;
}
while (1)
{
if (data < t->data)
{
if (t->left == leaf)
{
t->left = p;
p->fa = t;
break;
}
t = t->left;
}
else
{
if (t->right == leaf)
{
t->right = p;
p->fa = t;
break;
}
t = t->right;
}
}
p->flag = RED;
RB_insert_fixup(p);
return p;
}
void RB_insert_fixup(node *z)
{
while (z->fa != NULL && z->fa->flag == RED)
{
if (z->fa->fa->left == z->fa)
{
node *u = z->fa->fa->right;
if (u->flag == RED)
{
z->fa->flag = BLACK;
u->flag = BLACK;
z->fa->fa->flag = RED;
z = z->fa->fa;
}
else if (z == z->fa->right)
{
z = z->fa;
left_rotate(z);
}
else
{
z->fa->flag = BLACK;
z->fa->fa->flag = RED;
right_rotate(z->fa->fa);
}
}
else
{
node *u = z->fa->fa->left;
if (u->flag == RED)
{
u->flag = BLACK;
z->fa->flag = BLACK;
z->fa->fa->flag = RED;
z = z->fa->fa;
}
else if (z == z->fa->left)
{
z = z->fa;
right_rotate(z);
}
else
{
z->fa->fa->flag = RED;
z->fa->flag = BLACK;
left_rotate(z->fa->fa);
}
}
root->flag = BLACK;
}
}
void left_rotate(node *x)
{
node *y = x->right;
x->right = y->left;
if (y->left != leaf)
y->left->fa = x;
y->fa = x->fa;
if (x->fa == NULL)
root = y;
else if (x->fa->right == x)
x->fa->right = y;
else
x->fa->left = y;
y->left = x;
x->fa = y;
}
void right_rotate(node *x)
{
node *y = x->left;
x->left = y->right;
if (y->right != leaf)
y->right->fa = x;
y->fa = x->fa;
if (x->fa == NULL)
root = y;
else if (x->fa->left == x)
x->fa->left = y;
else
x->fa->right = y;
y->right = x;
x->fa = y;
}
void walk(node *_root)
{
if (_root != leaf)
{
walk(_root->left);
cout << _root->data << " ";
walk(_root->right);
}
}
node *Search(int data)
{
node *t = root;
while (t != leaf)
{
if (t->data == data)
break;
else if (t->data > data)
t = t->left;
else
t = t->right;
}
return t;
}
node *Mini(node *_root)
{
if (_root->left != leaf)
return Mini(_root->left);
else
return _root;
}
node *Max(node *_root)
{
if (_root->right != leaf)
return Max(_root->right);
else
return _root;
}
void RB_Transplant(node *_old, node *_new)
{
if (_old->fa == NULL)
root = _new;
else if (_old->fa->left == _old)
_old->fa->left = _new;
else
_old->fa->right = _new;
_new->fa = _old->fa;
}
void RB_Delete_Fixup(node *x)
{
while (x != root && x->flag == BLACK)
{
if (x == x->fa->left)
{
node *w = x->fa->right;
if (w->flag == RED)
{
w->flag = BLACK;
x->fa->flag = RED;
left_rotate(x->fa);
w = x->fa->right;
}
if (w->left->flag == BLACK && w->right->flag == BLACK)
{
w->flag == RED;
x = x->fa;
}
else if (w->right->flag == BLACK)
{
w->left->flag = BLACK;
w->flag = RED;
right_rotate(w);
w = x->fa->right;
w->flag = x->fa->flag;
x->fa->flag = BLACK;
w->right->flag = BLACK;
left_rotate(x->fa);
x = root;
}
}
else
{
node *w = x->fa->left;
if (w->flag == RED)
{
w->flag = BLACK;
x->fa->flag = RED;
right_rotate(x->fa);
w = x->fa->left;
}
if (w->left->flag == BLACK && w->right->flag == BLACK)
{
w->flag == RED;
x = x->fa;
}
else if (w->left->flag == BLACK)
{
w->right->flag = BLACK;
w->flag = RED;
left_rotate(w);
w = x->fa->left;
w->flag = x->fa->flag;
x->fa->flag = BLACK;
w->left->flag = BLACK;
right_rotate(x->fa);
x = root;
}
}
}
x->flag = BLACK;
}
bool RB_Delete(int data)
{
node *z = Search(data);
if (z == leaf)
return false;
else
{
node *y = z, *x;
int y_ori_colr = z->flag;
if (z->left == leaf)
{
x = z->right;
RB_Transplant(z, z->right);
}
else if (z->right == leaf)
{
x = z->left;
RB_Transplant(z, z->left);
}
else
{
y = Mini(z->right);
y_ori_colr = y->flag;
x = y->right;
if (y->fa == z)
x->fa = y; //x是叶节点也设置fa指向y
else
{
RB_Transplant(y, y->right);
y->right = z->right;
y->right->fa = y;
}
RB_Transplant(z, y);
y->left = z->left;
y->left->fa = y;
y->flag = z->flag;
}
if (y_ori_colr == BLACK)
RB_Delete_Fixup(x);
}
}
};
int main()
{
int max = 10;
int a[10] = { 33,66,23,1,535,3,23,5,233,6 };
RBT tree(a, 0, max - 1);
tree.walk(tree.root);
cout << endl;
tree.RB_Delete(23);
tree.walk(tree.root);
cout << endl;
system("pause");
}
后来我发现了问题所在 是算法导论上面伪代码我没看懂 case3 和 case4 的关系错了 一下为
原:
else if (w->left->flag == BLACK)
{
w->right->flag = BLACK;
w->flag = RED;
left_rotate(w);
w = x->fa->left;
w->flag = x->fa->flag;
x->fa->flag = BLACK;
w->left->flag = BLACK;
right_rotate(x->fa);
x = root;
}
更改后:
else
{
if (w->left->flag == BLACK)
{
w->right->flag = BLACK;
w->flag = RED;
left_rotate(w);
w = x->fa->left;
}
w->flag = x->fa->flag;
x->fa->flag = BLACK;
w->left->flag = BLACK;
right_rotate(x->fa);
x = root;
}
问题解决,还是要学会看伪代码啊
RBT
#include <cstdlib>
#include <cstring>
#include <iostream>
#define BLACK 1
#define RED 0
using namespace std;
class node
{
public:
int flag;
int data;
int rank;
struct node *left;
struct node *right;
struct node *fa;
};
node *new_node()
{
node *a = (node*)malloc(sizeof(node));
memset(a, 0, sizeof(node));
return a;
}
void Swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
class RBT
{
public:
node *root;
node *leaf;
RBT(int *input, int low, int high)
{
root = NULL;
leaf = new_node();
memset(leaf, 0, sizeof(node));
leaf->flag = BLACK;
leaf->rank = 0;
for (int i = low; i <= high; ++i)
this->RB_insert(input[i]);
}
node *RB_insert(int data)
{
//BST_insert
node *p = new_node();
p->data = data;
p->left = leaf;
p->right = leaf;
node *t = root;
if (!t)
{
root = p;
p->flag = BLACK;
return p;
}
while (1)
{
if (data < t->data)
{
if (t->left == leaf)
{
t->left = p;
p->fa = t;
break;
}
t = t->left;
}
else
{
if (t->right == leaf)
{
t->right = p;
p->fa = t;
break;
}
t = t->right;
}
}
p->flag = RED;
RB_insert_fixup(p);
return p;
}
void RB_insert_fixup(node *z)
{
while (z->fa != NULL && z->fa->flag == RED)
{
if (z->fa->fa->left == z->fa)
{
node *u = z->fa->fa->right;
if (u->flag == RED)
{
z->fa->flag = BLACK;
u->flag = BLACK;
z->fa->fa->flag = RED;
z = z->fa->fa;
}
else if (z == z->fa->right)
{
z = z->fa;
left_rotate(z);
}
else
{
z->fa->flag = BLACK;
z->fa->fa->flag = RED;
right_rotate(z->fa->fa);
}
}
else
{
node *u = z->fa->fa->left;
if (u->flag == RED)
{
u->flag = BLACK;
z->fa->flag = BLACK;
z->fa->fa->flag = RED;
z = z->fa->fa;
}
else if (z == z->fa->left)
{
z = z->fa;
right_rotate(z);
}
else
{
z->fa->fa->flag = RED;
z->fa->flag = BLACK;
left_rotate(z->fa->fa);
}
}
root->flag = BLACK;
}
}
void left_rotate(node *x)
{
node *y = x->right;
x->right = y->left;
if (y->left != leaf)
y->left->fa = x;
y->fa = x->fa;
if (x->fa == NULL)
root = y;
else if (x->fa->right == x)
x->fa->right = y;
else
x->fa->left = y;
y->left = x;
x->fa = y;
}
void right_rotate(node *x)
{
node *y = x->left;
x->left = y->right;
if (y->right != leaf)
y->right->fa = x;
y->fa = x->fa;
if (x->fa == NULL)
root = y;
else if (x->fa->left == x)
x->fa->left = y;
else
x->fa->right = y;
y->right = x;
x->fa = y;
}
void walk(node *_root)
{
if (_root != leaf)
{
walk(_root->left);
cout << _root->data << " ";
walk(_root->right);
}
}
node *Search(int data)
{
node *t = root;
while (t != leaf)
{
if (t->data == data)
break;
else if (t->data > data)
t = t->left;
else
t = t->right;
}
return t;
}
node *Mini(node *_root)
{
if (_root->left != leaf)
return Mini(_root->left);
else
return _root;
}
node *Max(node *_root)
{
if (_root->right != leaf)
return Max(_root->right);
else
return _root;
}
void RB_Transplant(node *_old, node *_new)
{
if (_old->fa == NULL)
root = _new;
else if (_old->fa->left == _old)
_old->fa->left = _new;
else
_old->fa->right = _new;
_new->fa = _old->fa;
}
void RB_Delete_Fixup(node *x)
{
while (x != root && x->flag == BLACK)
{
if (x == x->fa->left)
{
node *w = x->fa->right;
if (w->flag == RED)
{
w->flag = BLACK;
x->fa->flag = RED;
left_rotate(x->fa);
w = x->fa->right;
}
if (w->left->flag == BLACK && w->right->flag == BLACK)
{
w->flag == RED;
x = x->fa;
}
else
{
if (w->right->flag == BLACK)
{
w->left->flag = BLACK;
w->flag = RED;
right_rotate(w);
w = x->fa->right;
}
w->flag = x->fa->flag;
x->fa->flag = BLACK;
w->right->flag = BLACK;
left_rotate(x->fa);
x = root;
}
}
else
{
node *w = x->fa->left;
if (w->flag == RED)
{
w->flag = BLACK;
x->fa->flag = RED;
right_rotate(x->fa);
w = x->fa->left;
}
if (w->left->flag == BLACK && w->right->flag == BLACK)
{
w->flag == RED;
x = x->fa;
}
else
{
if (w->left->flag == BLACK)
{
w->right->flag = BLACK;
w->flag = RED;
left_rotate(w);
w = x->fa->left;
}
w->flag = x->fa->flag;
x->fa->flag = BLACK;
w->left->flag = BLACK;
right_rotate(x->fa);
x = root;
}
}
}
x->flag = BLACK;
}
bool RB_Delete(int data)
{
node *z = Search(data);
if (z == leaf)
return false;
else
{
node *y = z, *x;
int y_ori_colr = z->flag;
if (z->left == leaf)
{
x = z->right;
RB_Transplant(z, z->right);
}
else if (z->right == leaf)
{
x = z->left;
RB_Transplant(z, z->left);
}
else
{
y = Mini(z->right);
y_ori_colr = y->flag;
x = y->right;
if (y->fa == z)
x->fa = y; //x是叶节点也设置fa指向y
else
{
RB_Transplant(y, y->right);
y->right = z->right;
y->right->fa = y;
}
RB_Transplant(z, y);
y->left = z->left;
y->left->fa = y;
y->flag = z->flag;
}
if (y_ori_colr == BLACK)
RB_Delete_Fixup(x);
}
}
};
int main()
{
int max = 10;
int a[10] = { 33,66,23,1,535,3,23,5,233,6 };
RBT tree(a, 0, max - 1);
tree.walk(tree.root);
cout << endl;
tree.RB_Delete(23);
tree.walk(tree.root);
cout << endl;
system("pause");
}