红黑树建树

// 模板_建树.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>
#include<queue>
#include<iomanip>
#include<Windows.h>
#include<iostream>
#include<string>
#include<ctime>
using namespace std;

//红黑树

enum colortype { RED, BLACK };

struct node {
	int data;
	colortype color;
	node*L, *R, *F;
} *NIL, *root;

void show_tree();

void ini() {
	NIL = new node;
	NIL->color = BLACK;
	NIL->L = NULL;
	NIL->R = NULL;
	NIL->F = NULL;

	root = NIL;
}

void RR(node*cur) {

	node*it, *itF, *itL, *itLR;
	it = cur;
	itF = cur->F;
	itL = cur->L;
	itLR = cur->L->R;

	
	it->L = itLR;
	itLR->F = it;

	it->F = itL;
	itL->R = it;

	itL->F = itF;
	if (root == it) root = itL;
	else it == itF->L ? itF->L = itL : itF->R = itL;
}

void LR(node*cur) {

	node*it, *itR, *itF, *itRL;
	it = cur;
	itR = cur->R;
	itF = cur->F;
	itRL = cur->R->L;

	it->R = itRL;
	itRL->F = it;

	it->F = itR;
	itR->L = it;

	itR->F = itF;
	if (root == it) root = itR;
	else it == itF->R ? itF->R = itR : itF->L = itR;
}

void ins_adj(node*cur) {
	node*father = cur->F;
	node*grand = father->F;
	node*uncle = father == grand->L ? grand->R : grand->L;

	/*
	      -----gB-----
	 ----fR----  ----uR----
	cR        ?  ?         ?
   ?  ?       
	move father's and uncle's RED up   then may be grandfather'father is RED,
	if that ,father will not be the root ,we think grandfather is the new cur;
	      -----gR-----
	 ----fB----  ----uB----
	cR        ?  ?         ?
   ?  ?         
	*/
	if (uncle->color == RED) {
		father->color = BLACK;
		uncle->color = BLACK;
		grand->color = RED;
		if (grand == root)grand->color = BLACK;
		else if (grand->F->color == RED)ins_adj(grand);
	}

	/*there are 4 case and there is only show one of them
	        -----gB-----
	  ----fR----   ----uB----
	  ?        cR  ?        ?
	          ?  ?
	rote fR and then we can think father is the new cur;
    	  -----gB-----
	 ----fR----  ----uB----
	cR        ?  ?        ?
   ?  ?
   rote grandfather and change the color between father and grandfather ,end; 
	      -----fB-----
	     cR      ----gB----
	    ?  ?    ?         uB
		                 ?  ?  
	*/
	else {
		///////////////////////////////
		if (father == grand->L) {
			if (cur == father->R) {
				LR(father);

				father = cur;
				cur = cur->L;
			}
			father->color = BLACK;
			grand->color = RED;
			RR(grand);
		}
		else {
			if (cur == father->L) {
				RR(father);

				father = cur;
				cur = cur->R;
			}
			father->color = BLACK;
			grand->color = RED;
			LR(grand);
		}
		///////////////////////////////
	}
}

void del_adj(node*cur) {
	if (cur == root)return;
	if (cur->color == RED) {
		// the another black become the real black;
		cur->color = BLACK;
		return;
	}

	//now cur is black and it have another black
	/*
	  ----f?----  
	 cB         ?
	?  ?
	*/
	node*father = cur->F;
	node*broder = father->L == cur ? father->R : father->L;//cur_tree

	/*
	      ----fB----  
	     cB        bR
    	?  ?      ?  ?
	rote fahter
	       ----bB---
          fB        ?
       cB    ? 
      ?  ?
	
	*/
	if (broder->color == RED) {//a way to give a black broder to cur 
		father->color = RED;
		broder->color = BLACK;
		if (broder == father->L)RR(father), broder = father->L;
		else LR(father), broder = father->R;
	}
	//now broder is black,but we don't know father's color,we don't care that

	/*
    	----f?----
	   cB        bB
	  ?  ?      B  B
	move BLACK between cur and broder up,we can think father is the new one have the another black;
	   	----f?----
	   cB        bR
	  ?  ?      B  B
	*/
	if (broder->L->color == BLACK && broder->R->color == BLACK) {//move another black to father
		broder->color = RED;
		cur = father;
		del_adj(cur);
		return;
	}


	/*there are 4 case and only show one of them
	  ----f?------
	 cB        --bB-
	?  ?      R     B
	         ? ?   ? ?
	make the  broder'special child is RED;
        -----f?------
	  cB          --B-
	 ?  ?        ?     bR
	                  ?   B
					     ? ?
	we only care this part
	  -----f?------
	 cB          --B-
	?  ?        ?     bR
	                 ?  ?
	change it to this ,don't care father's color and give it to the new one who stand in father's place;
      -----B?------
	 fB          bB
	cB  ?       ?  ?  
   ?  ?          

   ok!!!!!!!!!!!
	*/
	if (cur == father->L) {
		if (broder->R->color == BLACK) {//then broder->L->color==RED
			broder->color = RED;
			broder->L->color = BLACK;
			RR(broder);
			broder = broder->F;
		}
		//now broder->R->color==RED and broder is black;move another black to father
		broder->R->color = BLACK;
		broder->color = father->color;
		father->color = BLACK;

		LR(father);
	}
	else {
		if (broder->L->color == BLACK) {
			broder->color = RED;
			broder->R->color = BLACK;
			LR(broder);
			broder = broder->F;
		}
		broder->L->color = BLACK;
		broder->color = father->color;
		father->color = BLACK;

		RR(father);
	}
}

