数据结构-树

1、树的定义:树是算法中常用的数据结构。以下给出针对于二叉树、以及二叉搜索树的代码实现。

2、代码实现

(1)二叉树

<span style="font-size:18px;"><span style="font-size:14px;">/*bitree.h*/
#ifndef BITREE_H
#define BITREE_H
#include<stdlib.h>

/*define a structure for binary tree nodes*/
typedef struct BiTreeNode_
{
	void	*data;
	struct BiTreeNode_ *left;
	struct BiTreeNode_ *right;
}BiTreeNode;

/*define a stucture for binary tree*/
typedef struct BiTree_
{
	int	size;
	int (*compare)(const void *key1,const void *key2);
	void (*destroy)(void *data);
	BiTreeNode *root;
}BiTree;

/*public interface*/
void bitree_init(BiTree *tree,void (*destroy)(void *data));
void bitree_destroy(BiTree *tree);
int bitree_ins_left(BiTree *tree,BiTreeNode *node,const void *data);
int bitree_ins_right(BiTree *tree,BiTreeNode *node,const void *data); 
void bitree_rem_left(BiTree *tree,BiTreeNode *node);
void bitree_rem_right(BiTree *tree,BiTreeNode *node);
int bitree_merge(BiTree *merge,BiTree *left,BiTree *right,const void *data);
#define bitree_size(tree)	((tree)->size)
#define bitree_root(tree)	((tree)->root)
#define bitree_is_eob(tree)	((node)==NULL)
#define bitree_is_leaf(tree)	((node)->left==NULL && (node)->right==NULL)
#define bitree_data(node)	((node)->data)
#define bitree_left(node)	((node)->left)
#define bitree_right(node)	((node)->right)

#endif
</span></span>

<span style="font-size:18px;"><span style="font-size:14px;">/*bitree.c*/
#include<stdlib.h>
#include<string.h>
#include"bitree.h"

void bitree_init(BiTree *tree,void (*destroy)(void *data))
{
	/*initialize the binary tree*/
	tree->size=0;
	tree->destroy=destroy;
	tree->root=NULL;
	return ;
}


void bitree_destroy(BiTree *tree)
{
	/*remove all the nodes from the tree*/
	bitree_rem_left(tree,NULL);

	/*clear the structure*/
	memset(tree,0,sizeof(BiTree));
	return;
}


int bitree_ins_left(BiTree *tree,BiTreeNode *node,const void *data)
{
	BiTreeNode *new_node,**position;

	/*determine where to insert the node*/
	if(node==NULL)
	{
		/*allow insertion at the root only in an empty tree*/
		if(bitree_size(tree)>0)
			return -1;
		position=&tree->root;
	}
	else
	{
		/*normally allow insertion only at the end of a branch*/
		if(bitree_left(node)!=NULL)
			return -1;
		position=&node->left;
	}

	/*allocate storage for the node*/
	if((new_node=(BiTreeNode *)malloc(sizeof(BiTreeNode)))==NULL)
		return -1;

	/*insert the node into the tree*/
	new_node->data=(void *)data;
	new_node->left=NULL;
	new_node->right=NULL;
	*position=new_node;

	/*adjust the size of the tree to account for the inserted node*/
	tree->size++;
	return 0;
}


int bitree_ins_right(BiTree *tree,BiTreeNode *node,const void *data)
{
		BiTreeNode *new_node,**position;

	/*determine where to insert the node*/
	if(node==NULL)
	{
		/*allow insertion at the root only in an empty tree*/
		if(bitree_size(tree)>0)
			return -1;
		position=&tree->root;
	}
	else
	{
		/*normally allow insertion only at the end of a branch*/
		if(bitree_left(node)!=NULL)
			return -1;
		position=&node->right;
	}

	/*allocate storage for the node*/
	if((new_node=(BiTreeNode *)malloc(sizeof(BiTreeNode)))==NULL)
		return -1;

	/*insert the node into the tree*/
	new_node->data=(void *)data;
	new_node->left=NULL;
	new_node->right=NULL;
	*position=new_node;

	/*adjust the size of the tree to account for the inserted node*/
	tree->size++;
	return 0;
}


void bitree_rem_left(BiTree *tree,BiTreeNode *node)
{
	BiTreeNode **position;

	/*do not allow removal from an empty tree*/
	if(bitree_size(tree)==0)
		return;
	/*determine where to remove node*/
	if(node==NULL)
		position=&tree->root;
	else
		position=&node->left;

	/*remove the nodes*/
	if(*position!=NULL)
	{
		bitree_rem_left(tree,*position);
		bitree_rem_right(tree,*position);
		if(tree->destroy!=NULL)
		{
			/*call a user-defined function to free dynamically allocated data*/
			tree->destroy((*position)->data);
		}
		free(*position);
		*position=NULL;

		/*adjust the size of the tree to account for the removed node*/
		tree->size--;
	}
	return ;
}


