二叉树 - 红黑树

RBTree.h

#include <iostream>

template <typename T>
class RBTree
{
public:
	RBTree();
	bool insert(const T&);
	bool del(const T&);
	void show() {
		Mid_Order(root);
	}

private:

	enum { RED, BLACK };

typedef struct _node
	{
		bool color;
		T data;
		struct _node * p, *left, *right;
	}Node;

	Node *root;
	Node *nil;
	unsigned int Size;

	void RB_Ins_Fix(Node *);
	void RB_Del_Fix(Node *);
	void Left_Rotate(Node *);
	void Right_Rotate(Node *);

	void Replace(Node *, Node *);
	void Mid_Order(const Node *);
};

template <typename T>
RBTree<T>::RBTree()
{
	Node *p = new Node;
	Size = 0;
	nil = new Node;
	nil->color = BLACK;
	nil->p = nil->left = nil->right = NULL;
	root = nil;
}

template <typename T>
bool RBTree<T>::insert(const T& val)
{
	Node *pf = nil;
	Node *pc = root;
	while (pc != nil)
	{
		pf = pc;
		if (val >= pc->data)
			pc = pc->right;
		else
			pc = pc->left;
	}
	Node *pn = new Node;
	pn->data = val;
	pn->p = pf;
	pn->left = pn->right = nil;
	pn->color = RED;
	if (pf == nil)
	{
		pn->color = BLACK;
		root = pn;
		return true;
	}
	else
	{
		if (val >= pf->data)
			pf->right = pn;
		else
			pf->left = pn;
	}
	RB_Ins_Fix(pn);
	return true;
}

template <typename T>
void RBTree<T>::RB_Ins_Fix(Node * ps)
{
	while (ps->p->color == RED)
	{
		Node * pb;
		if (ps->p == nil)
			return;

		if (ps->p == ps->p->p->left)
			pb = ps->p->p->right;
		else
			pb = ps->p->p->left;
		if (pb->color == RED)
		{
			pb->color = BLACK;
			ps->p->color = BLACK;
			ps->p->p->color = RED;
			ps = ps->p->p;
		}
		else
		{
			if (ps == ps->p->right && ps->p == ps->p->p->left)
			{
				Left_Rotate(ps->p);
				ps = ps->left;
			}
			else if (ps == ps->p->left && ps->p == ps->p->p->right)
			{
				Right_Rotate(ps->p);
				ps = ps->right;
			}
			ps->p->color = BLACK;
			ps->p->p->color = RED;
			if (ps == ps->p->right && ps->p == ps->p->p->right)
				Left_Rotate(ps->p->p);
			else
				Right_Rotate(ps->p->p);
		}
	}
	root->color = BLACK;

}

template <typename T>
void RBTree<T>::Left_Rotate(Node * pf)
{
	Node * pc = pf->right;
	pc->p = pf->p;
	if (pf->p != nil)
	{
		if (pf == pf->p->left)
			pf->p->left = pc;
		else
			pf->p->right = pc;
	}
	pf->right = pc->left;
	if (pf == root)
		root = pc;
	if (pc->left != nil)
		pc->left->p = pf;
	pc->left = pf;
	pf->p = pc;
}

template <typename T>
void RBTree<T>::Right_Rotate(Node * pf)
{
	Node * pc = pf->left;
	pc->p = pf->p;
	if (pf->p != nil)
	{
		if (pf == pf->p->left)
			pf->p->left = pc;
		else
			pf->p->right = pc;
	}
	pf->left = pc->right;
	if (pf == root)
		root = pc;
	if (pc->right != nil)
		pc->right->p = pf;
	pc->right = pf;
	pf->p = pc;
}

template <typename T>
void RBTree<T>::Mid_Order(const Node *p)
{
	if (p != nil)
	{
		Mid_Order(p->left);
		std::cout << "结点" << p->data << " " << ((p->color) ? "黑" : "红") << endl;
		Mid_Order(p->right);
	}
}

