C语言 数据结构 实验四 【自用】

C语言 数据结构 实验四


8606 - 二叉树的构建及遍历操作

#include "stdio.h"
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;

typedef char ElemType;
typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode, *BiTree;

Status CreateBiTree(BiTree &T)
{
//算法6.4
//按先序次序输入二叉树中结点的值(一个字符) ’#’字符表示空树
//构造二叉链表表示的二叉树T
    char ch;
    scanf("%c", &ch);
    if (ch == '#') T = NULL;
    else
    {
        if(!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
        T->data = ch; //生成根结点
        CreateBiTree(T->lchild); //构造左子树
        CreateBiTree(T->rchild); //构造右子树
    }
    return OK;
} //CreateBiTree


Status PrintElement(ElemType e)
{
//输出元素e的值
    printf("%c", e);
    return OK;
} //PrintElement


Status PreOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
//前序遍历二叉树T的递归算法 对每个数据元素调用函数Visit
//补全代码 可用多个语句
    Visit = PrintElement;
    if(T)
    {
        Visit(T->data);
        PreOrderTraverse(T->lchild, PrintElement);
        PreOrderTraverse(T->rchild, PrintElement);
    }
    else
    {
        return FALSE;
    }
    return TRUE;
} //PreOrderTraverse

Status InOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
//中序遍历二叉树T的递归算法 对每个数据元素调用函数Visit
//补全代码 可用多个语句
    Visit = PrintElement;
    if(T)
    {
        InOrderTraverse(T->lchild, PrintElement);
        Visit(T->data);
        InOrderTraverse(T->rchild, PrintElement);
    }
    else
    {
        return FALSE;
    }
    return TRUE;
} //InOrderTraverse

Status PostOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
//后序遍历二叉树T的递归算法 对每个数据元素调用函数Visit
//补全代码 可用多个语句
    Visit = PrintElement;
    if(T)
    {
        PostOrderTraverse(T->lchild, PrintElement);
        PostOrderTraverse(T->rchild, PrintElement);
        Visit(T->data);
    }
    else
    {
        return FALSE;
    }
    return TRUE;
} //PostOrderTraverse



int main() //主函数
{
    BiTree T = NULL;

    CreateBiTree(T);

    PreOrderTraverse(T, PrintElement);
    printf("\n");

    InOrderTraverse(T, PrintElement);
    printf("\n");

    PostOrderTraverse(T, PrintElement);
    printf("\n");

    //补充代码
} //main

/*
Description
构造二叉链表表示的二叉树:按先序次序输入二叉树中结点的值(一个字符),'#'字符表示空树,构造二叉链表表示的二叉树T;再输出三种遍历序列。
本题只给出部分代码,请补全内容。


--输入格式--
第一行:输入一棵二叉树的先序遍历序列


--输出格式--
第一行:二叉树的先序遍历序列
第二行:二叉树的中序遍历序列
第三行:二叉树的后序遍历序列


--输入样例--
AB##C##


--输出样例--
ABC
BAC
BCA
*/


8607 - 实现二叉排序树的各种算法(1)

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;

typedef enum {Link,Thread} pointerTag;
typedef int ElemType;
typedef struct _BiTNode
{
    ElemType data;
    struct _BiTNode *lchild, *rchild;
    pointerTag ltag, rtag;
}BiTNode, *BiTree;
BiTree preNode;

typedef BiTree QElemType;
#define MAXQSIZE 100

typedef struct
{
    QElemType *base;
    int front;
    int rear;
}SqQueue;

Status InitQueue(SqQueue &Q)
{
    if(!(Q.base = (QElemType *)malloc(sizeof(QElemType) * MAXQSIZE)))
        return ERROR;
    Q.front = Q.rear = 0;
    return OK;
}

Status EnQueue(SqQueue &Q, QElemType e)
{
    if((Q.rear+1)%MAXQSIZE == Q.front)
        return ERROR;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear+1)%MAXQSIZE;
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e)
{
    if(Q.rear == Q.front)
        return ERROR;
    e = Q.base[Q.front];
    Q.front = (Q.front+1)%MAXQSIZE;
    return OK;
}