void bitree_rem_right(BiTree *tree,BiTreeNode *node)
{
	BiTreeNode **position;

	/*do not allow removal from an empty tree*/
	if(bitree_size(tree)==0)
		return;
	/*determine where to remove node*/
	if(node==NULL)
		position=&tree->root;
	else
		position=&node->right;

	/*remove the nodes*/
	if(*position!=NULL)
	{
		bitree_rem_left(tree,*position);
		bitree_rem_right(tree,*position);
		if(tree->destroy!=NULL)
		{
			/*call a user-defined function to free dynamically allocated data*/
			tree->destroy((*position)->data);
		}
		free(*position);
		*position=NULL;

		/*adjust the size of the tree to account for the removed node*/
		tree->size--;
	}
	return ;
}


int bitree_merge(BiTree *merge,BiTree *left,BiTree *right,const void *data)
{
	/*initialize the merged tree*/
	bitree_init(merge,left->destroy);

	/*insert the data for the root node of the merged tree*/
	if(bitree_ins_left(merge,NULL,data)!=0)
	{
		bitree_destroy(merge);
		return -1;
	}

	/*merge the two binary trees into a single binary tree*/
	bitree_root(merge)->left=bitree_root(left);
	bitree_root(merge)->right=bitree_root(right);

	/*adjust the size of the new binary tree*/
	merge->size=merge->size+bitree_size(left)+bitree_size(right);

	/*do not let original trees access the merged nodes*/
	left->root=NULL;
	left->size=0;
	right->root=NULL;
	right->size=0;

	return 0;
}
</span></span>


应用实例:

后续补上

(2)二叉搜索树

<span style="font-size:18px;"><span style="font-size:14px;">/*bistree.h 二叉搜索树*/
#ifndef BISTREE_H
#define BISTREE_H
#include "bitree.h"

/*define balance factors for AVL trees*/
#define		AVL_LFT_HEAVY		1
#define		AVL_BALANCED		0
#define		AVL_RGT_HEAVY		-1

/*define a structure for node in AVL trees*/
typedef struct AvlNode_
{
	void *data;
	int hidden;
	int factor;
}AvlNode;

/*implement binary search trees as binary trees*/
typedef BiTree BisTree;

/*public interface*/
void bistree_init(BisTree *tree,int (*compare)(const void *key1,const void *key2),void (*destroy)(void *data));
void bistree_destroy(BisTree *tree);
int bistree_insert(BisTree *tree,const void *data);
int bistree_remove(BisTree *tree,const void *data);
int bistree_lookup(BisTree *tree,void **data);
#define bistree_size(tree) ((tree)->size)

#endif</span></span>

<span style="font-size:18px;"><span style="font-size:14px;">/*bistree.c二叉搜索树*/
#include<stdlib.h>
#include<string.h>
#include"bistree.h"

static void destroy_right(BisTree *tree,BiTreeNode *node);

