#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;
}
线段树简单实现
最新推荐文章于 2022-05-04 23:27:23 发布