Status Insert(BiTree &T)
{
    BiTree inputNode, traverseNode;
    ElemType e;

    scanf("%d", &e);

    if(!T)
    {
        if(!(T = (BiTree)malloc(sizeof(BiTNode))))
        {
            return ERROR;
        }
        T->data = e;
        T->lchild = NULL;
        T->rchild = NULL;
        T->ltag = Link;
        T->rtag = Link;
        return OK;
    }
    else
    {
        if(!(inputNode = (BiTree)malloc(sizeof(BiTNode))))
        {
            return ERROR;
        }
        inputNode->data = e;
        inputNode->lchild = NULL;
        inputNode->rchild = NULL;
        inputNode->ltag = Link;
        inputNode->rtag = Link;
        traverseNode = T;
    }

    while(TRUE)
    {
        if(inputNode->data < traverseNode->data)
        {
            if(!traverseNode->lchild)
            {
                traverseNode->lchild = inputNode;
                return OK;
            }
            else
            {
                traverseNode = traverseNode->lchild;
            }
        }
        else
        {
            if(!traverseNode->rchild)
            {
                traverseNode->rchild = inputNode;
                return OK;
            }
            else
            {
                traverseNode = traverseNode->rchild;
            }
        }
    }
}

void CreateBiTree(BiTree &T)
{
    int n;

    scanf("%d", &n);

    for(int i=0; i < n; i++)
    {
        Insert(T);
    }
}

Status PrintElement(ElemType e)
{
    printf("%d ", e);
    return OK;
}

void PreOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
    if(T)
    {
        Visit(T->data);
        PreOrderTraverse(T->lchild, Visit);
        PreOrderTraverse(T->rchild, Visit);
    }
}

void InOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
    if(T)
    {
        InOrderTraverse(T->lchild, Visit);
        Visit(T->data);
        InOrderTraverse(T->rchild, Visit);
    }
}

void PostOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
    if(T)
    {
        PostOrderTraverse(T->lchild, Visit);
        PostOrderTraverse(T->rchild, Visit);
        Visit(T->data);
    }
}

Status Search(BiTree T, ElemType e)
{
    BiTree pT;

    pT = T;

    while(pT)
    {
        if(pT->data > e)
        {
            pT = pT->lchild;
        }
        else if(pT->data < e)
        {
            pT = pT->rchild;
        }
        else
        {
            return OK;
        }
    }
    return ERROR;
}

void inThreadBiTree(BiTree &T)
{
    if(T)
    {
        inThreadBiTree(T->lchild);

        if(!T->lchild)
        {
            T->lchild = preNode;
            T->ltag = Thread;
        }

        if(!preNode->rchild)
        {
            preNode->rchild = T;
            preNode->rtag = Thread;
        }

        preNode = T;

        inThreadBiTree(T->rchild);
    }
}

void inThreadPreNode(BiTree &T, BiTree &pre)
{
    pre = (BiTree)malloc(sizeof(BiTNode));

    if(!T)
    {
        pre->lchild = pre;
        pre->ltag = Thread;

        pre->rchild = pre;
        pre->rtag = Thread;
    }
    else
    {
        pre->lchild = T;
        pre->ltag = Link;

        preNode = pre;

        inThreadBiTree(T);

        preNode->rchild = pre;
        preNode->rtag = Thread;

        pre->rchild = preNode;
        pre->rtag = Thread;
    }
}

void iteration_InOrderTraverse(BiTree &pre, Status(*Visit)(ElemType))
{
    BiTree pT;

    pT = pre->lchild;

    while(pre != pT)
    {
        while(Link == pT->ltag)
        {
            pT = pT->lchild;
        }
        Visit(pT->data);

        while(Thread == pT->rtag && pre != pT->rchild)
        {
            pT = pT->rchild;
            Visit(pT->data);
        }

        pT = pT->rchild;
    }
}

Status FTraverse(BiTree T)
{
    BiTree pT;
    SqQueue Q;

    pT = T;
    InitQueue(Q);

    EnQueue(Q, pT);
    while(Q.rear != Q.front)
    {
        DeQueue(Q, pT);
        printf("%d ", pT->data);
        if(pT->lchild && Link == pT->ltag)
            EnQueue(Q, pT->lchild);
        if(pT->rchild && Link == pT->rtag)
            EnQueue(Q, pT->rchild);
    }

    return OK;
}

