zoukankan      html  css  js  c++  java
  • 哈夫曼树的构建及遍历

    哈夫曼树是一棵怎样的树呢,假如我们给出一堆数据"1,2,3,4,5"(数据对应的数字还代表这个数字出现的次数)来构建一颗二叉树,怎样一颗二叉树才能使我们的查找效率率最高呢,那就是哈夫曼树了,在前面的“1,2,3,4,5”中,我们先选出两个最小的,那就是“1,2”,然后1和2构建一个结点。该结点为3,左右子树为“1,2”,把该结点3放进去后,现在的数据就是“3,3,4,5”,然后我们再从这里面选出两个最小的--"3,3",加起来就是6,放进去后就是“6,4,5”,依次循环。

    我们可以利用堆来实现,我们先把数据放入一个最小堆,然后建立一颗树结点,该树的左子树对于第一个出堆的结点数据,右子树等于第二个出堆的,该结点的值就为左右子树的值加起来,然后再放进堆,然后又从堆里面选出两个最小的值的结点为左右子树,依次这样,直到最后一个结点放进去,然后出堆。这样一颗哈夫曼树就构建成功了,为了方便我们看清楚它的样子,也为了方便我加强前面队列的印象,我就用了层次遍历把这个哈夫曼树遍历了一遍,层次遍历会运用到队列的思想,先将第根结点进队,然后输出,再将他的左右子树进队,然后出队,(反正就是每出一次队,我们就要将这个结点的左右子树存入进去)。这样直到队列为空。

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


    typedef struct huf {
    int weight;
    struct huf *left,*right;
    }Huf,*HufTree;//哈夫曼树的结构体。

    typedef struct Heap {
    Huf *data;
    int size;
    int maxsize;
    }Heap,*HNode;//堆的结构体。

    typedef struct Queue {
    Huf *data;
    int front;
    int rear;
    int maxsize;
    }Queue,*QNode;//队列的结构体。

    void InitHeap (HNode *H);//初始化堆。
    void InsertToHeap (HNode H,Huf *T);//插入堆。
    HufTree DeleteHeap (HNode H);//出堆。
    int IsFullHeap (HNode H);//判断堆是否为满。
    int IsEmptyHeap (HNode H);//判断堆是否为空。
    HufTree CreateHufTree (int n);//创建一个n个数据的一个哈夫曼树。
    void InitQueue (QNode *Q);//初始化队列。
    void InsertQueue (QNode Q,Huf *T);//进队。
    HufTree DeleteQueue (QNode Q);//出队。
    int IsFullQueue (QNode Q);//判断队是否为满。
    int IsEmptyQueue (QNode Q);//判断队是否为空。
    void LevelTree (HufTree T);//层次遍历树。


    int main ()
    {
    int n;
    scanf("%d",&n);
    HufTree T = CreateHufTree (n);//创建一颗树。
    LevelTree(T);//层次遍历该树。
    return 0;
    }

    void LevelTree (HufTree T)
    {
    QNode Q;
    InitQueue (&Q);
    InsertQueue(Q,T);

    while (!IsEmptyQueue(Q)) {
    HufTree temp;
    temp = DeleteQueue(Q);
    printf("%d ",temp->weight);
    if(temp->left) InsertQueue(Q,temp->left);
    if(temp->right) InsertQueue(Q,temp->right);
    }
    }

    void InitQueue (QNode *Q)
    {
    *Q = malloc(sizeof(Queue));
    (*Q)->maxsize = 10;
    (*Q)->data = (Huf*)malloc(sizeof(Huf)*(*Q)->maxsize);
    (*Q)->front= (*Q)->rear = 0;
    }

    int IsFullQueue (QNode Q)
    {
    return (Q-> rear + 1) % (Q->maxsize) == Q->front;
    }

    int IsEmptyQueue (QNode Q)
    {
    return Q->rear == Q->front;
    }

    void InsertQueue (QNode Q,Huf *T)
    {
    if(IsFullQueue (Q)) {
    printf("The queue is full! ");
    return;
    }

    Q->data[Q->rear] = *T;
    Q->rear = (Q->rear + 1) % (Q->maxsize);

    }

    HufTree DeleteQueue (QNode Q)
    {
    if (IsEmptyQueue(Q)) {
    printf("The queue is empty! ");
    return NULL;
    }

    Huf *temp;
    temp = malloc(sizeof(Huf));
    *temp = Q->data[Q->front];
    Q->front = (Q->front+1) % (Q->maxsize);

    return temp;
    }


    HufTree CreateHufTree (int n)
    {
    HNode H;
    InitHeap(&H);
    int x;
    for(int i = 1; i <= n;i++) {
    printf("x is :");
    scanf("%d",&x);
    Huf *temp = malloc(sizeof(Huf));
    temp->weight = x;
    temp->left = temp->right = NULL;
    InsertToHeap(H,temp);
    }

    HufTree Tree;
    for(int i = 1; i < n;i++) {
    Tree = malloc(sizeof(Huf));
    Tree->left = DeleteHeap(H);
    Tree->right = DeleteHeap(H);
    Tree->weight = Tree->left->weight + Tree->right->weight;
    InsertToHeap(H,Tree);
    }

    Tree = DeleteHeap(H);

    return Tree;
    }

    void InitHeap (HNode *H)
    {
    (*H) = (HNode) malloc (sizeof(Heap));
    (*H)->data = (Huf*)malloc(sizeof(Huf)*10);
    (*H)->size = 0;
    (*H)->maxsize = 10;
    (*H)->data[0].weight = -1;
    }

    int IsFullHeap (HNode H)
    {
    return (H->size == H->maxsize - 1);
    }

    int IsEmptyHeap (HNode H)
    {
    return (H->size == 0);
    }


    void InsertToHeap (HNode H, Huf *T)
    {
    if (IsFullHeap(H)) {
    printf("The heap is full! ");
    return ;
    }
    H->size++;
    int i = H->size;
    while (H->data[i/2].weight > T->weight) {
    H->data[i] = H->data[i/2];
    i = i /2;
    }

    H->data[i] = *T;
    }

    HufTree DeleteHeap (HNode H)
    {
    if (IsEmptyHeap(H)) {
    printf("The heap is empty! ");
    return NULL;
    }
    Huf *Min;
    Min = malloc(sizeof(Huf));
    *Min = H->data[1];
    Huf *temp;
    temp = malloc(sizeof(Huf));
    *temp = H->data[H->size];
    H->size--;

    int parent,child;

    for(parent = 1;parent * 2 <= H->size;parent = child) {
    child = parent * 2;
    if (child != H->size && H->data[child].weight > H->data[child+1].weight) {
    child++;
    }

    if (temp->weight <= H->data[child].weight) break;
    else H->data[parent] = H->data[child];
    }

    H->data[parent] = *temp;

    return Min;
    }

    代码就如上,若读者有任何不懂,可以留言,期待下一次!

  • 相关阅读:
    Advanced Sort Algorithms
    Bash Excercises
    分布式Java应用与实践 (一)
    Configure HttpClient correctly
    Automated Front End Test
    linux 判断一个用户是否存在 _fei
    linux 系统扩容 VMware Centos---VMware ESXi
    ESX 基本使用 _fei
    centos jira wiki 开机自启
    svn 添加子目录后检出失败 _fei
  • 原文地址:https://www.cnblogs.com/ranyang/p/13892828.html
Copyright © 2011-2022 走看看