數據結構——樹

頭文件:

#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 根節點的位置是 0
int 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);


#endif  // __TREE_H__

錯誤信息頭文件:

#ifndef __ERROR_H__
#define __ERROR_H__

#include <stdio.h>

#define TRUE           1
#define FALSE          0
#define ERROR         -1
#define MALLOC_ERROR  -2

int errno;     // 錯誤號

void myError(char *str);

char* myStrError(int num);


#endif // __ERROR_H__

輸出錯誤信息函數:

#include "error.h"

void myError(char *str)
{
    char *msg = myStrError(errno);
    printf ("%s: %s\n", str, msg);
}

char* myStrError(int num)
{
    switch (errno)
    {
        case ERROR:
            return "輸入參數錯誤";    
        case MALLOC_ERROR:
            return "malloc空間分配失敗";  
    }
}

功能函數:

#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->head = (TreeNode*)malloc(sizeof(TreeNode)/sizeof(char));
    if (tree->head == NULL)
    {
        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;
}

/*
TreeData data;
struct _treeNode *parent;      // 指向父節點的指針          11111111111
struct _treeNode *next;        // 指向鏈表的下一個結點
struct _childNode *childList;  // 孩子鏈表的頭節點
int degree;                    // 結點的度

typedef struct _childNode
{
    struct _treeNode * childNode;
    struct _childNode *next;  // 指向孩子結點鏈表下一個元素
}ChildNode;
*/

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->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* 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", '-');
    }

    // 打印結點自己
    // 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 (tree == NULL)
        return;

    r_display(tree->head->next, 0, pFunc);
}

void r_delete(Tree *tree, TreeNode *node)
{
    if (tree == NULL || node == NULL)
        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 (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;
        }
    }

    // 將該結點的孩子結點刪掉
    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 (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 Tree_Get(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;
    return Delete (tree, 0, &x);
}

void Tree_Destroy(Tree* tree)
{
    if (tree == NULL)
    {
        errno = ERROR;
        return;
    }

    Tree_Clear(tree);

    free (tree->head);
    free (tree);
}

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_height(TreeNode* node)
{
    if (node == NULL)
        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 (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;

    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 (tree == NULL)
    {
        errno = ERROR;
        return FALSE;
    }

    int degree = r_degree(tree->head->next);

    return degree;
}

main函數:

#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);
    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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章