⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsort.h

📁 可能是能找到的处理速度最快
💻 H
字号:
#ifndef _GSORT_H_
#define _GSORT_H_
//#include"tlink.h"
#include<stdio.h>
/*
Type T must provide the following methous:
	-					:	Compare operator ,return -1,0,1
	(*func)()			:	Visit operate function
	Copy Constructor	:	a copy constructor to copy objects if in Own mode
*/
template<class T,class T2=T> class CTree;
template<class T,class T2=T> class CTreeNode
{
	T *data;
	CTreeNode<T,T2> *left;
	CTreeNode<T,T2> *right;
	bool Own;
	int balance;
//	int Count;
public:
	T *Data()
	{
		return data;
	}
	CTreeNode():
	{
		data=NULL;
		left=NULL;
		right=NULL;
		Own=FALSE;
		balance=0;
	}
	CTreeNode(T *t,bool O=false,CTreeNode<T,T2> *l=NULL,CTreeNode<T,T2> *r=NULL)	// point-to version
	{
		Own=O;
		if (Own)
			data=new T(*t);
		else
			data=t;
		left=l;
		right=r;
		balance=0;
	}
	CTreeNode(T &t,CTreeNode<T,T2> *l=NULL,CTreeNode<T,T2> *r=NULL)	// copy version
	{
		Own=true;
		data=new T(t);
		left=l;
		right=r;
		balance=0;
	}
	~CTreeNode()
	{
		if (Own)
			delete data;
	}
	friend void SearchAndAdd(CTreeNode<T,T2> *t1, CTree<T,T2>  &t2, CTree<T,T2> &NewTree);
	friend void Copy(CTreeNode<T,T2> *t1, CTree<T,T2> &NewTree);
	friend class CTree<T,T2>;
};

enum SearchType {Equal,Left,Right};

