算法导论代码笔记(二)

开放寻址: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");
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值