红黑树的简单实现

#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
#include <functional>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <vector>

using namespace std;
enum COLOR{RED,BLACK};

struct Node{
	int key;
	COLOR color;
	Node* p;
	Node* left;
	Node* right;
	Node(int k, COLOR c = RED, Node* parent = nullptr, Node* l = nullptr, Node* r = nullptr) :key(k), color(c), p(parent), left(l), right(r) {}
};

class Tree{
	friend ostream& operator<<(ostream& o, const Tree& t);
private:
	Node* root;
	void leftR(Node* n) {
		if (!n || !n->right) {
			return;
		}
		Node* r = n->right;
		Node* p = n->p;
		if (p) {
			if (p->right == n)
				p->right = r;
			else
				p->left = r;
		}
		else
			root = r;
		r->p = p;
		n->right = r->left;
		if(n->right)
			n->right->p = n;
		r->left = n;
		n->p = r;
	}
	void rightR(Node* n) {
		if (!n || !n->left) {
			return;
		}
		Node* l = n->left;
		Node* p = n->p;
		if (p) {
			if (p->left == n)
				p->left = l;
			else
				p->right = l;
		}
		else
			root = l;
		l->p = p;
		n->left = l->right;
		if(n->left)
			n->left->p = n;
		l->right = n;
		n->p = l;
	}
	void keep(Node* tokeep) {
		while (tokeep->p && tokeep->p->color == RED) {
			if (tokeep->p->p->left == tokeep->p) {//其父为左孩子
				Node* father = tokeep->p;
				Node* uncle = father->p->right;
				if (uncle && uncle->color == RED) {
					father->color = BLACK;
					uncle->color = BLACK;
					father->p->color = RED;
					tokeep = father->p;
				}
				else {
					if (tokeep == father->right) {
						leftR(father);
						tokeep = father;
						father = father->p;
					}
					father->color = BLACK;
					father->p->color = RED;
					rightR(father->p);
				}
			}
			else {
				Node* father = tokeep->p;
				Node* uncle = father->p->left;
				if (uncle && uncle->color == RED) {
					uncle->color = BLACK;
					father->color = BLACK;
					father->p->color = RED;
					tokeep = father->p;
				}
				else {
					if (tokeep == father->left) {
						rightR(father);
						tokeep = father;
						father = father->p;
					}
					father->color = BLACK;
					father->p->color = RED;
					leftR(father->p);
				}
			}
		}
		root->color = BLACK;
	}
	ostream& pr(ostream& o,Node* r) const{
		if (!r)
			return o;
		o << r->key << " ";
		pr(o, r->left);
		pr(o, r->right);
		return o;
	}
	ostream& mr(ostream& o, Node* r) const{
		if (!r)
			return o;
		mr(o, r->left);
		o << r->key << " ";
		mr(o, r->right);
		return o;
	}
	ostream& er(ostream& o, Node* r) const{
		if (!r)
			return o;
		er(o, r->left);
		er(o, r->right);
		o << r->key << " ";
		return o;
	}
	Node* getKey(int key) {
		Node* r = root;
		while (r) {
			if (r->key == key)
				break;
			if (r->key < key)
				r = r->right;
			else
				r = r->left;
		}
		if (!r)
			return nullptr;
		return r;
	}
	Node* getMin(Node* t) {
		Node* res = nullptr;
		while (t) {
			res = t;
			t = t->left;
		}
		return res;
	}
	Node* getNext(Node* t) {
		if (t && t->right) {
			return getMin(t->right);
		}
		else {
			while (t && t->p && t->p->left == t) {
				t = t->p;
			}
			if (t && t->p)
				return t->p;
			else
				return nullptr;
		}
	}
	void dkeep(Node* x, Node* px) {
		while (x != root && (!x || x->color == BLACK)) {
			if (x == px->left) {
				Node* w = px->right;
				if (w->color == RED) {
					w->color = BLACK;
					px->color = RED;
					leftR(px);
					w = px->right;
				}
				if ((!w->left || w->left->color == BLACK) && (!w->right || w->right->color == BLACK)) {
					w->color = RED;
					x = px;
					px = px->p;
				}
				else {
					if (!w->right || w->right->color == BLACK) {
						w->color = RED;
						w->left->color = BLACK;
						rightR(w);
						w = px->right;
					}
					w->color = px->color;
					px->color = BLACK;
					w->right->color = BLACK;
					leftR(px);
					x = root;
				}
			}
			else {
				Node* w = px->left;
				if (w->color == RED) {
					w->color = BLACK;
					px->color = RED;
					rightR(px);
					w = px->left;
				}
				if ((!w->left || w->left->color == BLACK) && (!w->right || w->right->color == BLACK)) {
					w->color = RED;
					x = px;
					px = px->p;
				}
				else {
					if (!w->left || w->left->color == BLACK) {
						w->right->color = BLACK;
						w->color = RED;
						leftR(w);
						w = px->left;
					}
					w->color = px->color;
					px->color = BLACK;
					w->left->color = BLACK;
					rightR(px);
					x = root;
				}

			}
		}
		x->color = BLACK;
	}
public:
	Tree(Node* r = nullptr) :root(r) {}
	void insert(int key) {
		Node* tr = root;
		Node* ti = nullptr;
		while (tr) {
			ti = tr;
			if (tr->key < key)
				tr = tr->right;
			else
				tr = tr->left;
		}
		if (!ti)
			root = new Node(key,BLACK);
		else{
			Node* tokeep = new Node(key, RED, ti);
			if (ti->key < key)
				ti->right = tokeep;
			else
				ti->left = tokeep;
			keep(tokeep);
		}
	}
	
