二叉樹之AVL樹

高度爲 h 的 AVL 樹,節點數 N 最多2^h − 1; 最少 N( h)= N( h− 1) + N( h− 2) + 1。
最少節點數n 如以 斐波那契數列能夠用數學概括法證實:
即:
N(0) = 0 (表示 AVL Tree 高度爲0的節點總數)
N(1) = 1 (表示 AVL Tree 高度爲1的節點總數)
N(2) = 2 (表示 AVL Tree 高度爲2的節點總數)
N( h)= N( h− 1) + N( h− 2) + 1 (表示 AVL Tree 高度爲h的節點總數)
 
 
#include <iostream.h> 
#include <math.h>; 
#include <stdlib.h>; //創建一個整數類型 
 
#define MAXSIZE 512
 
typedef struct obj_n_t { int obj_key; } obj_node_t; //創建樹結點的基本機構 
typedef struct tree_n_t { int key; struct tree_n_t *left,*right; int height;
} tree_node_t; //創建堆棧 
 
tree_node_t *stack[MAXSIZE]; //warning!the tree can contain 256 leaves at most! 
int i=0; //堆棧計數器 //堆棧清空 
void stack_clear() 
{ 
    while(i!=0)
    {
        stack[i-1]=NULL;
        i--;
    }
}
//堆棧爲空
int stack_empty()
{
    return(i==0);
}
//入棧函數
int push(tree_node_t *node)
{
    if(i<MAXSIZE)
    {
        stack[i++]=node;
        return(0);
    }
    else
    return(-1);
}
//出棧函數
tree_node_t *pop()
{
    if(i>0)
    return(stack[--i]);
    else
    return(0);
}
//創建get_node函數,用於動態分配內存空間
tree_node_t *get_node()
{
    tree_node_t *tmp;
    tmp=(tree_node_t *)malloc(sizeof(tree_node_t));
    return(tmp);
}
//創建return_node函數,用於釋放內存
void return_node(tree_node_t *free_node)
{
    free(free_node);
}
//創建左旋轉函數
void left_rotation(tree_node_t *node)
{
    tree_node_t *tmp;
    int tmp_key;
    tmp=node->left;
    tmp_key=node->key;
    node->left=node->right;
    node->key=node->right->key;
    node->right=node->left->right;
    node->left->right=node->left->left;
    node->left->left=tmp;
    node->left->key=tmp_key;
}
//創建右旋轉函數
void right_rotation(tree_node_t *node)
{
    tree_node_t *tmp;
    int tmp_key;
    tmp=node->right;
    tmp_key=node->key;
    node->right=node->left;
    node->key=node->left->key;
    node->left=node->right->left;
    node->right->left=node->right->right;
    node->right->right=tmp;
    node->right->key=tmp_key;
}
int rebalance(tree_node_t *node)
{
    int finished=0;
    while(!stack_empty()&&!finished)
    {
        int tmp_height,old_height;
        node=pop(); //back to the root along the search path
        old_height=node->height;
        if(node->left->height-node->right->height==2)
        {
            if(node->left->left->height-node->right->height==1)
            {
				right_rotation(node);
				node->right->height=node->right->left->height+1;
				node->height=node->right->height+1;
			}
			else
			{
				left_rotation(node->left);
				right_rotation(node);
				tmp_height=node->left->left->height;
				node->left->height=tmp_height+1;
				node->right->height=tmp_height+1;
				node->height=tmp_height+2;
			}
		}
		else if(node->left->height-node->right->height==-2)
		{
			if(node->right->right->height-node->left->height==1)
			{
				left_rotation(node);
				node->left->height=node->left->right->height+1;
				node->height=node->left->height+1;
			}
			else
			{
				right_rotation(node->right);
				left_rotation(node);
				tmp_height=node->right->right->height;
				node->left->height=tmp_height+1;
				node->right->height=tmp_height+1;
				node->height=tmp_height+2;
			}
		}
		else
		{
			if(node->left->height>node->right->height)
				node->height=node->left->height+1;
			else
				node->height=node->right->height+1;
		}
		if(node->height==old_height)
			finished=1;
	}
	stack_clear();
	return(0);
}
//創建creat_tree函數,用於創建一顆空樹
tree_node_t *creat_tree()
{
	tree_node_t *root;
	root=get_node();
	root->left=root->right=NULL;
	root->height=0;
	return(root); //build up an empty tree.the first insert bases on the empty tree.
}
//創建find函數,用於查找一個對象
obj_node_t *find(tree_node_t *tree,int query_key)
{
	tree_node_t *tmp;
	if(tree->left==NULL)
		return(NULL);
	else
	{
		tmp=tree;
		while(tmp->right!=NULL)
		{
			if(query_key<tmp->key)
				tmp=tmp->left;
			else
				tmp=tmp->right;
		}
		if(tmp->key==query_key)
			return((obj_node_t*)tmp->left);
		else
			return(NULL);
	}
}
//創建插入函數
int insert(tree_node_t *tree,obj_node_t *new_obj)
{
	tree_node_t *tmp;
	int query_key,new_key;
	query_key=new_key=new_obj->obj_key;
	if(tree->left==NULL)
	{
		tree->left=(tree_node_t *)new_obj;
		tree->key=new_key;
		tree->height=0;
		tree->right=NULL;
	}
	else
	{
		stack_clear();
		tmp=tree;
		while(tmp->right!=NULL)
		{
		//use stack to remember the path from root to the position at which the new object should be inserted.
		//then after inserting,we can rebalance from the parrent node of the leaf which pointing to new object to the root node.
			push(tmp);
			if(query_key<tmp->key)
				tmp=tmp->left;
			else
				tmp=tmp->right;
		}
		if(tmp->key==query_key)
			return(-1);
		else
		{
			tree_node_t *old_leaf,*new_leaf;
			//It must allocate 2 node space in memory.
			//One for the new one,another for the old one.
			//the previous node becomes the parrent of the new node.
			//when we delete a leaf,it will free two node memory spaces as well.
			old_leaf=get_node();
			old_leaf->left=tmp->left;
			old_leaf->key=tmp->key;
			old_leaf->right=NULL;
			old_leaf->height=0;
			new_leaf=get_node();
			new_leaf->left=(tree_node_t *)new_obj;
			new_leaf->key=new_key;
			new_leaf->right=NULL;
			new_leaf->height=0;
			if(tmp->key<new_key)
			{
				tmp->left=old_leaf;
				tmp->right=new_leaf;
				tmp->key=new_key;
			}
			else
			{
				tmp->left=new_leaf;
				tmp->right=old_leaf;
			}
			tmp->height=1;
		}
	}
	rebalance(tmp);
	return(0);
}
//創建刪除函數
int del(tree_node_t *tree,int key)
{
	tree_node_t *tmp,*upper,*other;
	if(tree->left==NULL)
		return(-1);
	else if(tree->right==NULL)
	{
		if(tree->key==key)
		{
			tree->left=NULL;
			return(0);
		}
		else
			return(-1);
	}
	else
	{
		tmp=tree;
		stack_clear();
		while(tmp->right!=NULL)
		{
			upper=tmp;
			push(upper);
			if(key<tmp->key)
			{
				tmp=upper->left;
				other=upper->right;
			}
			else
			{
				tmp=upper->right;
				other=upper->left;
			}
		}
		if(tmp->key!=key)
			return(-1);
		else
		{
			upper->key=other->key;
			upper->left=other->left;
			upper->right=other->right;
			upper->height=upper->height-1;
			return_node(tmp);
			return_node(other);
			rebalance(pop());
			//here must pop,then rebalance can run from the parrent of upper,because upper has become a leaf.
			return(0);
		}
	}
}
//創建測試遍歷函數
int travel(tree_node_t *tree)
{
	stack_clear();
	if(tree->left==NULL)
		push(tree);
	else if(tree->left!=NULL)
	{
		int m=0;
		push(tree);
		while(i!=m)
		{
			if(stack[m]->left!=NULL && stack[m]->right!=NULL)
			{
				push(stack[m]->left);
				push(stack[m]->right);
			}
			m++;
		}
	}
	return(0);
}
//創建測試函數
int test_structure(tree_node_t *tree)
{
	travel(tree);
	int state=-1;
	while(!stack_empty())
	{
		--i;
		if(stack->right==NULL && stack->height==0) //this statement is leaf,but also contains an empty tree
			state=0;
		else if(stack->left!=NULL && stack->right!=NULL)
		{
			if(abs(stack->height-stack->height)<=1)
				state=0;
			else
			{
				state=-1;
				stack_clear();
			}
		}
	}
	stack_clear();
	return(state);
}
//創建remove_tree函數
int remove_tree(tree_node_t *tree)
{
	travel(tree);
	if(stack_empty())
		return(-1);
	else
	{
		while(!stack_empty())
		{
			return_node(pop());
		}
		return(0);
	}
}
void main()
{
	tree_node_t *atree=NULL;
	obj_node_t obj[256],*f; //MAXSIZE=n(number of leaf)+(n-1) number of node
	int n,j=0;
	cout<<"Now Let's start this program! There is no tree in memory.\n";
	int item;
	while(item!=0)
	{
		cout<<"\nRoot address = "<<atree<<"\n";
		cout<<"\n1.Create a tree\n";
		cout<<"\n2.Insert a int type object\n";
		cout<<"\n3.Test the structure of the tree\n";
		cout<<"\n4.Find a object\n";
		cout<<"\n6.Delete a object\n";
		cout<<"\n7.Remove the Tree\n";
		cout<<"\n0.Exit\n";
		cout<<"\nPlease select:";
		cin>>item;
		cout<<"\n\n\n";
		switch(item)
		{
		case 1:
		{
			atree=creat_tree();
			cout<<"\nA new empty tree has been built up!\n";
			break;
		}
		case 2:
		{
			if(atree!=NULL)
			{
				while(n!=3458)
				{
					cout<<"Please insert a new object.\nOnly one object every time(3458 is an end code) : ";
					cin>>n;
					if(n!=3458)
					{
						obj[j].obj_key=n;
						if(insert(atree,&obj[j])==0)
						{
							j++;
							cout<<"Integer "<<n<<" has been input!\n\n";
						}
						else
							cout<<"\n\nInsert failed!\n\n";
					}
				}
			}
			else
				cout<<"\n\nNo tree in memory,insert Fail!\n\n";
			break;
		}
		case 3:
		{
			if(atree!=NULL)
			{
				n=test_structure(atree);
				if(n==-1)
					cout<<"\n\nIt's not a correct AVL tree.\n\n";
				if(n==0)
					cout<<"\n\nIt's a AVL tree\n\n";
			}
			else
				cout<<"\n\nNo tree in memory,Test Fail!\n\n";
			break;
		}
		case 4:
		{
			if(atree!=NULL)
			{
				cout<<"\n\nWhat do you want to find? : ";
				cin>>n;
				f=find(atree,n);
				if(f==NULL)
				{
					cout<<"\n\nSorry,"<<n<<" can't be found!\n\n";
				}
				else
				{
					cout<<"\n\nObject "<<f->obj_key<<" has been found!\n\n";
				}
			}
			else
				cout<<"\n\nNo tree in memory,Find Fail!\n\n";
			break;
		}
		case 5:
		{
			if(atree!=NULL)
			{
				travel(atree);
				for(int count=0;count<i;count++)
				{
					cout<<" "<<stack[count]->key<<",";
				}
			}
			else
				cout<<"\n\nNo tree in memory,Travel Fail!\n\n";
			break;
		}
		case 6:
		{
			if(atree!=NULL)
			{
				cout<<"\n\nWhich object do you want to delete?\n\n";
				cin>>n;
				if(del(atree,n)==0)
				{
					cout<<"\n\n"<<n<<" has been deleted!\n\n";
				}
				else
					cout<<"\n\nNo this object\n\n";
			}
			else
				cout<<"\n\nNo tree in memory,Delete Fail!\n\n";
			break;
		}
		case 7:
		{
			if(atree!=NULL)
			{
				remove_tree(atree);
				cout<<"\n\nThe Tree has been removed!\n\n";
				atree=NULL;
			}
			else
				cout<<"\n\nNo tree in memory,Removing Fail!\n\n";
			break;
		}
		default:
			cout<<"\n\nNo this operation!\n\n";
		}
		n=0;
	}
}
相關文章
相關標籤/搜索