template<class T,class T2=T>
class CTree
{
	CTreeNode<T,T2> *Root;
	CTreeNode<T,T2> *Current;
	bool Own;
	int DelDuplicate;
	bool ShowMsg;
	CTreeNode<T,T2> *Add(CTreeNode<T,T2> *, CTreeNode<T,T2> *t =NULL);
	void Clear(CTreeNode<T,T2> *t=NULL);
protected:
	unsigned long count;
public:
	unsigned long Count()
	{
		return count;
	}
	T *Add(T *p)	// point-to version
	{
		CTreeNode<T,T2> *p2=new CTreeNode<T,T2>(p,Own);
		if(Root)
		{
			CTreeNode<T,T2> *p3=Add(p2);
			if (p3!=p2)
				delete p2;
			return p3->data;
		}
		else
		{
			Root=p2;
			return p2->data;
		}
	}
	T *Add(T &p)		// copy version
	{
		CTreeNode<T,T2> *p2=new CTreeNode<T,T2>(p);
		if(Root)
		{
			CTreeNode<T,T2> *p3=Add(p2);
			if (p3!=p2)
				delete p2;
			return p3->data;
		}
		else
		{
			Root=p2;
			return p2->data;
		}
	}
	CTree()
	{
		Root=NULL;
		DelDuplicate=true;
		Current=NULL;
		Own=FALSE;
		ShowMsg=true;
		count=0;
	}
	CTree(bool O,bool NoDulp=true,int=true)
	{
		Own=O;
		DelDuplicate=NoDulp;
		Root=NULL;
		Current=NULL;
		count=0;
	}
	~CTree()
	{
		if (Root)
		{
			Clear();
			delete Root;
		}
	}
	void LeftMidRight(void (*func)(T *),CTreeNode<T,T2> *t=NULL);
	void RightMidLeft(void (*func)(T *),CTreeNode<T,T2> *t=NULL);
	void MidLeftRight(void (*func)(T *),CTreeNode<T,T2> *t=NULL);
//	T *FindFirst(T &,SearchType tp=Equal,CTreeNode<T,T2> *t=0);
//	T *FindNext(T &,SearchType tp=Equal);
	T *FindFirst(T2 &,SearchType tp=Equal,CTreeNode<T,T2> *t=0);
	T *FindNext(T2 &,SearchType tp=Equal);
	friend CTree operator&(CTree &tree1, CTree &tree2);		// get the same part and build a tree, compare by data only
	CTree &operator=(CTree &tree2);				
	CTree(CTree &tree2);					// copy constructor , copy pointer only
	CTreeNode<T,T2> *CurrentNode()
	{
		return Current;
	}
};
template<class T, class T2>
CTreeNode<T,T2> *CTree<T,T2>::Add(CTreeNode<T,T2> *tree2,CTreeNode<T,T2> *tree1)// tree2 add to tree1
{   
	if(tree2==NULL)
		return NULL;
	CTreeNode<T,T2> *most_recent=Root,*most_recent_parent=NULL,*parent=NULL,*new_Root=NULL;
	CTreeNode<T,T2> *p=NULL;//,*tree1=Root;
	bool AdjustBalance=false;
	if (tree1==NULL)
		tree1=Root;
	if (tree1==Root)
		AdjustBalance=true;
	while(tree1)
	{
		if (tree1->balance!= 0)
		{
			most_recent = tree1;
			most_recent_parent = parent;
		}
		int a=*(tree2->data)-*(tree1->data);
		if (a==0)
		{
			if (DelDuplicate)
				return tree1;
		}
		if (a<=0)
		{
			if (tree1->left)
			{
				parent=tree1;
				tree1=tree1->left;
			}
			else
			{
				tree1->left=tree2;
				break;
			}
		}
		else
		{
			if ( tree1->right)
			{
				parent=tree1;
				tree1=tree1->right;
			}
			else
			{
				tree1->right=tree2;
				break;
			}
		}
	}
	count++;
	if (!AdjustBalance)
		return tree2;
	int rebal_direc;
	if ( *(tree2->data)-*(most_recent->data) > 0)
	{
		tree1 = most_recent->right;
		rebal_direc = -1;
	}
	else
	{
		tree1 = most_recent->left;
		rebal_direc = +1;
	}
	CTreeNode<T,T2> *most_recent_child = tree1;
	while (tree1!= tree2)
	{
		if (*(tree2->data)-*(tree1->data) > 0)
		{
			tree1-> balance = -1;// hight of right is increased by 1
			tree1 = tree1->right;
		}
		else
		{
			tree1->balance = +1;				// hight of left is increased by 1
			tree1 = tree1->left;
		}
	}
	// need to check if the balance of
	// the tree is alright
	int unbal_flag = 1;
	if (most_recent-> balance == 0)
	{
		// tree is not unbalanced
		most_recent->balance = rebal_direc;
		unbal_flag = 0;
	}
	if ( (most_recent->balance + rebal_direc) == 0 )
	{
		// tree is not unbalanced
		most_recent->balance = 0;
		unbal_flag = 0;
	}
	if (unbal_flag == 1)
	{
		// Tree is unbalanced. determine
		// rotation direction, and rotate.
		if (rebal_direc == +1)
		{
			// left subtree is imbalanced
			// Rotate left
			if (most_recent_child->balance == +1)
			{
				most_recent->left = most_recent_child->right;
				most_recent_child->right = most_recent;
				most_recent->balance = 0;
				most_recent_child->balance = 0;
			}
			else
			{
				new_Root = most_recent_child->right;
				most_recent_child->right = new_Root->left;
				most_recent->left = new_Root->right;
				new_Root->left = most_recent_child;
				new_Root->right = most_recent;
				switch (new_Root->balance)
				{
				case +1:
					most_recent->balance = -1;
					most_recent_child->balance = 0;
					break;
				case -1:
					most_recent_child->balance = 1;
					most_recent->balance = 0;
					break;
				case 0:
					most_recent_child->balance = 0;
					most_recent->balance = 0;
					break;
				}// end of the switch statement
				new_Root->balance = 0;
				most_recent_child = new_Root;
			}
		}
		else
		{
			// right substree is unbalanced
			if (most_recent_child->balance == -1)
			{
				most_recent->right = most_recent_child->left;
				most_recent_child->left = most_recent;
				most_recent->balance = 0;
				most_recent_child->balance = 0;
			}
			else
			{
				new_Root = most_recent_child->left;
				most_recent_child->left = new_Root->right;
				most_recent->right = new_Root->left;
				new_Root->right = most_recent_child;
				new_Root->left = most_recent;
				switch (new_Root->balance)
				{
				case -1:				// Should be -1
					most_recent->balance = 1;
					most_recent_child->balance = 0;
					break;
				case +1:				// Should be +1
					most_recent_child->balance = -1;
					most_recent->balance = 0;
					break;
				case 0:
					most_recent_child->balance = 0;
					most_recent->balance = 0;
					break;
				}
				new_Root->balance = 0;
				most_recent_child = new_Root;
			}// end of the else
		}  // end of the if rebal_direc = -1

		if (most_recent_parent == NULL)
			Root = most_recent_child;
		else if (most_recent == most_recent_parent->left)
			most_recent_parent->left = most_recent_child;
		else if (most_recent == most_recent_parent->right)
			most_recent_parent->right = most_recent_child;
	} // end of if unbalanced
	return tree2;
}

