zoukankan      html  css  js  c++  java
  • 搜索二叉树和红黑树的实现

    参考了CLRS(算法导论第二版十二十三章的内容),为了能让红黑树继承搜索二叉树中的大部分方法,我修改了书中红黑树的实现方式,即不再将空节点视为黑色节点,这样一来,红黑树的规则变成了四条。

    1. 根节点为黑色
    2. 从任一节点,到叶子节点(这里的叶子节点不是空节点)的所有路径中,包含了相同个数的黑节点
    3. 任一节点非红即黑
    4. 任一节点,若其为红,则其孩子要么都为空,要么都为黑节点。

    下面是搜索二叉树的实现

    //e:\Projects\CLRS\CLRS\BinaryTree.h
    #ifndef BINARYTREE_H
    #define BINARYTREE_H
    #include <fstream>
    #include <cassert>
    using namespace std;
    template<class T,class P>
    class TreeNode
    {
    public:
    	TreeNode(T _key,P * pdata = NULL)
    	{
    		key = _key;
    		sateliteData = pdata;
    		parentNode = rightNode = leftNode = NULL;
    	}
    	T key;
    	P * sateliteData;
    	TreeNode * leftNode;
    	TreeNode * rightNode;
    	TreeNode * parentNode;
    };
    template<class T,class P>
    class BinaryTree
    {
    public:
    	BinaryTree()
    	{
    		root = NULL;
    	}
    	TreeNode<T,P> * root;
    	void Inorder_Walk(ofstream &fout);
    	void Inorder_Walk(TreeNode<T,P>* node,ofstream & fout);
    	void Preorder_Walk(ofstream &fout);//前序
    	void Preorder_Walk(TreeNode<T,P>* node,ofstream & fout,int level);
    
    	TreeNode<T,P> * Search(T key);
    	TreeNode<T,P> * Search(TreeNode<T,P>* node,T key);
    
    	TreeNode<T,P> * Iterative_Search(T key);
    	TreeNode<T,P> * Iterative_Search(TreeNode<T,P>* node,T key);
    	TreeNode<T,P>* Min(TreeNode<T,P>* node);
    	TreeNode<T,P>* Min();
    	TreeNode<T,P>* Max(TreeNode<T,P>* node);
    	TreeNode<T,P>* Max();
    	TreeNode<T,P>* TreeSuccessor(TreeNode<T,P>* node);
    
    	TreeNode<T,P>*  Insert(TreeNode<T,P>* z);
    	TreeNode<T,P>* Delete(TreeNode<T,P>* z,TreeNode<T,P>*& x,TreeNode<T,P>*& p);
    	void LeftRotate(TreeNode<T,P>* x);
    	void RightRotate(TreeNode<T,P>* y);
    
    	bool IsSorted(); //是二叉搜索树吗
    	bool IsSorted(TreeNode<T,P>* node,T& minVal,T& maxVal); //是二叉搜索树吗
    
    };
    
    template<class T,class P>
    bool BinaryTree<T,P>::IsSorted()
    {
    	if (root == NULL)
    	{
    		return true;
    	}
    	T minV,maxV;
    	return IsSorted(root,minV,maxV);
    
    }
    template<class T,class P>
    bool BinaryTree<T,P>::IsSorted(TreeNode<T,P>* node,T& minV,T&maxV)
    {
    	T lminV,lmaxV;
    	T rminV,rmaxV;
    
    	if (node->leftNode!=NULL)
    	{
    		bool res = IsSorted(node->leftNode,lminV,lmaxV);
    		if (!res)
    		{
    			return false;
    		}
    	}
    	if (node->rightNode!=NULL)
    	{
    		bool res = IsSorted(node->rightNode,rminV,rmaxV);
    		if (!res)
    		{
    			return false;
    		}
    	}
    	if (node->leftNode!=NULL)
    	{
    		if (lmaxV>node->key)
    		{
    			return false;
    		}
    	}
    	if (node->rightNode!=NULL)
    	{
    		if (rminV < node->key)
    		{
    			return false;
    		}
    	}
    
    	if (node->leftNode == NULL)
    	{
    		minV = node->key;
    	}else{
    		minV = lminV;
    	}
    
    	if (node->rightNode == NULL)
    	{
    		maxV = node->key;
    	}else{
    		maxV = rmaxV;
    	}
    	return true;
    }
    
    template<class T,class P>
    void BinaryTree<T,P>::Preorder_Walk(ofstream &fout)
    {
    	if (root == NULL)
    	{
    		fout << "empty tree"<<endl;
    	}
    	Preorder_Walk(root,fout,0);
    	fout << (IsSorted()?"sorted":"unsorted") << endl;
    
    }
    
    template<class T,class P>
    void BinaryTree<T,P>::Preorder_Walk(TreeNode<T,P>* node,ofstream & fout,int level)
    {
    	if (node == NULL)
    	{
    		return;
    	}
    	for (int i = 0;i<level;i++)
    	{
    		fout << "\t";
    	}
    	if (node->parentNode!=NULL && node->parentNode->leftNode == node)
    	{
    		fout << "L:";
    	}
    	if (node->parentNode!=NULL && node->parentNode->rightNode == node)
    	{
    		fout << "R:";
    	}
    
    	fout << node->key << endl;
    	Preorder_Walk(node->leftNode,fout,level + 1);
    	Preorder_Walk(node->rightNode,fout,level + 1);
    }
    
    template<class T,class P>
    void BinaryTree<T,P>::LeftRotate(TreeNode<T,P>* x)
    {
    	assert(x != NULL);
    	assert(x->rightNode !=NULL);
    
    	TreeNode<T,P>* y = x->rightNode;
    	TreeNode<T,P>* p = x->parentNode;
    
    	x->rightNode = y->leftNode;
    	if (x->rightNode)
    	{
    		x->rightNode->parentNode = x;
    	}
    
    	y->parentNode = p;
    
    	if (p)
    	{
    		if (x == p->leftNode)
    			p->leftNode = y;
    		else
    			p->rightNode = y;
    	}else{
    		root = y;
    	}
    
    	x->parentNode = y;
    	y->leftNode = x;
    }
    template<class T,class P>
    void BinaryTree<T,P>::RightRotate(TreeNode<T,P>* y)
    {
    	assert(y != NULL);
    	assert(y->leftNode !=NULL);
    
    	TreeNode<T,P>* x = y->leftNode;
    	TreeNode<T,P>* p = y->parentNode;
    
    	y->leftNode = x->rightNode;
    	if (y->leftNode)
    	{
    		y->leftNode->parentNode = y;
    	}
    
    	x->parentNode = p;
    
    	if (p)
    	{
    		if (y == p->leftNode)
    			p->leftNode = x;
    		else
    			p->rightNode = x;
    	}else{
    		root = x;
    	}
    
    	y->parentNode = x;
    	x->rightNode = y;
    }
    
    
    //返回x为被删节点的孩子,p为被删节点的父亲(两者都可能为空)
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::Delete(TreeNode<T,P>* z,TreeNode<T,P>*& x,TreeNode<T,P>*& p)
    {
    	if (z == NULL)
    	{
    		x = p = NULL;
    		return NULL;
    	}
    
    	TreeNode<T,P>* y;
    	if (z->leftNode == NULL || z->rightNode == NULL)
    	{
    		y = z;
    	}else
    	{
    		y = TreeSuccessor(z);
    	}
    
    	//////////////////////////////////////////////////////////////////////////
    	//y 最多只有一个孩子
    
    	if (y->leftNode!=NULL)
    	{
    		x = y->leftNode;
    	}else{
    		x = y->rightNode;
    	}
    
    	//如果x为空,则y没有孩子
    	p = y->parentNode;
    	if (x != NULL)
    	{
    		x->parentNode = p;
    	}
    	if (p == NULL)
    	{
    		root = x;
    	}else{
    		if (y == p->leftNode)
    			p->leftNode = x;
    		else
    			p->rightNode = x;
    	}
    
    	if (y!=z)
    	{
    		z->key = y->key;
    		z->sateliteData = y->sateliteData;
    	}
    	return y;
    }
    
    
    //返回插入节点的父节点
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::Insert(TreeNode<T,P>* z)
    {
    	TreeNode<T,P>* y = NULL;
    	TreeNode<T,P>* x = root;
    	while (x != NULL)
    	{
    		y = x;
    		if (z->key < x->key)
    		{
    			x = x->leftNode;
    		}else{
    			x = x->rightNode;
    		}
    	}
    	z->parentNode = y;
    	if (y == NULL)
    	{
    		root = z;
    	}else{
    		if (z->key < y->key)
    		{
    			y->leftNode = z;
    		}else
    		{
    			y->rightNode = z;
    		}
    	}
    	return y;
    }
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::TreeSuccessor(TreeNode<T,P>* node)
    {
    	if (node == NULL)
    	{
    		return NULL;
    	}
    	if (node->rightNode!=NULL)
    	{
    		return Min(node->rightNode);
    	}
    	TreeNode<T,P>* y = node->parentNode;
    	while (y!=NULL && y->rightNode==node)  //node是y的右孩子
    	{
    		node = y;
    		y = node->parentNode;
    	}
    	return y;
    }
    
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::Max()
    {
    	return Max(root);
    }
    
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::Max(TreeNode<T,P>* node)
    {
    	if (node == NULL)
    	{
    		return NULL;
    	}
    	if (node->rightNode!=NULL)
    	{
    		 node = node->rightNode;
    	}
    	return node;
    }
    
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::Min()
    {
    	return Min(root);
    }
    
    template<class T,class P>
    TreeNode<T,P>* BinaryTree<T,P>::Min(TreeNode<T,P>* node)
    {
    	if (node == NULL)
    	{
    		return NULL;
    	}
    	if (node->leftNode!=NULL)
    	{
    		node = node->leftNode;
    	}
    	return node;
    }
    
    template<class T,class P>
    void BinaryTree<T,P>::Inorder_Walk(ofstream & fout)
    {
    	Inorder_Walk(root,fout);
    }
    
    template<class T,class P>
    void BinaryTree<T,P>::Inorder_Walk(TreeNode<T,P>* node,ofstream & fout)
    {
    	if (node != NULL)
    	{
    		Inorder_Walk(node->leftNode,fout);
    		fout << node->key << endl;
    		Inorder_Walk(node->rightNode,fout);
    	}
    }
    
    template<class T,class P>
    TreeNode<T,P> * BinaryTree<T,P>::Search(T key)
    {
    	return Search(root,key);
    }
    template<class T,class P>
    TreeNode<T,P> * BinaryTree<T,P>::Search(TreeNode<T,P>* node,T key)
    {
    	if (node == NULL || node->key == key)
    	{
    		return node;
    	}
    	if (key < node->key)
    	{
    		return Search(node->leftNode,key);
    	}
    	return Search(node->rightNode,key);
    }
    
    template<class T,class P>
    TreeNode<T,P> * BinaryTree<T,P>::Iterative_Search(T key)
    {
    	return Iterative_Search(root,key);
    }
    template<class T,class P>
    TreeNode<T,P> * BinaryTree<T,P>::Iterative_Search(TreeNode<T,P>* node,T key)
    {
    	while (node != NULL && node->key!=key)
    	{
    		if (key < node->key)
    		{
    			node = node->leftNode;
    		}else
    		{
    			node = node->rightNode;
    		}
    	}
    	return node;
    }
    
    #endif

    红黑树继承了上面的搜索二叉树,代码如下

    //e:\Projects\CLRS\CLRS\RBTree.h
    #ifndef RBTREE_H
    #define RBTREE_H
    #include <queue>
    using namespace std;
    
    /*
      我们的实现不采用书中的NIL叶的概念,这样需要4个ruler
      1. 每个节点非红即黑(null没有颜色的概念)
      2. 根是黑色的(如果树为空,颜色就没了)
      3. 若某个节点node为红,则其孩子都是黑的
      4. 对每个节点,其到子孙叶子节点的路径上,所包含的黑色数相同
    
      由4和3,隐含的一点就是,某个节点为红,则其要么两个孩子为空,要么都是黑孩子。
    */
    enum NodeColor
    {
    	BLACK,
    	RED
    };
    template<class T,class P>
    class RBNode:public TreeNode<T,P>
    {
    public:
    	RBNode(T key,P* pData = NULL):TreeNode<T,P>(key,pData)
    	{
    
    	}
    	NodeColor color;
    };
    template<class T,class P>
    class RBTree:public BinaryTree<T,P>
    {
    public:
    	RBTree():BinaryTree<T,P>()
    	{
    	}
    	void Insert(RBNode<T,P>* z);
    	RBNode<T,P>* Delete(RBNode<T,P>* z);
    
    	void Preorder_Walk(ofstream &fout);
    	void Preorder_Walk(RBNode<T,P>* node,ofstream & fout,int level);
    	bool IsRBTree(); //计算是否符合红黑树的条件
    	int GetBlackNodes(RBNode<T,P>* node);//获取node到底的黑节点个数,如果不符合红黑树的条件,则返回-1
    	//RBNode<T,P> * Search(T key);
    	
    };
    template<class T,class P>
    int RBTree<T,P>::GetBlackNodes(RBNode<T,P>* node)
    {
    	RBNode<T,P> * nl = (RBNode<T,P>*)node->leftNode;
    	RBNode<T,P> * nr = (RBNode<T,P>*)node->rightNode;
    	int lnum = 0;
    	int rnum = 0;
    	if(nl!=NULL)
    	{
    		lnum = GetBlackNodes(nl);
    		if (lnum == -1)
    		{
    			return -1;
    		}
    	}
    	if (nr !=NULL)
    	{
    		rnum = GetBlackNodes(nr);
    		if (rnum == -1)
    		{
    			return -1;
    		}
    	}
    	
    	if(lnum != rnum)
    		return -1;
    	return lnum + (node->color == BLACK);
    }
    
    template<class T,class P>
    bool RBTree<T,P>::IsRBTree()
    {
    	if (root == NULL)
    	{
    		return true;
    	}
    	if(((RBNode<T,P>*)root)->color == RED)
    		return false;
    
    	queue<RBNode<T,P>* > nodes;
    	nodes.push((RBNode<T,P>*)root);
    	while (!nodes.empty())
    	{
    		RBNode<T,P>* node = nodes.front();
    		nodes.pop();
    		RBNode<T,P> * nl = (RBNode<T,P>*)node->leftNode;
    		RBNode<T,P> * nr = (RBNode<T,P>*)node->rightNode;
    		if (node->color == RED)
    		{
    			if ((nl==NULL && nr == NULL) ||
    				(nl!=NULL && nr != NULL && nl->color == BLACK && nr->color == BLACK))
    			{
    				//do nothing
    			}else{
    				return false;
    			}
    		}
    		if (nl!=NULL)
    		{
    			nodes.push(nl);
    		}
    		if (nr!=NULL)
    		{
    			nodes.push(nr);
    		}
    	}
    
    
    	int blackNodeNum = GetBlackNodes((RBNode<T,P>*)root);
    	if (blackNodeNum == -1)
    	{
    		return false;
    	}
    	return true;
    		
    }
    
    //template<class T,class P>
    //RBNode<T,P>* RBTree<T,P>::Search(T key)
    //{
    //	TreeNode<T,P>* node = BinaryTree<T,P>::Search(key);
    //	return (RBNode<T,P>*)node;
    //}
    //
    template<class T,class P>
    void RBTree<T,P>::Preorder_Walk(ofstream &fout)
    {
    	if (root == NULL)
    	{
    		fout << "empty tree"<<endl;
    	}
    	Preorder_Walk((RBNode<T,P>*)root,fout,0);
    	fout << (IsSorted()?"sorted":"unsorted") << endl;
    	fout << (IsRBTree()?"rbtree":"not a rbtree") << endl;
    
    }
    
    
    //以后可以传入一个函数指针visit节点
    template<class T,class P>
    void RBTree<T,P>::Preorder_Walk(RBNode<T,P>* node,ofstream & fout,int level)
    {
    	if (node == NULL)
    	{
    		return;
    	}
    	for (int i = 0;i<level;i++)
    	{
    		fout << "\t";
    	}
    	if (node->parentNode!=NULL && node->parentNode->leftNode == node)
    	{
    		fout << "L:";
    	}
    	if (node->parentNode!=NULL && node->parentNode->rightNode == node)
    	{
    		fout << "R:";
    	}
    
    	fout << node->key << " " << (node->color == RED? "red":"black") << endl;
    	Preorder_Walk((RBNode<T,P>*)node->leftNode,fout,level + 1);
    	Preorder_Walk((RBNode<T,P>*)node->rightNode,fout,level + 1);
    }
    //
    template<class T,class P>
    RBNode<T,P>* RBTree<T,P>::Delete(RBNode<T,P>* z)
    {
    	RBNode<T,P>* x;
    	RBNode<T,P>* p;
    	TreeNode<T,P>* _x;
    	TreeNode<T,P>* _p;
    	RBNode<T,P>* y = (RBNode<T,P>*)BinaryTree<T,P>::Delete(z,_x,_p);
    	x = (RBNode<T,P>*)_x;
    	p = (RBNode<T,P>*)_p;
    
    	//x为被删节点y的孩子,p为y的父亲,现在为x的父亲
    	if (y==NULL || y->color == RED)
    	{
    		return y;
    	}
    	
    	//y为黑色节点
    
    	while (x != root && (x == NULL || x->color == BLACK))
    	{
    		RBNode<T,P>* w;
    		if (x == p->leftNode)//p不可能为null,否则x就为root了,就不会进入此循环
    		{
    			w = (RBNode<T,P>*)p->rightNode;//w必定不空
    			//case 1
    			if (w->color == RED) //此时w的两个孩子均为黑节点(非空)
    			{
    				p->color = RED;
    				w->color = BLACK;
    				LeftRotate(p);
    				w = (RBNode<T,P>*)p->rightNode;
    			}
    
    			//w必定是黑节点(非空),p的颜色未知
    			RBNode<T,P>* wl = (RBNode<T,P>*)w->leftNode;
    			RBNode<T,P>* wr = (RBNode<T,P>*)w->rightNode;
    			if ((wl == NULL && wr == NULL) ||
    				( wl!=NULL&&wr!=NULL && 
    				wl->color == BLACK && wr->color == BLACK)
    				)
    			{
    				//case 2
    				w->color = RED;
    				x = p;
    			}else{
    
    				//case 3
    				if(wr == NULL || wr->color == BLACK)
    				{
    					//w->leftNode必为红
    					wl->color = BLACK;
    					RightRotate(w);
    					w = (RBNode<T,P>*)p->rightNode;
    				}
    
    				//case 4
    				//此时 w->right必为红
    				wr = (RBNode<T,P>*)w->rightNode;
    				wr->color = BLACK;
    				w->color = p->color;
    				p->color = BLACK;
    				LeftRotate(p);
    				x = (RBNode<T,P>*)root;
    			}
    		}else{
    			w = (RBNode<T,P>*)p->leftNode;//w必定不空
    			//case 1
    			if (w->color == RED) //此时w的两个孩子均为黑节点(非空)
    			{
    				p->color = RED;
    				w->color = BLACK;
    				RightRotate(p);
    				w = (RBNode<T,P>*)p->leftNode;
    			}
    
    			//w必定是黑节点(非空),p的颜色未知
    			RBNode<T,P>* wl = (RBNode<T,P>*)w->leftNode;
    			RBNode<T,P>* wr = (RBNode<T,P>*)w->rightNode;
    			if ((wl == NULL && wr == NULL) ||
    				( wl!=NULL&&wr!=NULL && 
    				wl->color == BLACK && wr->color == BLACK)
    				)
    			{
    				//case 2
    				w->color = RED;
    				x = p;
    			}else{
    
    				//case 3
    				if(wl == NULL || wl->color == BLACK)
    				{
    					//w->rightNode必为红
    					wr->color = BLACK;
    					LeftRotate(w);
    					w = (RBNode<T,P>*)p->leftNode;
    				}
    
    				//case 4
    				//此时 w->left必为红
    				wl = (RBNode<T,P>*)w->leftNode;
    				wl->color = BLACK;
    				w->color = p->color;
    				p->color = BLACK;
    				RightRotate(p);
    				x = (RBNode<T,P>*)root;
    			}
    
    		}
    
    		if (x!=NULL)
    		{
    			p = (RBNode<T,P>*)x->parentNode;
    		}
    	}
    
    	if(x!=NULL)
    		x->color = BLACK;
    	return y;
    }
    
    template<class T,class P>
    void RBTree<T,P>::Insert(RBNode<T,P>* z)
    {
    	//z是外面生成的节点;
    	RBNode<T,P>* parent = (RBNode<T,P>*)BinaryTree<T,P>::Insert((TreeNode<T,P>*)z);//返回为新插入点的父亲
    	z->color = RED;
    	z->leftNode = z->rightNode = NULL;
    	RBNode<T,P> * uncle;
    	RBNode<T,P>* grandParent;
    	//RBInsertFixup
    	while (parent!=NULL && parent->color == RED)
    	{
    		RBNode<T,P>* grandParent = (RBNode<T,P>*)parent->parentNode;//grandParent肯定非空,且为黑色
    		if (parent == grandParent->leftNode)//parent是左孩子
    		{
    			uncle = (RBNode<T,P>*)grandParent->rightNode; 
    			//如果uncle是红色,则
    			if (uncle!=NULL && uncle->color == RED)
    			{
    				parent->color = uncle->color = BLACK;
    				grandParent->color = RED;
    				z = grandParent;
    			}else{//uncle是黑色或空
    				if (z == parent->rightNode) //z是右孩子
    				{
    					z = parent;
    					LeftRotate(z);
    					parent = (RBNode<T,P>*)z->parentNode;
    				}
    
    				parent->color = BLACK;
    				grandParent->color = RED;
    				RightRotate((TreeNode<T,P>*)grandParent);
    				//此时结束了
    			}
    		}else{ //parent是右孩子
    			uncle = (RBNode<T,P>*)grandParent->leftNode;
    			if (uncle!=NULL && uncle->color == RED)
    			{
    				parent->color = uncle->color = BLACK;
    				grandParent->color = RED;
    				z = grandParent;
    			}else{
    				if (z == parent->leftNode)
    				{
    					z = parent;
    					RightRotate(z);
    					parent = (RBNode<T,P>*)z->parentNode;
    				}
    				parent->color = BLACK;
    				grandParent->color = RED;
    				LeftRotate(grandParent);
    			}
    		}
    		parent = (RBNode<T,P>*)z->parentNode;
    	}
    	((RBNode<T,P>*)root)->color = BLACK;
    }
    
    #endif
    测试代码如下
    #include "BinaryTree.h"
    #include "RBTree.h"
    #include "algorithm.h"
    #include <vector>
    #include <iostream>
    #include <fstream>
    using namespace std;
    using namespace CLRS;
    void TestInsertSort()
    {
    	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
    	InsertSort(arr,sizeof(arr) / sizeof(int));
    	copy(arr,arr + sizeof(arr) / sizeof(int),ostream_iterator<int>(cout, "\t"));
    	cout << endl;
    }
    void TestMergeSort()
    {
    	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
    	InsertSort(arr,sizeof(arr) / sizeof(int));
    	copy(arr,arr + sizeof(arr) / sizeof(int),ostream_iterator<int>(cout, "\t"));
    	cout << endl;
    }
    void TestRBTree()
    {
    	ofstream fout("log.txt");
    	RBTree<int,int> tree;
    	
    
    	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
    	for (int i = 0;i<sizeof(arr) / sizeof(int);i++)
    	{
    		RBNode<int,int> * node = new RBNode<int,int>(arr[i]);
    		tree.Insert(node);
    		fout << "after:"<<arr[i]<<" inserted"<<endl;
    		tree.Preorder_Walk(fout);
    	}
    
    	int arr2[] = {5,4,1,2,3,8,9,32,1,5,7,213,7,6,3,345,52};
    	for (int i = 0;i<sizeof(arr2) / sizeof(int);i++)
    	{
    		RBNode<int,int>* node = (RBNode<int,int>*)tree.Search(arr2[i]);
    		if (node != NULL)
    		{
    			RBNode<int,int>* _node = tree.Delete(node);
    			delete _node;
    			
    			fout << arr2[i] <<" deleted"<<endl;
    			tree.Preorder_Walk(fout);
    
    		}
    	}
    	fout.close();
    
    }
    
    void TestBinaryTree()
    {
    	ofstream fout("log.txt");
    	BinaryTree<int,int> tree;
    
    	int arr[] = {4,5,1,2,3,7,8,9,32,345,1,52,5,7,213,6,3};
    	//int arr[] = {4,1,2,1,3,3};
    	for (int i = 0;i<sizeof(arr) / sizeof(int);i++)
    	{
    		tree.Insert(new TreeNode<int,int>(arr[i]));
    		fout << "after:"<<arr[i]<<" inserted"<<endl;
    		tree.Preorder_Walk(fout);
    	}
    
    	int arr2[] = {5,4,1,2,3,8,9,32,1,5,7,213,7,6,3,345,52};
    	for (int i = 0;i<sizeof(arr2) / sizeof(int);i++)
    	{
    		TreeNode<int,int>* node = tree.Search(arr2[i]);
    		if (node != NULL)
    		{
    			TreeNode<int,int>* x;
    			TreeNode<int,int>* p;
    
    			TreeNode<int,int>* _node = tree.Delete(node,x,p);
    			delete _node;
    			fout << arr2[i] <<" deleted"<<endl;
    			tree.Preorder_Walk(fout);
    
    		}
    	}
    	fout.close();
    }
    //template<class T,class P>
    //class A
    //{
    //public:
    //	void func2(int x)
    //	{
    //		cout << "A<T,P>::func2"<<endl;
    //	}
    //};
    //template<class T,class P>
    //class B:public A<T,P>
    //{
    //public:
    //	int func2()
    //	{
    //		A<T,P>::func2(4);
    //		cout << "B<T,P>:func2"<<endl;
    //		return 0;
    //	}
    //};
    //void Test()
    //{
    //	B<int,int> b;
    //	A<int,int>* pa = &b;
    //	B<int,int>* pb = &b;
    //	cout << (pa == pb) << endl;
    //	b.func2();
    //}
    int main(int argc,char* argv[])
    {
    	//TestInsertSort();
    	//TestMergeSort();
    	//TestBinaryTree();
    	TestRBTree();
    	//Test();
    	return 0;
    }
  • 相关阅读:
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(88)-Excel导入和导出-主从表结构导出
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(89)-EF执行SQL语句与存储过程
    ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试
    ASP.NET MVC5+EF6+EasyUI 仓库管理系统
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(91)-EF 连接 MySql
    样例功能截图
    Fastreport.net 如何在开发MVC应用程序时使用报表
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(90)-EF 扩展操作
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(87)-MVC Excel导入和导出
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(86)-日程管理-fullcalendar插件用法
  • 原文地址:https://www.cnblogs.com/speedmancs/p/1859779.html
Copyright © 2011-2022 走看看