template <typename T>
bool RBTree<T>::del(const T& val)
{
	Node *pc = nil;
	Node *pn = root;
	while (pn != nil && pc->data != val)
	{
		pc = pn;
		if (val >= pn->data)
			pn = pn->right;
		else
			pn = pn->left;
	}
	if (pc == nil || pc->data != val)
		return false;

	if (pc->color == RED)
	{
		if (pc == pc->p->left)
			pc->p->left = nil;
		else
			pc->p->right = nil;
		delete pc;
	}
	else
	{
		Node *pt = pc; //寻找右侧结点
		if (pt->right != nil)
			while (pt->left != nil)
				pt = pt->left;
		if (pt != pc)
			Replace(pt, pc); //交换结点,转换为删除单子树结点问题

		pc = pt;
		pt = pt->right;
		pc->p->left = pt;
		pt->p = pc->p;
		if (pc == root)
			root = pt;
		delete pc;
		RB_Del_Fix(pt);
	}
	return true;
}

template <typename T>
void RBTree<T>::RB_Del_Fix(Node *x)
{
	while (x != root && x->color == BLACK)
	{
		Node *w;
		if (x == x->p->left)
		{
			w = x->p->right;
			if (w->color == RED)
			{
				w->color = BLACK;
				w->p->color = RED;
				Left_Rotate(w->p);
				w = x->p->right;
			}
		}
		else
		{
			w = x->p->left;
			if (w->color == RED)
			{
				w->color = BLACK;
				w->p->color = RED;
				Right_Rotate(w->p);
				w = x->p->left;
			}
		}
		if (w->left->color == BLACK && w->right->color == BLACK)
		{
			w->color = RED;
			x = x->p;
		}
		else
		{
			if (w->left->color == RED)
			{
				w->left->color = BLACK;
				w->color = RED;
				Right_Rotate(w);
				w = w->p;
			}
			w->color = w->p->color;
			w->p->color = BLACK;
			w->right->color = BLACK;
			Left_Rotate(w->p);
			x = root; //已经平衡,退出
		}
	}
	x->color = BLACK;
}

template <typename T>
void RBTree<T>::Replace(Node *x, Node *y)
{
	/*
	Node *tmp;

	if (x == x->p->left)
		x->p->left = y;
	else
		x->p->right = y;
	if (y == y->p->left)
		y->p->left = x;
	else
		y->p->right = x;

	tmp = x->p;
	x->p = y->p;
	y->p = tmp; 

	tmp = x->left;
	x->left = y->left;
	y->left = tmp;

	tmp = x->right;
	x->right = y->right;
	y->right = tmp;

	if (x->color != y->color)
	{
		if (x->color == RED)
		{
			x->color = BLACK;
			y->color = RED;
		}
		else
		{
			x->color = RED;
			y->color = BLACK;
		}
	}
	*/
	T t = x->data;
	x->data = y->data;
	y->data = t;
}

main.cpp

#include <iostream>
#include "RBTree.h"
using namespace std;
int main()
{
	RBTree<int> a;
	for (int i = 0; i < 10; ++i)
	{
		a.insert(i);
		a.show();
		cout << endl;
	}

	for (int i = 0; i < 10; ++i)
	{
		a.del(i);
		a.show();
		cout << endl;
	}

	cout << endl;
	cout << "ok\n";
	cin.get();
	cin.get();
	return 0;
}
时间: 2024-11-29 05:28:19

二叉树 - 红黑树的相关文章

TreeMap红黑树

Java TreeMap实现了SortedMap接口,也就是说会按照key的大小顺序对Map中的元素进行排序,key大小的评判可以通过其本身的自然顺序(natural ordering),也可以通过构造时传入的比较器(Comparator). TreeMap底层通过红黑树(Red-Black tree)实现,也就意味着containsKey(), get(), put(), remove()都有着log(n)的时间复杂度.其具体算法实现参照了<算法导论>. 出于性能原因,TreeMap是非同步

TreeMap源码分析之一 —— 排序二叉树、平衡二叉树、红黑树

