#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; }