数据结构探险——二叉树的线索化和霍夫曼树

#include <stdio.h>
#include <stdlib.h>
// 线索化的实质就是将二叉链表中的空指针改为指向前驱或后继的线索
typedef DataType char;

typedef struct node
{
    DataType data;
    int leftFlag,rightFlag; //c 没有bool,枚举也行
    struct node *left,*right;
}BTNode,*PBTNode,*BiTreeLink;

PBTNode pre;

void InThreading(PBTNode p)
{
    if(p)
    {
        InThreading(p->left);//1
        if(!p->left)//--
        {
            p->leftFlag = 1;
            p->left = pre;
        }else p->leftFlag = 0;
        if(!pre->right)/
        {
            pre->rightFlag = 1;
            pre->right = p;
        }else p->rightFlag = 0;
        pre = p;//-- 
        InThreading(p->right);//2
    }
}//按1 -- 2顺序,中序线索化
if(p)
    {
        InThreading(p->left);
        pre = p;
        InThreading(p->right);
    }

保证pre是p的前驱

PBTNode InOderNext(PBTNode p)
{
    PBTNode q = p->right;
    if(p->rightFlag == 0)
    {
        while(q->leftFlag == 0)
            q = q->left;
    }
    return q;
}

PBTNode InOderPrior(PBTNode p)
{
    PBTNode q = p->left;
    if(p->leftFlag == 0)
    {
        while(q->rightFlag == 0)
            q = q->right;
    }
    return q;
}

void InThreadTraverse(BiTreeLink root)
{
    PBTNode p = root->leftFlag;
    while(p->leftFlag == 0) p = p->left;
    while(p != root)
    {
        printf("%c\t",p->data);
        p = InOderNext(p);
    }
}

哈夫曼算法和哈夫曼树

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述


#define MAX 100
typedef DataType char;

typedef struct node
{
    DataType data;
    int left;
    int right;
    int parent;
    int weight;
}HufNode;

typedef struct
{
    char code[MAXBIT];
    int start;
}HufCode;

//创建哈夫曼树
void HuffmanTree(int weight[],DataType ch[],int n,HufNode hf[])
{
    int i,j,node1,node2,mw1,mw2;
    for(i = 0; i < 2*n - 1; i ++)
    {
        if(i < n)
        {
          hf[i].weight = weight[i];
          hf[i].data   = ch[i];
        }else hf[i].weight = 0;
        hf[i].left = -1;hf[i].right = -1;hf[i].parent = -1;
    }
    for (i = n; i < 2*n -1;i ++)
    {
        mw1 = mw2 = MAX;
        node1 = node2 = -1;
        for (j = 0; j < i - 1;j ++)
        {
            if(hf[j].parent == -1)
            {
                if(hf[j].weight < mw1)
                {
                    mw2 = mw1;
                    node2 = node1;
                    mw1 = hf[j].weight;
                    node1 = j;
                }else if(hf[j].weight < mw2)
                {
                    mw2 = hf[j].weight;
                    node2 = j;
                }
            }
        }
        hf[i].weight = hf[node1].weight + hf[node2].weight;
        hf[i].left = node1;
        hf[j].right = node2;
        hf[node1].parent = i;
        hf[node2].parent = i;
    }
}

//编码
void HuffmanCode(HufNode hf[],HufCode hfc[],int n)
{
    int parent,node,i;
    HufCode hc;
    for ( i = 0; i < n; ++i)
    {
        hc.start = n;
        node = i;
        parent = hf[i].parent;
        while(parent != -1)
        {
            if(hf[parent].left == node)
                hc.code[start --] = '0';
            else
                hc.code[start --] = '1';
            node = parent;
            parent = hf[node].parent;
        }
        hc.start ++;
        hfc[i] = hc;
    }
}

重要:
1.从一堆数中取出最小的两个数
假定一堆n个数是存储在数组a中,用mw1记录最小的,mw2记录第二小的。

for(int i = 0;i < n;i ++)
{
   if(a[i] < mw1) 
   {
      mw2 = mw1;
      mw1 = a[i];
   }else if(a[i] < mw2)
   {
      mw2 = a[i];
   }
}

2.哈夫曼编码中数组的运用

猜你喜欢

转载自blog.csdn.net/DanielDingshengli/article/details/81223042