数据结构:一般树

来源:互联网 发布:莉莉柯林斯长相知乎 编辑:程序博客网 时间:2024/05/17 05:05

这是我学了这么多天感觉最难的,用了两个链表进行嵌套。

思路:先用一个链表保存所有树结点,由于不知道每个树有多少子节点,就再用一个链表保存子节点的位置。

数据结构的课是上完了,但是肯定还是不够的,以后我还会在整理。但是近期就难说,逼近我还有下面的课程。

头文件

#ifndef __TREE_H__#define __TREE_H__ #include"error.h"struct tree_node;//孩子节点链表的类型typedef struct child_node{struct child_node* next;struct tree_node* child;}CHILDNODE;//数节点typedef char TREE_DATA;typedef struct tree_node{TREE_DATA data;             //存的数据struct tree_node* parent;   //父节点struct tree_node* next;     //指向下一个节点int degree;                 //表示度CHILDNODE* child_link;//指向子链表的头结点}TREENODE;typedef struct tree{TREENODE* head;int len;}TREE;//创建一个树TREE* Create_Tree();//插入一个树节点int Insert_Tree(TREE* tree,char data,int pos);//输出数void Display(TREE* tree);//删除pos位节点,以及他的子节点int DelTree(TREE* tree,int pos);//获取第pos位的数据int Get_Tree(TREE* tree,int pos,TREE_DATA *x);//清空树所有节点int Tree_Clear(TREE* tree);//销毁树int Tree_Destroy(TREE** tree);//求树的节点个数int Tree_Count(TREE* tree);//求树的高度int Tree_Height(TREE* tree);//求树的度int Tree_Degree(TREE* tree);#endif


主函数

#include<stdio.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->len = 0 ; 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->child_link = NULL;tree->head->data = 0;tree->head->degree = 0;return tree;}//插入一个树节点int Insert_Tree(TREE* tree,TREE_DATA 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->degree = 0;node->child_link = (CHILDNODE*)malloc(sizeof(CHILDNODE)/sizeof(char));if(node->child_link == NULL){errno = MALLOC_ERROR ;free(node);return FALSE;}node->child_link->next = NULL;node->child_link->child = NULL;//找父节点int i;TREENODE* p = tree->head->next;for(i=0;i<pos;i++){p = p->next;}node->parent = p;if(p != NULL){CHILDNODE* ch = (CHILDNODE*)malloc(sizeof(CHILDNODE)/sizeof(char));if(ch == NULL)    {errno = MALLOC_ERROR;free(node->child_link);free(node);return FALSE;}ch->child = node;ch->next = NULL;CHILDNODE* tmp = p->child_link;while(tmp->next){tmp = tmp->next;}tmp->next = ch;p->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 flag){if (node == NULL)             return ;int i;for(i=0;i<flag;i++)              //先输出空格{printf("-");}printf("%c\n",node->data);       //再输出自己CHILDNODE* tmp = node->child_link->next;while(tmp){r_display(tmp->child,flag+4);  //最后输出自己的儿子 tmp = tmp->next;}}//输出数///输出要用递归实现void Display(TREE* tree){if(tree == NULL){errno == ERROR;return;}r_display(tree->head->next,1);}//递归删除void r_delete(TREE* tree,TREENODE* node){if(tree == NULL  || node == NULL){errno = ERROR;return ;}//找上一个节点,找到后移除TREENODE *tmp = tree->head;   //这里不能加next,不然会少判断第一个 while(tmp->next){if(tmp->next == node){tmp->next = node->next;tree->len--;break;}tmp = tmp->next;}//删除父节点中子链表的位置,并删除if(node->parent != NULL){CHILDNODE* tmp = node->parent->child_link;while(tmp->next){if(tmp->next->child == node){CHILDNODE* pchild = tmp->next;tmp->next = pchild->next;free(pchild);node->parent->degree--;     //这里别忘了,不然后面不好做break;}tmp = tmp->next;}}//删除孩子节点,递归CHILDNODE* child = node->child_link->next;while(child){CHILDNODE* p = child->next;r_delete(tree,child->child);child = p;}free(node->child_link);   //释放孩子节点的头结点free(node);               //释放自我 }//删除pos位节点,以及他的子节点int DelTree(TREE* tree,int pos){if (tree == NULL || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (pos != 0 && pos == tree->len){errno = ERROR;return FALSE;}//找自己的位置,然后递归int i;TREENODE* current = tree->head->next;for (i=0;i<pos;i++){current = current->next;}r_delete(tree,current);}//获取第pos位的数据int Get_Tree(TREE* tree,int pos,TREE_DATA *x){if (tree == NULL || pos < 0 || pos > tree->len){errno = ERROR;return FALSE;}if (pos != 0 && pos == tree->len){errno = ERROR;return FALSE;}int i;TREENODE* current = tree->head->next;for (i=0;i<pos;i++){current = current->next;}*x = current->data;}//清空树所有节点int Tree_Clear(TREE* tree){if(tree == NULL){errno = ERROR;return FALSE;}DelTree(tree,0);return TRUE;}//销毁树int Tree_Destroy(TREE** tree){if(tree == NULL  || *tree){errno = ERROR;return FALSE;}Tree_Clear(*tree);free ((*tree)->head);free(*tree);*tree = NULL;return TRUE;}//求树的节点个数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;CHILDNODE* child = node->child_link->next;int nowheight = 0;int max = 0;while(child){//递归找到字节点的高度nowheight = r_height(child->child);//比较子节点的高度,取最大if(nowheight > max)    max = nowheight;child = child->next;}return max+1;      //返回子节点最大高度加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;//求孩子的度CHILDNODE* child = node->child_link->next;int max = node->degree;    //假设最大度是自己的度int nowdegree = 0;while(child){nowdegree = r_degree(child->child);if(max < nowdegree)max = nowdegree;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;}


原创粉丝点击