int main()
{
    BiTree pre=NULL, T=NULL;

    CreateBiTree(T);

    PreOrderTraverse(T, PrintElement);
    printf("\n");
    InOrderTraverse(T, PrintElement);
    printf("\n");
    PostOrderTraverse(T, PrintElement);
    printf("\n");

    ElemType e;
    scanf("%d", &e);
    if(Search(T, e)) printf("1\n");
    else             printf("0\n");
    scanf("%d", &e);
    if(Search(T, e)) printf("1\n");
    else             printf("0\n");

    Insert(T);
    PreOrderTraverse(T, PrintElement);
    printf("\n");
    InOrderTraverse(T, PrintElement);
    printf("\n");
    PostOrderTraverse(T, PrintElement);
    printf("\n");

    inThreadPreNode(T, pre);
    iteration_InOrderTraverse(pre, PrintElement);
    printf("\n");

    FTraverse(T);
    printf("\n");
}

/*
Description
用函数实现如下二叉排序树算法:
(1)	插入新结点
(2)	前序 中序 后序遍历二叉树
(3)	中序遍历的非递归算法
(4)	层次遍历二叉树
(5)	在二叉树中查找给定关键字(函数返回值为成功1 失败0)


--输入格式--
第一行:准备建树的结点个数n
第二行:输入n个整数,用空格分隔。
第三行:输入待查找的关键字
第四行:输入待查找的关键字
第五行:输入待插入的关键字


--输出格式--
第一行:二叉树的先序遍历序列
第二行:二叉树的中序遍历序列
第三行:二叉树的后序遍历序列
第四行:查找结果
第五行:查找结果
第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列。
第九行:插入新结点后的二叉树的中序遍历序列(非递归算法)
第十行:插入新结点后的二叉树的层次遍历序列


--输入样例--
7
40 20 60 18 50 56 90
18
35
30


--输出样例--
40 20 18 60 50 56 90
18 20 40 50 56 60 90
18 20 56 50 90 60 40
1
0
40 20 18 30 60 50 56 90
18 20 30 40 50 56 60 90
18 30 20 56 50 90 60 40
18 20 30 40 50 56 60 90
40 20 60 18 30 50 90 56
*/


8608 - 实现二叉排序树的各种算法(2)

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;

typedef int ElemType;
typedef struct _BiTNode
{
    ElemType data;
    struct _BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

typedef BiTree SElemType;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

typedef struct
{
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;

Status InitStack(SqStack &S)
{
    if(!(S.base = (SElemType *)malloc(sizeof(SElemType) * STACK_INIT_SIZE)))
        return ERROR;
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}

Status Push(SqStack &S, SElemType e)
{
    if(S.top-S.base >= S.stacksize)
    {
        if(!(S.base = (SElemType *)realloc(S.base, sizeof(SElemType) * (S.stacksize+STACKINCREMENT))))
           return ERROR;
        S.top = S.base+S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *(S.top++) = e;
    return OK;
}

Status Pop(SqStack &S, SElemType &e)
{
    if(S.top == S.base)
        return ERROR;
    e = *(--S.top);
    return OK;
}

typedef BiTree QElemType;
#define MAXQSIZE 100

typedef struct
{
    QElemType *base;
    int front;
    int rear;
}SqQueue;

Status InitQueue(SqQueue &Q)
{
    if(!(Q.base = (QElemType *)malloc(sizeof(QElemType) * MAXQSIZE)))
        return ERROR;
    Q.front = Q.rear = 0;
    return OK;
}

Status EnQueue(SqQueue &Q, QElemType e)
{
    if((Q.rear+1)%MAXQSIZE == Q.front)
        return ERROR;
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear+1)%MAXQSIZE;
    return OK;
}

Status DeQueue(SqQueue &Q, QElemType &e)
{
    if(Q.rear == Q.front)
        return ERROR;
    e = Q.base[Q.front];
    Q.front = (Q.front+1)%MAXQSIZE;
    return OK;
}

Status Insert(BiTree &T)
{
    BiTree inputNode, traverseNode;
    ElemType e;

    scanf("%d", &e);

    if(!T)
    {
        if(!(T = (BiTree)malloc(sizeof(BiTNode))))
            return ERROR;
        T->data = e;
        T->lchild = NULL;
        T->rchild = NULL;
        return OK;
    }
    else
    {
        if(!(inputNode = (BiTree)malloc(sizeof(BiTNode))))
            return ERROR;
        inputNode->data = e;
        inputNode->lchild = NULL;
        inputNode->rchild = NULL;
        traverseNode = T;
    }

    while(TRUE)
    {
        if(inputNode->data < traverseNode->data)
        {
            if(!traverseNode->lchild)
            {
                traverseNode->lchild = inputNode;
                return OK;
            }
            else
            {
                traverseNode = traverseNode->lchild;
            }
        }
        else
        {
            if(!traverseNode->rchild)
            {
                traverseNode->rchild = inputNode;
                return OK;
            }
            else
            {
                traverseNode = traverseNode->rchild;
            }
        }
    }
}

void CreateBiTree(BiTree &T)
{
    int n;

    scanf("%d", &n);

    for(int i=0; i < n; i++)
    {
        Insert(T);
    }
}

Status PrintElement(ElemType e)
{
    printf("%d ", e);
    return OK;
}

void PreOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
    if(T)
    {
        Visit(T->data);
        PreOrderTraverse(T->lchild, Visit);
        PreOrderTraverse(T->rchild, Visit);
    }
}

void InOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
    if(T)
    {
        InOrderTraverse(T->lchild, Visit);
        Visit(T->data);
        InOrderTraverse(T->rchild, Visit);
    }
}