	bool find(int key) {
		return getKey(key) != nullptr;
	}
	void remove(int key) {
		Node* r = getKey(key);
		int color;
		Node* x = nullptr;
		Node* px = nullptr;
		if (!r)
			return;
		color = r->color;
		if (!r->left && !r->right) {
			x = nullptr;
			px = r->p;
			if (!px) {
				root = nullptr;
				free(r);
				return;
			}
			else {
				if (px->left == r) {
					px->left = x;
				}
				else {
					px->right = x;
				}
			}
		}else if (!r->left) {
			x = r->right;
			px = r->p;
			if (!px) {
				root = x;
			}
			else {
				if (px->right == r) {
					px->right = x;
				}
				else {
					px->left = x;
				}
			}
			x->p = px;
		}
		else if (!r->right) {
			x = r->left;
			px = r->p;
			if (!px) {
				root = x;
			}
			else {
				if (px->right == r) {
					px->right = x;
				}
				else {
					px->left = x;
				}
			}
			x->p = px;
		}
		else {
			Node* nr = getMin(r->right);	//nr->left==nullptr
			color = nr->color;				// nr->p != nullptr
			x = nr->right;
			px = nr->p;
			if (px->left == nr) {
				px->left = x;
			}
			else {
				px->right = x;
			}
			if (x) {
				x->p = px;
			}
			if (px == r)
				px = nr;
			if (!r->p) {
				root = nr;
			}
			else if (r->p->left == r) {
				r->p->left = nr;
			}
			else {
				r->p->right = nr;
			}
			nr->p = r->p;
			nr->left = r->left;
			nr->left->p = nr;
			nr->right = r->right;
			if (nr->right)
				nr->right->p = nr;

		}
		free(r);
		if (color == BLACK) {
			dkeep(x,px);
		}
	}
};
ostream& operator<<(ostream& o,const Tree &t) {
	t.pr(o, t.root) << endl;
	t.mr(o,t.root) << endl;
	t.er(o,t.root) << endl;
	return o;
}

int main() {
	ifstream in("D:\\input.txt");
	//istream &in=cin;
	Tree t;
	t.insert(1);
	cout << t << endl;
	t.insert(2);
	cout << t << endl;
	t.insert(3);
	cout << t << endl;
	t.insert(4);
	cout << t << endl;
	t.insert(8);
	cout << t << endl;
	t.insert(5);
	cout << t << endl;
	t.insert(6);
	cout << t << endl;
	t.insert(7);
	cout << t << endl;
	t.remove(3);
	cout << t << endl;
	char c;
	cin >> c;

	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值