樹是由根結點和若干顆子樹構成的。樹是由一個集合以及在該集合上定義的一種關系構成的。集合中的元素稱為樹的結點,所定義的關系稱為父子關系。父子關系在樹的結點之間建立了一個層次結構。在這種層次結構中有一個結點具有特殊的地位,這個結點稱為該樹的根結點,或稱為樹根。
頭文件 tree.h
#ifndef __TREE_H__
#define __TREE_H__#include "error.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);// 打印
void printA (TreeNode* node);#endif // __TREE_H__
源文件 tree.c
#include "tree.h"
#include <stdlib.h>Tree *Create_Tree()
{// 創建樹節點Tree* tree = (Tree*) malloc(sizeof(Tree)/sizeof(char));if (NULL == tree){errno = MALLOC_ERROR;return NULL;}// 給樹結點鏈表創建頭節點tree->head = (TreeNode*) malloc(sizeof(TreeNode)/sizeof(char));if (NULL == tree->head){errno = MALLOC_ERROR;free (tree);return NULL;}tree->head->parent = NULL;tree->head->childList = NULL;tree->head->next = NULL; // 代表樹中沒有結點// 空樹結點為0tree->len = 0;return tree;
}int Insert_Tree (Tree* tree, TreeData data, int pos)
{if (NULL == tree || 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 (NULL == node){ errno = MALLOC_ERROR;return FALSE;}node->data = data;node->next = NULL;// 創建該新節點的孩子結點鏈表的頭節點node->childList = (ChildNode*) malloc(sizeof(ChildNode)/sizeof(char));if (NULL == node->childList){ 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 (NULL == childnode){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 (NULL == node){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 (NULL == tree){return;}r_display (tree->head->next, 0, pFunc);
}void r_delete (Tree *tree, TreeNode *node)
{if (NULL == tree || NULL == node)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 (NULL != parent){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 (NULL == tree || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (0 != pos && 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 (NULL == tree || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (0 != pos && 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 (NULL == tree){errno = ERROR;return FALSE;}TreeData x;return Delete (tree, 0, &x);
}void Tree_Destroy (Tree* tree)
{if (NULL == tree){errno = ERROR;return;}Tree_Clear (tree);free (tree->head);free (tree);
}TreeNode* Tree_Root (Tree* tree)
{if (NULL == tree){errno = ERROR;return NULL;}return tree->head->next;
}int Tree_Count (Tree* tree)
{if (NULL == tree){errno = ERROR;return FALSE;}return tree->len;
}// 遞歸求高度
int r_height (TreeNode* node)
{if (NULL == node){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 (NULL == tree){errno = ERROR;return FALSE;}int height = r_height (tree->head->next);return height;
}// 遞歸求度
int r_degree (TreeNode* node)
{if (NULL == node){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 (NULL == tree){errno = ERROR;return FALSE;}int degree = r_degree (tree->head->next);return degree;
}void printA (TreeNode* node)
{printf ("%c\n", node->data);
}
主函數 main.c
#include <stdio.h>
#include "tree.h"int main()
{Tree* tree = Create_Tree();if (NULL == tree){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);Insert_Tree (tree, 'J', 3);Insert_Tree (tree, 'X', 3);Insert_Tree (tree, 'Z', 8);Display (tree, printA);//printf ("刪除B :\n");TreeData x;//Delete(tree, 1, &x);//Display(tree, printA);printf ("height = %d\n", Tree_Height(tree));printf ("degree = %d\n", Tree_Degree(tree));return 0;
}
error.h是我自己寫的一個包含常見錯誤的頭文件,這里我就不發了。