void PostOrderTraverse(BiTree T, Status(*Visit)(ElemType))
{
    if(T)
    {
        PostOrderTraverse(T->lchild, Visit);
        PostOrderTraverse(T->rchild, Visit);
        Visit(T->data);
    }
}

Status Search(BiTree T, ElemType e)
{
    BiTree pT;

    pT = T;

    while(pT)
    {
        if(pT->data > e)
        {
            pT = pT->lchild;
        }
        else if(pT->data < e)
        {
            pT = pT->rchild;
        }
        else
        {
            return OK;
        }
    }
    return ERROR;
}

void NotRecursionInOrderTraverse(BiTree T)
{
    BiTree pT;
    SqStack S;

    pT = T;
    InitStack(S);

    while(pT || !(S.top == S.base))
    {
        while(pT)
        {
            Push(S, pT);
            pT = pT->lchild;
        }

        Pop(S, pT);
        printf("%d ", pT->data);

        pT = pT->rchild;
    }
}

void LevelTraverse(BiTree T)
{
    BiTree pT;
    SqQueue Q;

    pT = T;
    InitQueue(Q);

    EnQueue(Q, pT);
    while(Q.rear != Q.front)
    {
        DeQueue(Q, pT);
        printf("%d ", pT->data);
        if(pT->lchild) EnQueue(Q, pT->lchild);
        if(pT->rchild) EnQueue(Q, pT->rchild);
    }
}

void SwapBiTree(BiTree &T)
{
    BiTree pT, temp;
    SqStack S;

    pT = T;
    InitStack(S);

    while(pT || !(S.top == S.base))
    {
        while(pT)
        {
            Push(S, pT);
            pT = pT->lchild;
        }

        Pop(S, pT);
        temp = pT->lchild;
        pT->lchild = pT->rchild;
        pT->rchild = temp;

        pT = pT->lchild;
    }
}

int TreeDepth(BiTree T)
{
    int depth, depth_t;
    BiTree pT;
    SqStack S;

    depth = depth_t = 0;
    pT = T;
    InitStack(S);

    while(pT || !(S.top == S.base))
    {
        while(pT)
        {
            Push(S, pT);
            pT = pT->lchild;
            depth_t++;
        }

        Pop(S, pT);
        if(!pT->rchild)
            depth_t--;
        if(!pT->lchild && !pT->rchild && depth < depth_t)
            depth = depth_t;

        pT = pT->rchild;
    }

    return depth;
}

int LeafCount(BiTree T)
{
    int cnt;
    BiTree pT;
    SqStack S;

    cnt = 0;
    pT = T;
    InitStack(S);

    while(pT || !(S.top == S.base))
    {
        while(pT)
        {
            Push(S, pT);
            pT = pT->lchild;
        }

        Pop(S, pT);
        if(!pT->lchild && !pT->rchild)
            cnt++;

        pT = pT->rchild;
    }

    return cnt;
}

