乾貨7:樹

#ifndef __TREE_H__
#define __TREE_H__

struct _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 代表要插入結點父親結點的位置
// 約定:
// 1 新插入的結點插入在當前父親結點所有孩子的右邊
// 2 根節點的位置是 0
int Insert_Tree(Tree *tree, TreeData data, int pos);

void Display(Tree *tree, TreePrint pFunc);

int Delete(Tree *tree, int pos, TreeData *x);

int Tree_Get(Tree* tree, int pos, TreeData *x);

// 清空樹中所有的節點
int Tree_Clear(Tree* tree);

// 樹的銷燬 
void Tree_Destroy(Tree* tree);

TreeNode* Tree_Root(Tree* tree);

int Tree_Count(Tree* tree);

int Tree_Height(Tree* tree);

int Tree_Degree(Tree* tree);


#endif  // __TREE_H__



#include "tree.h"
#include <stdlib.h>

Tree *Create_Tree()
{
	// 創建樹節點
	Tree* tree = (Tree*)malloc(sizeof(Tree)/sizeof(char));
	if (tree == NULL)
	{
		errno = MALLOC_ERROR;
		return NULL;
	}
	
	// 給樹結點鏈表創建頭節點
	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->childList = NULL;
	tree->head->next      = NULL;   // 代表樹中沒有結點
	
	// 空樹結點爲0
	tree->len = 0;
	
	return tree;
}

/*
TreeData data;
struct _treeNode *parent;      // 指向父節點的指針          
struct _treeNode *next;        // 指向鏈表的下一個結點
struct _childNode *childList;  // 孩子鏈表的頭節點
int degree;                    // 結點的度

typedef struct _childNode
{
	struct _treeNode * childNode;
	struct _childNode *next;  // 指向孩子結點鏈表下一個元素
}ChildNode;
*/

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->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* 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", '-');
	}
	
	// 打印結點自己
	// printf ("%c\n", node->data);
	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);
}

void r_delete(Tree *tree, TreeNode *node)
{
	if (tree == NULL || node == NULL)
		return;
	
	// 從樹鏈表中移除這個結點,找node的前一個結點
	TreeNode* tmp = tree->head; // 鏈表的頭節點
	while (tmp->next)
	{
		if (tmp->next == node)
		{
			tmp->next = node->next;
			tree->len --;
			break;
		}
		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;
		}
	}
	
	// 將該結點的孩子結點刪掉
	ChildNode* child = node->childList->next;   // 子結點鏈表中的第一個結點
	while (child)
	{
		ChildNode* pchild = child->next;
		r_delete(tree, child->childNode);
		child  = pchild;
	}

	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 Tree_Get(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;
	return Delete (tree, 0, &x);
}

void Tree_Destroy(Tree* tree)
{
	if (tree == NULL)
	{
		errno = ERROR;
		return;
	}
	
	Tree_Clear(tree);
	
	free (tree->head);
	free (tree);
}

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_height(TreeNode* node)
{
	if (node == NULL)
		return 0;
	
	int subHeight = 0;
	int max = 0;
	ChildNode* child = node->childList->next;
	while (child)
	{
		subHeight = r_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_height(tree->head->next);
	
	return height;
}

int r_degree(TreeNode* node)
{
	if (node == NULL)
		return 0;
	
	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 Tree_Degree(Tree* tree)
{
	if (tree == NULL)
	{
		errno = ERROR;
		return FALSE;
	}
	
	int degree = r_degree(tree->head->next);
	
	return degree;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章