node*find(int x, node*cur = root) {
	if (cur == NULL) {
		cout << "couldn't find " << x << endl;
		show_tree();
		system("pause");
		return NULL;
	}
	if (x > cur->data)return find(x, cur->R);
	else if (x < cur->data) return find(x, cur->L);
	else if (x == cur->data)return cur;
}

void insert(int x, node*&cur = root, node*fa = NULL) {
	if (cur == NIL) {
		cur = new node;
		cur->data = x;
		cur->color = RED;
		cur->L = NIL;
		cur->R = NIL;
		cur->F = fa;

		if (root == cur)cur->color = BLACK;
		else if (cur->F->color == RED)ins_adj(cur);
	}
	else if (x > cur->data)insert(x, cur->R, cur);
	else insert(x, cur->L, cur);
}

void del(node*wtd) {
	if (wtd == NULL) {
		cout << "delete error" << endl;
		return;
	}
	node*td = wtd;

	//find one to replace wtd and then delete it;
	if (td->L != NIL && td->R != NIL) {
		td = td->L;
		while (td->R != NIL)td = td->R;
		wtd->data = td->data;
	}

	if (td->F == NULL) {
		root = td->L != NIL ? td->L : td->R;
		root->F = NULL;
		root->color = BLACK;
		delete td;
		return;
	}

	node*father = td->F;
	node*broder = father->L == td ? father->R : father->L;
	node*child = td->L != NIL ? td->L : td->R;

	if (td == father->L) father->L = child;
	else father->R = child;
	child->F = father;

	if (td->color == BLACK)del_adj(child);//Now there is another black in child
	delete td;
}

void clear(node*cur = root) {
	if (cur == NIL)return;
	if (cur->L != NIL)clear(cur->L);
	if (cur->R != NIL)clear(cur->R);
	delete cur;
	cur = NIL;
}

void mid(node*cur = root) {
	if (cur->L != NIL)mid(cur->L);
	cout << cur->data << " ";
	if (cur->R != NIL)mid(cur->R);
}

void front(node*cur = root) {
	cout << cur->data << " ";
	if (cur->L != NIL)mid(cur->L);
	if (cur->R != NIL)mid(cur->R);
}


int main()
{
	srand(time(NULL));
	ini();
	int a[20];
	for (int i = 0; i < 20; i++)
		a[i] = 4*i+10;
	random_shuffle(a, a + 20);
	for (int i = 0; i < 20; i++)cout << "insert " << a[i] << endl, insert(a[i]),show_tree();

	string str;
	int key;
	while (cin >> str >> key) {
		if (str == "delete")del(find(key));
		else if (str == "insert")insert(key);
		else { cout << "cin error" << endl; continue; }
		show_tree();
		cout << "中序"; mid(); cout << endl;
		cout << "先序"; front(); cout << endl;
		cout << endl;
	}
}

void show_tree() {
	//调一下控制台便,可以查看深度小于7的树
	if (root == NIL) {
		cout << "error no tree " << endl;
		return;
	}

	queue<node*>a, b;
	a.push(root);
	int t = 7;
	for (int i = 0; i < t;) {

		int d = (1 << (t - i)) - 1;

		if (a.front() == NULL)b.push(NULL), b.push(NULL);
		else {
			if (a.front()->L != NIL)b.push(a.front()->L);
			else b.push(NULL);
			if (a.front()->R != NIL)b.push(a.front()->R);
			else b.push(NULL);
		}


		if (a.front() != NULL) {
			if (a.front()->color == RED)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
			else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN);
			{
				cout.fill(' ');
				cout << setw(d - d / 2) << "";
				cout.fill('-');
				cout << setw(d / 2) << "" << setw(2) << a.front()->data << setw(d / 2) << "";
				cout.fill(' ');
				cout << setw(d - d / 2) << "";
			}


			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);

		}
		else cout << setw(2 * d + 2) << "";
		a.pop();
		if (a.empty()) {

			while (!b.empty()) {
				a.push(b.front());
				b.pop();
			}
			i++;
			cout << endl;
		}
	}
	cout << endl;

}



猜你喜欢

转载自blog.csdn.net/qq_41157212/article/details/80913348