數據結構之樹的實現

#ifndef _TREE_H_
#define _TREE_H_

#include "error.h"

#define false 0
#define true 1
typedef _TreeNode;

typedef struct _ChildNode  //孩子結點型鏈表
{
	struct _TreeNode *childNode; //孩子結點指向父結點的指針
	struct _ChildNode *next;  //指向孩子結點鏈表下一個元素

}ChildNode;

typedef char TreeData;  //樹結點類型
typedef struct _TreeNode
{
	TreeData data;
	struct _TreeNode *parent; //指向父結點的指針
	struct _TreeNode *next;  //指向鏈表的下一個元素
	struct _ChildNode *childlist;  //父結點指向孩子鏈表的頭結點
	int degree;//結點的度(後繼的數量)
}TreeNode;

typedef struct _Tree
{
	struct _TreeNode *head;   //樹鏈表的頭結點
	int len;   //樹結點的個數(長度)
}Tree;
//定義一個函數指針類型
typedef void (*TreePrint)(TreeNode *node);

Tree *Create_Tree();
//pos 要插入父結點
int Insert_Tree(Tree *tree,TreeData data,int pos);

//顯示樹
void Display (Tree *tree,TreePrint pFunc);

//移除結點
//int R_Delete (Tree *tree,TreeNode *node);

//刪除指定位置結點
int Delete(Tree *tree,int pos,TreeData *x);

//獲取樹的結點
int Get_Tree(Tree *tree,int pos,TreeData *x);

//清楚所有結點
int Tree_Clear(Tree *tree);

//銷燬樹
void Destroy(Tree *tree);

//獲取根節點
TreeNode *Tree_root(Tree *tree);

//樹鏈表的長度
int Tree_Count(Tree *tree);

//結點的高度
//int R_Tree_Height(TreeNode *node); 

//樹的高度
int Tree_Height(Tree *tree);

//結點的度(後繼數量)
//int R_Degree(TreeNode *tree); 

//樹的度
int Degree(Tree *tree);



#endif   //_TREE_H_


//tree.c函數源代碼
#include "tree.h"

#include <stdlib.h>


Tree *Create_Tree()
{	
    //創建樹結點
	Tree *tree = (Tree *)malloc(sizeof(Tree) / sizeof(char));
	if(tree == NULL)
	{
		errno = MALLOC_ERROR;
		return false;
	}
	
	//創建樹結點鏈表的頭結點
	tree->head = (TreeNode *)malloc(sizeof(TreeNode) / sizeof(char));
	if(tree->head == NULL)
	{
		errno = MALLOC_ERROR;
		free(tree);
		return NULL;
	}
	//給元素賦值 
	tree->head->parent    = NULL;
	tree->head->next      = NULL;
	tree->head->childlist = NULL;//置空,樹中沒有結點
	
	tree->len = 0;
	
	return tree;
}


// pos 代表要插入結點父親結點的位置
int Insert_Tree(Tree *tree,TreeData data,int pos)
{
	if(tree == NULL || pos < 0 || pos > tree->len)
	{
		errno = ERROR;
		return false;
	}
	
	if(pos != 0 && tree->len == pos)
	{
		errno = ERROR;
		return false;
	}
	
	//新建結點
	TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode) / sizeof(char));
	if(node == NULL)
	{
		errno = MALLOC_ERROR;
		return false;
	}
	
	node->data = data;
	node->next = NULL;
	
	//創建node結點的孩子結點鏈表的頭結點
	node->childlist = (ChildNode *)malloc(sizeof(ChildNode) / sizeof(char));
	if(node->childlist == NULL)
	{
		errno = MALLOC_ERROR;
		free(node);
		return false;
	}
	
	node->childlist->next      = NULL;
	node->childlist->childNode = NULL;
	node->degree = 0;
	
	//找父結點
	int i;
	TreeNode *parent = tree->head->next;  //樹結點的第一個結點,根節點
	for(i = 0;i < pos;i++)
	{
		parent = parent->next;
	}
		node->parent = parent;
	
	if(parent != NULL)
	{    //在孩子鏈表中創建一個結點
		ChildNode *childnode = (ChildNode *)malloc(sizeof(ChildNode) / sizeof(char));
		if(childnode == NULL)
		{
			errno = MALLOC_ERROR;
			free(node->childlist);
			free(node);
			return false;
		}
		childnode->childNode = node;
		childnode->next = NULL;
		
		//把childnode加入到父結點node的孩子鏈表中
		ChildNode *tmp = parent->childlist;//孩子鏈表的頭結點
		while(tmp->next)
			tmp = tmp->next;
		
		tmp->next = childnode;
		parent->degree += 1;//後繼(度)加一
		
	}
	
	TreeNode *tmp = tree->head;//樹結點鏈表的頭結點
		while(tmp->next)
			tmp = tmp->next;
		
		tmp->next = node;
		tree->len += 1;
		
		return true;
	
}


void R_Display(TreeNode *node,int gap,TreePrint pFunc)  //遞歸打印結點
{
	if(node == NULL)
		return;
	
	//打印距離前一個結點的距離
	int i;
	for(i = 0;i < gap;i++)
	{
		printf("%c",'-');
	}
	//打印結點自己
	pFunc(node);
	
	ChildNode *child = node->childlist->next;//該節點的第一個孩子結點
	//用遞歸打印結點孩子
		while(child)
		{
			R_Display (child->childNode,gap+4,pFunc);
			child = child->next;
		}
}