int main()
{
    BiTree T=NULL;

    CreateBiTree(T);

    PreOrderTraverse(T, PrintElement);
    printf("\n");
    InOrderTraverse(T, PrintElement);
    printf("\n");
    PostOrderTraverse(T, PrintElement);
    printf("\n");

    ElemType e;
    scanf("%d", &e);
    if(Search(T, e)) printf("1\n");
    else             printf("0\n");
    scanf("%d", &e);
    if(Search(T, e)) printf("1\n");
    else             printf("0\n");

    Insert(T);
    PreOrderTraverse(T, PrintElement);
    printf("\n");
    InOrderTraverse(T, PrintElement);
    printf("\n");
    PostOrderTraverse(T, PrintElement);
    printf("\n");

    NotRecursionInOrderTraverse(T);
    printf("\n");

    LevelTraverse(T);
    printf("\n");

    SwapBiTree(T);
    PreOrderTraverse(T, PrintElement);
    printf("\n");
    InOrderTraverse(T, PrintElement);
    printf("\n");
    PostOrderTraverse(T, PrintElement);
    printf("\n");

    SwapBiTree(T);
    PreOrderTraverse(T, PrintElement);
    printf("\n");
    InOrderTraverse(T, PrintElement);
    printf("\n");
    PostOrderTraverse(T, PrintElement);
    printf("\n");

    printf("%d\n", TreeDepth(T));

    printf("%d\n", LeafCount(T));
}

/*
Description
用函数实现如下二叉排序树算法:
(1) 插入新结点
(2) 前序 中序 后序遍历二叉树
(3) 中序遍历的非递归算法
(4) 层次遍历二叉树
(5) 在二叉树中查找给定关键字(函数返回值为成功1 失败0)
(6) 交换各结点的左右子树
(7) 求二叉树的深度
(8) 叶子结点数


--输入格式--
第一行:准备建树的结点个数n
第二行:输入n个整数,用空格分隔。
第三行:输入待查找的关键字
第四行:输入待查找的关键字
第五行:输入待插入的关键字


--输出格式--
第一行:二叉树的先序遍历序列
第二行:二叉树的中序遍历序列
第三行:二叉树的后序遍历序列
第四行:查找结果
第五行:查找结果
第六行~第八行:插入新结点后的二叉树的先、中、序遍历序列
第九行:插入新结点后的二叉树的中序遍历序列(非递归算法)
第十行:插入新结点后的二叉树的层次遍历序列
第十一行~第十三行:第一次交换各结点的左右子树后的先、中、后序遍历序列。
第十四行~第十六行:第二次交换各结点的左右子树后的先、中、后序遍历序列。
第十七行:二叉树的深度
第十八行:叶子结点数


--输入样例--
7
40 20 60 18 50 56 90
18
35
30


--输出样例--
40 20 18 60 50 56 90
18 20 40 50 56 60 90
18 20 56 50 90 60 40
1
0
40 20 18 30 60 50 56 90
18 20 30 40 50 56 60 90
18 30 20 56 50 90 60 40
18 20 30 40 50 56 60 90
40 20 60 18 30 50 90 56
40 60 90 50 56 20 30 18
90 60 56 50 40 30 20 18
90 56 50 60 30 18 20 40
40 20 18 30 60 50 56 90
18 20 30 40 50 56 60 90
18 30 20 56 50 90 60 40
4
4
*/


8609 - 哈夫曼树

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