static void rotate_left(BiTreeNode **node)
{
	BiTreeNode *left,*grandchild;
	left=bitree_left(*node);
	if(((AvlNode *)bitree_data(left))->factor==AVL_LFT_HEAVY)
	{
		/*Perform an LL rotation*/
		bitree_left(*node)=bitree_right(left);
		bitree_right(left)=*node;
		((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
		((AvlNode *)bitree_data(left))->factor=AVL_BALANCED;
		*node=left;
	}
	else
	{
		/*perform an LR rotation*/
		grandchild=bitree_right(left);
		bitree_right(left)=bitree_left(grandchild);
		bitree_left(grandchild)=left;
	    bitree_left(*node)=bitree_left(grandchild);
		bitree_right(grandchild)=*node;

		switch(((AvlNode *)bitree_data(grandchild))->factor)
		{
		case AVL_LFT_HEAVY:
			((AvlNode *)bitree_data(*node))->factor=AVL_RGT_HEAVY;
			((AvlNode *)bitree_data(left))->factor=AVL_BALANCED;
			break;
		case AVL_BALANCED:
			((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
			((AvlNode *)bitree_data(left))->factor=AVL_BALANCED;
			break;
		case AVL_RGT_HEAVY:
			((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
			((AvlNode *)bitree_data(left))->factor=AVL_LFT_HEAVY;
			break;
		}
		((AvlNode *)bitree_data(grandchild))->factor=AVL_BALANCED;
		*node=grandchild;
	}
	return;
}


static void rotate_right(BiTreeNode **node)
{
	BiTreeNode *right,*grandchild;
	right=bitree_right(*node);
	if(((AvlNode *)bitree_data(right))->factor==AVL_RGT_HEAVY)
	{
		/*Perform an RR rotation*/
		bitree_right(*node)=bitree_left(right);
		bitree_right(right)=*node;
		((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
		((AvlNode *)bitree_data(right))->factor=AVL_BALANCED;
		*node=right;
	}
	else
	{
		/*perform an RL rotation*/
		grandchild=bitree_left(right);
		bitree_left(right)=bitree_right(grandchild);
		bitree_right(grandchild)=right;
	    bitree_right(*node)=bitree_left(grandchild);
		bitree_left(grandchild)=*node;

		switch(((AvlNode *)bitree_data(grandchild))->factor)
		{
		case AVL_LFT_HEAVY:
			((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
			((AvlNode *)bitree_data(right))->factor=AVL_RGT_HEAVY;
			break;
		case AVL_BALANCED:
			((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
			((AvlNode *)bitree_data(right))->factor=AVL_BALANCED;
			break;
		case AVL_RGT_HEAVY:
			((AvlNode *)bitree_data(*node))->factor=AVL_LFT_HEAVY;
			((AvlNode *)bitree_data(right))->factor=AVL_BALANCED;
			break;
		}
		((AvlNode *)bitree_data(grandchild))->factor=AVL_BALANCED;
		*node=grandchild;
	}
	return;
	 
}


static void destroy_left(BisTree *tree,BiTreeNode *node)
{
	BiTreeNode **position;

	/*do not allow destruction of an empty tree*/
	if(bitree_size(tree)==0)
		return;

	/*determine where to destroy nodes*/
	if(node==NULL)
		position=&tree->root;
	else 
		position=&node->left;

	/*destroy the nodes*/
	if(*position !=NULL)
	{
		destroy_left(tree,*position);
		destroy_right(tree,*position);
		if(tree->destroy!=NULL)
		{
			/*call a user-define function to free dynamically allocated data*/
			tree->destroy(((AvlNode *)(*position)->data)->data);
		}

		/*Free the AVL data in the node,then free the node itself*/
		free((*position)->data);
		free(*position);
		*position=NULL;

		/*Ajust the size*/
		tree->size--;
	}
	return ;
	
}


static void destroy_right(BisTree *tree,BiTreeNode *node)
{
	BiTreeNode **position;

	/*do not allow destruction of an empty tree*/
	if(bitree_size(tree)==0)
		return;

	/*determine where to destroy nodes*/
	if(node==NULL)
		position=&tree->root;
	else 
		position=&node->right;

	/*destroy the nodes*/
	if(*position !=NULL)
	{
		destroy_left(tree,*position);
		destroy_right(tree,*position);
		if(tree->destroy!=NULL)
		{
			/*call a user-define function to free dynamically allocated data*/
			tree->destroy(((AvlNode *)(*position)->data)->data);
		}

		/*Free the AVL data in the node,then free the node itself*/
		free((*position)->data);
		free(*position);
		*position=NULL;

		/*Ajust the size*/
		tree->size--;
	}
	return ;
	
}


static int insert(BisTree *tree,BiTreeNode **node,const void *data,int *balanced)
{
	AvlNode *avl_data;
	int cmpval,retval;

	/*insert the data into the tree*/
	if(bitree_is_eob(*node))
	{
		/*handle insertion into an empty tree*/
		if((avl_data=(AvlNode *)malloc(sizeof(AvlNode)))==NULL)
			return -1;
		avl_data->factor=AVL_BALANCED;
		avl_data->hidden=0;
		avl_data->data=(void *)data;
		return bitree_ins_left(tree, *node,avl_data);
	}
	else
	{
		/*handle insertion into a tree that is not empty*/
		cmpval=tree->compare(data,((AvlNode *)bitree_data(*node))->data);
		if(cmpval<0)
		{
			/*move to  the left*/
			if(bitree_is_eob(bitree_left(*node)))
			{
				if((avl_data=(AvlNode *)malloc(sizeof(AvlNode *)))==NULL)
					return -1;
				avl_data->factor=AVL_BALANCED;
				avl_data->hidden=0;
				avl_data->data=(void *)data;
				if(bitree_ins_left(tree,*node,avl_data)!=0)
					return -1;
				*balanced=0;
			}
			else
			{
				if((retval=insert(tree,&bitree_left(*node),data,balanced))!=0)
				{	
					return retval;
				}
			}

			/*ensure that the tree remains balanced*/
			if(!(*balanced))
			{
				switch(((AvlNode *)bitree_data(*node))->factor)
				{
				case AVL_LFT_HEAVY:
					rotate_left(node);
					*balanced=1;
					break;
				case AVL_BALANCED:
					((AvlNode *)bitree_data(*node))->factor=AVL_LFT_HEAVY;
					break;
				case AVL_RGT_HEAVY:
					((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
					*balanced=1;
					break;
				}
			}
		}
		
		else if(cmpval>0)
		{
			/*move to  the right*/
			if(bitree_is_eob(bitree_right(*node)))
			{
				if((avl_data=(AvlNode *)malloc(sizeof(AvlNode *)))==NULL)
					return -1;
				avl_data->factor=AVL_BALANCED;
				avl_data->hidden=0;
				avl_data->data=(void *)data;
				if(bitree_ins_right(tree,*node,avl_data)!=0)
					return -1;
				*balanced=0;
			}
			else
			{
				if((retval=insert(tree,&bitree_right(*node),data,balanced))!=0)
				{	
					return retval;
				}
			}

			/*ensure that the tree remains balanced*/
			if(!(*balanced))
			{
				switch(((AvlNode *)bitree_data(*node))->factor)
				{
				case AVL_LFT_HEAVY:
					((AvlNode *)bitree_data(*node))->factor=AVL_BALANCED;
					*balanced=1;
					break;
				case AVL_BALANCED:
					((AvlNode *)bitree_data(*node))->factor=AVL_RGT_HEAVY;
					break;
				case AVL_RGT_HEAVY:
					rotate_right(node);
					*balanced=1;
					break;
				}
			}
		}

		else
		{
			/*handle finding a copy for the data*/
			if(!((AvlNode *)bitree_data(*node))->hidden)
			{
				/*do nothing since the data is in the tree and not hidden*/
				return 1;
			}
			else
			{
				/*insert the new data and mask it as no hidden*/
				if(tree->destroy!=NULL)
				{
					/*destroy the hidden data since it is being replaced*/
					tree->destroy(((AvlNode *)bitree_data(*node))->data);
				}
				((AvlNode *)bitree_data(*node))->data=(void *)data;
				((AvlNode *)bitree_data(*node))->hidden=0;

				/*do not rebalance because the tree structure is unchanged*/
				*balanced=1;
			}
		}

	}
	return 0;

}


static int hide(BisTree *tree,BiTreeNode *node,const void *data)
{
	int cmpval,retval;
	if(bitree_is_eob(node))
	{
		/*return that the data was not found*/
		return -1;
	}
	cmpval=tree->compare(data,((AvlNode *)bitree_data(node))->data);
	if(cmpval<0)
	{
		/*move to the left*/
		retval=hide(tree,bitree_left(node),data);
	}
	else if(cmpval>0)
	{
		/*move to the right*/
		retval=hide(tree,bitree_right(node),data);
	}
	else
	{
		/*mark the node as hidden*/
		((AvlNode *)bitree_data(node))->hidden=1;
		retval=0;
	}
	return retval;

}


static int lookup(BisTree *tree,BiTreeNode *node,void **data)
{
	int cmpval,retval;
	if(bitree_is_eob(node))
	{
		/*return that the data was not found*/
		return -1;
	}
	cmpval=tree->compare(*data,((AvlNode *)bitree_data(node))->data);
	if(cmpval<0)
	{
		/*move to the left*/
		retval=lookup(tree,bitree_left(node),data);
	}
	else if(cmpval>0)
	{
		/*move to the riht*/
		retval=lookup(tree,bitree_right(node),data);
	}
	else
	{
		if(!((AvlNode *)bitree_data(node))->hidden)
		{
			/*pass back the data from the tree*/
			*data=((AvlNode *)bitree_data(node))->data;
			retval=0;
		}
		else
		{
			/*return that the data was no found*/
			return -1;
		}
	}

	return retval;
}


void bistree_init(BisTree *tree,int (*compare)(const void *key1,const void *key2),void (*destroy)(void *data))
{
	/*initialize the tree*/
	bitree_init(tree,destroy);
	tree->compare=compare;
	return;
}


void bistree_destroy(BisTree *tree)
{
	/*destroy all node in the tree*/
	destroy_left(tree,NULL);
	memset(tree,0,sizeof(BisTree));
	return;
}


int bistree_insert(BisTree *tree,const void *data)
{
	int balanced=0;
	return insert(tree,&bitree_root(tree),data,&balanced);
}


int bistree_remove(BisTree *tree,const void *data)
{
	return hide(tree,bitree_root(tree),data);
}


int bistree_lookup(BisTree *tree,void **data)
{
	return lookup(tree,bitree_root(tree),data);
}</span></span>


应用实例:

后续补上

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值