数据结构之树的一些基本操作
来源:互联网 发布:淘宝旺旺号有什么用 编辑:程序博客网 时间:2024/05/22 08:01
树是由根结点和若干颗子树构成的。树是由一个集合以及在该集合上定义的一种关系构成的。集合中的元素称为树的结点,所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构。在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点,或称为树根。
头文件 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 根节点的位置是 0int 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; // 代表树中没有结点 // 空树结点为0 tree->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是我自己写的一个包含常见错误的头文件,这里我就不发了。
阅读全文
0 0
- 数据结构之树的一些基本操作
- 数据结构之二叉树的一些基本操作
- 数据结构之顺序栈的一些基本操作
- 数据结构之链式栈的一些基本操作
- 数据结构之二叉树的基本操作
- 数据结构之一般树的基本操作
- 数据结构之树的基本操作
- 数据结构之顺序表的基本操作
- 数据结构之图(图的基本操作)
- 数据结构之双链表的基本操作
- 数据结构之顺序串的基本操作
- 数据结构之栈的基本操作
- 数据结构之链表的基本操作
- 数据结构之栈的基本操作
- 数据结构查找之-单链表的基本操作
- 数据结构之单链表的基本操作
- 数据结构中线性表的一些基本操作
- C语言数据结构单链表的一些基本操作
- C++实现单例模式
- NP难问题与过拟合
- PHP变量
- 【shell】变量内容的删除和替换
- 构造函数、析构函数、拷贝构造函数,常函数
- 数据结构之树的一些基本操作
- Eclipse Debug不为人知的秘密
- jQuery学习笔记01
- 友元函数和运算符重载
- Java多线程基础--03之 Thread中start()和run()的区别
- 【PAT】1017. The Best Peak Shape
- ACM_20
- SSH服务器
- Linux下高级I/O多路转接之poll服务器