树是由根结点和若干颗子树构成的。树是由一个集合以及在该集合上定义的一种关系构成的。集合中的元素称为树的结点,所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构。在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点,或称为树根。
头文件 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是我自己写的一个包含常见错误的头文件,这里我就不发了。