线段树简单实现

来源:互联网 发布:网络招聘怎么写 编辑:程序博客网 时间:2024/06/06 03:45
#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;elsep->left = r;}elseroot = 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;elsep->right = l;}elseroot = 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;elser = 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;elsereturn 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;}}returnr;}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;elsetr = 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;elseti->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==nullptrcolor = nr->color;// nr->p != nullptrx = 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;}