一.排序二叉树(BST树) 1.排序二叉树的定义 排序二叉树,Binary Sort Tree 排序二叉树要么是一棵空二叉树,要么是具有下列性质的二叉树: (1)若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值: (2)若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值: (3)它的左.右子树也分别为排序二叉树. 按中序遍历排序二叉树可以得到由小到大的有序序列. 比如 2.排序二叉树的插入和删除 二.平衡二叉树(Balanced Binary Tree,AVL树) 三.红黑

二叉树,平衡树,红黑树,B~/B+树汇总

二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree).这四种树都具备下面几个优势: (1) 都是动态结构.在删除,插入操作的时候,都不需要彻底重建原始的索引树.最多就是执行一定量的旋转,变色操作来有限的改变树的形态.而这些操作所付出的代价都远远小于重建一棵树.这一优势在<查找结构专题(1):静态查找结构概论 >中讲到过. (2) 查找的时间复杂度大体维持在O(log(N))数量级上.可能有些结构在最差的情况下效率将会下降很快,比如二叉树 1.二叉查找树

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

Atitit 常见的树形结构 红黑树 &#160;二叉树 &#160;&#160;B树 B+树 &#160;Trie树&#160;attilax理解与总结

Atitit 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树 attilax理解与总结 1.1. 树形结构-- 一对多的关系1 1.2. 树的相关术语: 1 1.3. 常见的树形结构 红黑树  二叉树   B树 B+树  Trie树2 1.4. 满二叉树和完全二叉树..完全二叉树说明深度达到完全了.2 1.5. 属的逻辑表示 树形比奥死,括号表示,文氏图,凹镜法表示3 1.6. 二叉树是数据结构中一种重要的数据结构,也是树表家族最为基础的结构.3 1.6.1. 3.2 平衡二叉

查找二,二叉树查找与2-3树红黑树

BST: 每个节点的键,都大于其左自述中的任意节点的键,而小于有字数的任意结点的键. 部分实现 get(Node x , Key key){ if(x == null) return null; cmp = key.compareTo(x.key); if(cmp<0) retrun get(x.right,key); else if(cmp>0) retrun get(x.left,key); else return x.val; } 2-3树红黑树: 属于平衡查找树,为了希望保持二分查找树

排序二叉树,平衡二叉树和红黑树的概念以及相关的操作讲解

1. 排序二叉树     排序二叉树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索. 排序二叉树要么是一棵空二叉树,要么是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值: 若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值: 它的左.右子树也分别为排序二叉树. 图 1 显示了一棵排序二叉树: 图 1. 排序二叉树 对排序二叉树,若按中序遍历就可以得到由小到大的有序序列.如图 1 所示二叉树,中序遍历得: {2,3,4,8,9,9

树/二叉树(哈夫曼树/红黑树)笔记

1.树是一种常用数据结构,它是非线性结构. 2.树中任一普通节点可以有0或者多个子节点,但只能有一个父节点. 根节点没有父节点, 叶子节点没有子节点. 3.二叉树: 1)每个节点最多只能有两个子树的有序树 2)左边的子树称为左子树 3)右边的子树成为右子树 4)一棵深度为k的二叉树,如果它包含了(2^k-1)个节点,就把这棵二叉树称为满二叉树 4.满二叉树的特点: 1)每一层上的节点数都是最大节点数,即各层为1,2,4,8,16 .... (2^k-1) 2)一棵有n个节点的二叉树,按满二叉树的

数据结构之二叉树扩展AVL,B-,B+,红黑树

1.AVL 1.基本概念 AVL是平衡二叉查找树,它或者是一颗空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1. 若将二叉树结点上的平衡因子BF(Balance Factor)定义为该结点的左子树的深度减去它的右子树的深度,则平衡二叉树上所有结点的平衡因子只能是-1,0,1. 2.性质 平衡二叉查找树,在添加或者删除的结点的过程中,如果失去平衡,则需要进行平衡调整.调整的过程中,要保持根大于左,小于右的特性. 3.应用场景 最早的平衡