这是我学了这么多天感觉最难的,用了两个链表进行嵌套。
思路:先用一个链表保存所有树结点,由于不知道每个树有多少子节点,就再用一个链表保存子节点的位置。
数据结构的课是上完了,但是肯定还是不够的,以后我还会在整理。但是近期就难说,逼近我还有下面的课程。
头文件
#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;
}