typedef char **HuffmanCode;
typedef struct
{
    unsigned int weight;
    unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;

void Select(HuffmanTree &HT, int n, int &s1, int &s2)
{
//在HT[1..n]中选择parent为0且weight最小的两个结点 序号分别为s1和s2
    int i;
    s1 = -1; s2 = -1;
    for(i = 1; i <= n; i++)
    {
        if(0 == HT[i].parent)
        {
            if(-1 == s1)
                s1 = i;
            else if(-1 == s2)
                s2 = i;

            if(HT[i].weight < HT[s1].weight)
            {
                s2 = s1;
                s1 = i;
            }
            else if(HT[i].weight < HT[s2].weight)
            {
                if(i != s1) //因为初进循环s2=-1 所以HT[s2].weight的值为不确定值 导致run和Debug的结果不相同
                    s2 = i;
            }
        }
    }
}

void HuffmanCoding(HuffmanTree &HT, HuffmanCode &HC, int *w, int n)
{
//并求出n个字符的哈夫曼编码HC
    int i, j, m, s1, s2, start;
    char *cd;
    unsigned int c, f;
    if(n <= 1) return;
    m = 2*n-1;
    HT = (HuffmanTree)malloc(sizeof(HTNode) * (m+1));
    for(i = 1; i <= n; i++)
    {
        HT[i].weight = w[i-1];
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
    }
    for(i = n+1; i <= m; i++)
    {
        HT[i].weight = 0;
        HT[i].parent = 0;
        HT[i].lchild = 0;
        HT[i].rchild = 0;
    }

    /*
    printf("\n哈夫曼树的构造过程如下:\n");
    printf("HT初态\n  结点  weight  parent  lchild  rchild");
    for(i = 1; i <= m; i++)
        printf("\n%4d%8d%8d%8d%8d", i, HT[i].weight, HT[i].parent, HT[i].lchild, HT[i].rchild);
    */

    for(i = n+1; i <= m; i++) //构建哈夫曼树
    {
        //在HT[1..i-1]中选择parent为0且weight最小的两个结点 序号分别为s1和s2
        Select(HT, i-1, s1, s2);
        HT[s1].parent = i; HT[s2].parent = i;
        HT[i].lchild = s1; HT[i].rchild = s2;
        HT[i].weight = HT[s1].weight+HT[s2].weight;

        /*
        printf("\nselect: s1=%d   s2=%d\n", s1, s2);
        printf("  结点  weight  parent  lchild  rchild");
        for (j = 1; j <= i; j++)
            printf("\n%4d%8d%8d%8d%8d", j, HT[j].weight, HT[j].parent, HT[j].lchild, HT[j].rchild);
        */

    }
    //--- 从叶子到根逆向求每个字符的哈夫曼编码 ---
    cd = (char *)malloc(n * sizeof(char)); //分配求编码的工作空间
    cd[n-1] = '\0'; //编码结束符。
    for (i = 1; i <= n; i++) //逐个字符求哈夫曼编码
    {
        start = n-1; //编码结束符位置
        for(c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent)
        {
            //从叶子到根逆向求编码
            if(HT[f].lchild == c) cd[--start] = '0';
            else cd[--start] = '1';
        }
        HC[i] = (char *)malloc((n-start) * sizeof(char));
        //为第i个字符编码分配空间
        strcpy(HC[i], &cd[start]); //从cd复制编码(串)到HC
        //////////////&cd[start]:即从start位置为起始位置往后的字符串
    }
    free(cd); //释放工作空间
} //HuffmanCoding

int main()
{
    int i, n;
    int *w;
    HuffmanTree HT;
    HuffmanCode HC;
    //printf("Node Number:");
    scanf("%d", &n); //权值个数
    w = (int *)malloc(n * sizeof(int));
    //printf("Input weights:");
    for (i = 0; i < n; i++) //录入权值
        scanf("%d", &w[i]);

    HC = (char **)malloc((n+1) * sizeof(char*)); //0空间未用
    HT = (HuffmanTree)malloc((2*n+1+1) * sizeof(HTNode)); //0空间未用
    HuffmanCoding(HT, HC, w, n);
    //printf("\n");
    for (i = 1; i < n+1; i++)
    {
        puts(HC[i]); //输出哈夫曼编码
        free(HC[i]); //释放空间
    }
    free(HC);
    free(HT);
} //main

/*
Description
利用静态链表建立赫夫曼树,建树过程中要求左子树权值小于右子树权值,求各结点的编码。
要求:叶子结点的个数n及结点值由键盘录入。本题给出程序代码,要求修改以满足测试要求.


--输入格式--
第一行:权值个数
第二行:输入n个权值 用空格分隔


--输出格式--
输出n行
每行表示各权值对应的哈夫曼编码


--输入样例--
8
5 29 7 8 14 23 3 11


--输出样例---
0001
10
1110
1111
110
01
0000
001
*/


【自用】


上一篇文章:
C语言 数据结构 实验三 【自用】
下一篇文章:
C语言 数据结构 实验五 【自用】

相关文章:
C语言 数据结构 线索二叉树
C语言 数据结构 哈夫曼编码

发布了18 篇原创文章 · 获赞 1 · 访问量 675

猜你喜欢

转载自blog.csdn.net/LangYueMoon/article/details/104089770