void Display(Tree *tree,TreePrint pFunc)//打印樹
{
	if(tree == NULL)

		return;
		
	R_Display(tree->head->next,0,pFunc);//先打印根節點
}

int R_Delete (Tree *tree,TreeNode *node)//移除結點
{
	if(tree == NULL || node == NULL)
	{
		return;
	}
	//先從樹鏈表中移除結點,找node的前一個結點
	TreeNode *tmp = tree->head->next;
	while(tmp)
	{
		if(tmp == node)
		{
			tmp = node->next;
			(tree->len)--;
		}
		tmp = tmp->next;
	}
	
	//將父結點中子節點鏈表中的node的結點移除
	TreeNode *parent = node->parent;
	if(parent != NULL)
	{
		ChildNode *tmp = parent->childlist;//子結點鏈表的頭結點
		while(tmp->next)
		{
			if(tmp->next->childNode == node)
			{
				ChildNode *p = tmp->next;
				tmp->next = p->next;
				free(p);
				parent->degree--;
				break;
			}
			tmp = tmp->next;
		}
	}
	//將node結點的孩子結點刪掉
	ChildNode *child = node->childlist->next; //孩子鏈表的第一個結點
	while(child)
	{
		ChildNode *tmp = child->next;
		R_Delete(tree,child->childNode); 
		child = tmp;
	}
	free(node->childlist);
	free(node);
	
}

int Delete(Tree *tree,int pos,TreeData *x)//刪除指定位置結點
{
	if(tree == NULL || pos < 0 || pos > tree->len)
	{
		errno = ERROR;
		return false;
	}
	if(pos != 0 && tree->len == pos)
	{
		errno = ERROR;
		return false;
	}
	
	//找結點
	int i;
	TreeNode *current = tree->head->next;//當前樹鏈表第一個結點
	for(i = 0; i < pos;i++)
	{
		current = current->next;
	}
	
	*x = current->data;
	
	R_Delete(tree,current);
	
	return true;
}

int Get_Tree(Tree *tree,int pos,TreeData *x) //獲取樹的結點
{
	if(tree == NULL || pos < 0 || pos > tree->len)
	{
		errno = ERROR;
		return false;
	}
	if(pos != 0 && tree->len == pos)
	{
		errno = ERROR;
		return false;
	}
	
	int i;
	// 找結點
	TreeNode* current = tree->head->next;  
	for (i = 0; i < pos; i++)
	{
		current = current->next;
	}
	
	*x = current->data;//獲取結點數據
	
	return true;
}

int Tree_Clear(Tree *tree)//清楚所有結點
{
	if(tree = NULL)
	{
		errno = ERROR;
		return false;
	}
	TreeData x;
	
	Delete(tree,0,&x);
	
	return true;
}

void Destroy(Tree *tree)//銷燬樹
{
	
	
	if(tree = NULL)
	{
		errno = ERROR;
		return ;
	}
	
	Tree_Clear(tree);//清除所有結點在釋放掉
	
	free(tree->head);
	free(tree);
	
	return;
}

TreeNode *Tree_root(Tree *tree) //獲取根節點
{
	if(tree == NULL)
	{
		errno = ERROR;
		return NULL;
	}
	return tree->head->next;
}

int Tree_Count(Tree *tree) // 樹鏈表的長度
{
	if(tree = NULL)
	{
		errno = ERROR;
		return false;
	}
	
	return tree->len;
}

int R_Tree_Height(TreeNode *node) //結點的高度
{
	if(node == NULL)
	{
		return false;
	}
	int subheight = 0;
	int max = 0;
	ChildNode *child = node->childlist->next;
	while(child)
	{
		subheight = R_Tree_Height(child->childNode);
		if(subheight > max)
			max = subheight;
		
		child = child->next;
	}
		return max + 1;
}

int Tree_Height(Tree *tree)  //樹的高度
{
	if (tree == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	int height = R_Tree_Height(tree->head->next);
	
	return height;
}

int R_Degree(TreeNode *node) //結點的度(後繼數量)
{
	if(node == NULL)
	{
		return false;
	}
	
	int max = node->degree;
	int subdegree = 0;
	ChildNode *child = node->childlist->next;
	while(child)
	{
		subdegree = R_Degree(child->childNode);
		if(subdegree > max)
		{
			max = subdegree;
		}
		child = child->next;
	}
	return max;                
}

int Degree(Tree *tree) //樹的度
{
	if (tree == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	
	int degree = R_Degree(tree->head->next);
	
	return degree;
}



//main.c
#include <stdio.h>
#include "tree.h"

void printA(TreeNode *node)
{
	printf("%c\n",node->data);
}


int main()
{
	Tree *tree = Create_Tree();
	if(tree == NULL)
	{
		myerror("Create_Tree");
		return -1;
	}
	
	Insert_Tree(tree,'A',0);
	Insert_Tree(tree,'B',0);
	Insert_Tree(tree,'C',0);
	Insert_Tree(tree,'D',0);
	Insert_Tree(tree,'E',1);
	Insert_Tree(tree,'F',1);
	Insert_Tree(tree,'H',3);
	Insert_Tree(tree,'I',3);

	Display(tree,printA);
	
	TreeData x;
	//Delete(tree,i,&x);
	
	printf("height = %d\n",Tree_Height(tree));
	printf("degree = %d\n",Degree(tree));
	
	
	
	return 0;
}



發佈了58 篇原創文章 · 獲贊 12 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章