数据结构之树的一些基本操作

来源:互联网 发布:淘宝旺旺号有什么用 编辑:程序博客网 时间: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是我自己写的一个包含常见错误的头文件,这里我就不发了。

原创粉丝点击