线段树简单实现

#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 begin;
	int end;
	COLOR color;
	Node* p;
	Node* left;
	Node* right;
	int mmax;
	Node(int b,int e, COLOR c = RED, Node* parent = nullptr, Node* l = nullptr, Node* r = nullptr) :begin(b),end(e), color(c), p(parent), left(l), right(r),mmax(end) {}
};

class Tree {
	friend ostream& operator<<(ostream& o, const Tree& t);
private:
	Node* root;
	int getEnd(Node* root) const {
		if (!root)
			return INT_MIN;
		int tmp = max(root->left ? root->left->mmax : INT_MIN, root->right ? root->right->mmax : INT_MIN);
		return max(root->end, tmp);
	}
	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;

		//添加以适应线段树
		r->mmax = n->mmax;
		n->mmax = getEnd(n);

	}
	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;

		//添加以适应线段树
		l->mmax = n->mmax;
		n->mmax = getEnd(n);
	}
	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->begin << ":" << r->end <<" ";
		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->begin << ":" << r->end << " ";
		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->begin << ":" << r->end << " ";
		return o;
	}
	ostream& cr(ostream& o, Node* r) const {
		if (!r)
			return o;
		cr(o, r->left);
		o << r->color << " ";
		cr(o, r->right);
		return o;
	}
	ostream& maxr(ostream& o, Node* r)const {
		if (!r)
			return o;
		maxr(o, r->left);
		o << r->mmax << " ";
		maxr(o, r->right);
		return o;
	}
	Node* getKey(int key) const {
		Node* r = root;
		while (r) {
			if (r->begin == key)
				break;
			if (r->begin < key)
				r = r->right;
			else
				r = r->left;
		}
		if (!r)
			return nullptr;
		return r;
	}
	Node* getMin(Node* t) const{
		Node* res = nullptr;
		while (t) {
			res = t;
			t = t->left;
		}
		return res;
	}
	Node* getNext(Node* t) const{
		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;
	}
	void clear(Node* root) {
		if (!root)
			return;
		clear(root->left);
		clear(root->right);
		delete root;
	}
	Node* find(int begin, int end, Node* r) const {
		while (r && (r->begin > end || r->end < begin)) {
			if (r->mmax >= begin) {
				r = r->left;
			}
			else {
				r = r->right;
			}
		}
		return	r;
	}
public:
	Tree(Node* r = nullptr) :root(r) {}
	void insert(int begin,int end) {
		Node* tr = root;
		Node* ti = nullptr;
		while (tr) {
			//修改以适应线段树
			tr->mmax = max(tr->mmax, end);

			ti = tr;
			if (tr->begin < begin)
				tr = tr->right;
			else
				tr = tr->left;
		}
		if (!ti)
			root = new Node(begin,end, BLACK);
		else {
			Node* tokeep = new Node(begin,end, RED, ti);
			if (ti->begin < begin)
				ti->right = tokeep;
			else
				ti->left = tokeep;
			keep(tokeep);
		}
	}

	bool find(int begin) const {
		return getKey(begin) != nullptr;
	}
	void remove(int begin) {
		Node* r = getKey(begin);
		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);
				delete 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;

			//修改以适应线段树
			nr->mmax = r->mmax;
		}
//		free(r);
		delete r;
		
		//修改以适应线段树
		Node* tpx = px;
		while (tpx) {
			tpx->mmax = getEnd(tpx);
			tpx = tpx->p;
		}

		if (color == BLACK) {
			dkeep(x, px);
		}
	}
	Node* find(int begin, int end) const{
		return find(begin, end, root);
	}
	ostream& maxr(ostream& o) {
		return maxr(o, root)<<endl;
	}
	void clear() {
		clear(root);
		root = nullptr;
	}
	~Tree() {
		clear();
	}
};
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;
	t.cr(o, t.root) << endl;
	return o;
}

int main() {
	ifstream in("D:\\input.txt");
	//istream &in=cin;
	Tree t;
	t.insert(1,5);
	t.maxr(cout);
	cout << t << endl;
	t.insert(2,3);
	t.maxr(cout);
	cout << t << endl;
	t.insert(3,4);
	t.maxr(cout);
	cout << t << endl;
	t.insert(4,7);
	t.maxr(cout);
	cout << t << endl;
	t.insert(8,10);
	t.maxr(cout);
	cout << t << endl;
	t.remove(3);
	t.maxr(cout);
	cout << t << endl;
	t.insert(5, 7);
	t.maxr(cout);
	cout << t << endl;
	t.insert(6,8);
	t.maxr(cout);
	cout << t << endl;
	t.insert(7,9);
	t.maxr(cout);
	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、付费专栏及课程。

余额充值