template<class T, class T2>
void CTree<T,T2>::LeftMidRight(void (*func)(T *),CTreeNode<T,T2> *tree)
{
	if (tree==NULL)
		tree=Root;
	if (tree->left!=NULL)
		LeftMidRight(func,tree->left);

	(*func)(tree->data);

	if (tree->right!=NULL)
		LeftMidRight(func,tree->right);
}

template<class T, class T2> void CTree<T,T2>::MidLeftRight(void (*func)(T *),CTreeNode<T,T2> *tree)
{
	if (tree==NULL)
		tree=Root;
	(*func)(tree->data);

	if (tree->left!=NULL)
		MidLeftRight(func,tree->left);

	if (tree->right!=NULL)
		MidLeftRight(func,tree->right);
}

template<class T, class T2> void CTree<T,T2>::RightMidLeft(void (*func)(T *),CTreeNode<T,T2> *tree)
{
	if (tree==NULL)
		tree=Root;
	if (tree->right!=NULL)
		RightMidLeft(func,tree->right);

	(*func)(tree->data);

	if (tree->left!=NULL)
		RightMidLeft(func,tree->left);
}

template<class T, class T2> void CTree<T,T2>::Clear(CTreeNode<T,T2> *tree)
{
	if (tree==NULL)
		tree=Root;
	if (tree->left)
	{
		Clear(tree->left);
		delete tree->left;
		tree->left=NULL;
	}
	if (tree->right)
	{
		Clear(tree->right);
		delete tree->left;
		tree->right=NULL;
	}
}

template<class T, class T2>
T *CTree<T,T2>::FindFirst(T2 &str,SearchType tp,CTreeNode<T,T2> *tree1)
{
	if (tree1==NULL)
		tree1=Root;
	CTreeNode<T,T2> *left=tree1,*right=tree1;
	while(tree1)
	{
		int a=*(tree1->data)-str;
		if (a==0)		//if match
		{
			Current=tree1;
			return tree1->data;
		}
		else	if (a>0)		// if not match and the str is smaller than the node
		{
			left=tree1;
			tree1=tree1->left;	// turn to left branch
		}
		else
		{
			right=tree1;
			tree1=tree1->right;
		}
	}
	Current=NULL;
	switch(tp)
	{
	case Equal:
		return NULL;	// no the equal one
	case Left:
		Current=left;
		return left->data;		// user can select return  the bigger one (the smallest that bigger than the target) >=
	case Right:
		Current=right;
		return right->data;		// or the smaller one(the biggest that smaller than the target) <=
	}
	return NULL;
}

template<class T,class T2>
T *CTree<T,T2>::FindNext(T2 &str,SearchType tp)
{
	if (Current)
		return FindFirst(str,Current->left,tp);
	else
		return NULL;
}

template<class T, class T2>
void SearchAndAdd(CTreeNode<T,T2> *t1, CTree<T,T2>  &t2, CTree<T,T2> &NewTree)
{
	if (t1->left)
		SearchAndAdd(t1->left,t2,NewTree);
	if (t2.FindFirst(*(t1->data)))
		NewTree.Add(t1->data);
	if (t1->right)
		SearchAndAdd(t1->right,t2,NewTree);
}

template<class T,class T2> CTree<T,T2> operator&(CTree<T,T2> &tree1, CTree<T,T2> &tree2)		// get the same part and build a tree, compare by data 
	{
		CTree<T,T2> newtree(/*own the data=*/false,/*kill_dup=*/false,/*showmsg=*/false);
		SearchAndAdd(tree1.Root,tree2,newtree);
		return newtree;
	}

template<class T, class T2> 
void Copy(CTreeNode<T,T2> *t1, CTree<T,T2> &NewTree)
{
	if (t1==NULL) return;
	if (t1->left)
		Copy(t1->left,NewTree);
	NewTree.Add(t1->data);
	if (t1->right)
		Copy(t1->right,NewTree);
}
template<class T, class T2>
CTree<T,T2> &CTree<T,T2>::operator=(CTree<T,T2> &tree2)
	{
		Clear();
		delete Root;
		Root=NULL;
		Current=NULL;
		DelDuplicate=tree2.DelDuplicate;
		Own=false;
		count=tree2.count;
		Copy(tree2.Root,*this);
		return *this;
	}
template <class T,class T2> 
CTree<T,T2>::CTree<T,T2>(CTree &tree2)					// copy constructor , copy pointer only
	{	
		count=tree2.count;
		Root=NULL;
		Current=NULL;
		DelDuplicate=tree2.DelDuplicate;
		Own=false;
		Copy(tree2.Root,*this);
	}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -