哈夫曼树Huff的创建

①定义以及作用
哈夫曼树:哈夫曼树是字符的编码,目的是为了获取最小的WPL,即最小的代价(表达能力有限,不知道咋说),顾名思义来理解吧,就是为了编码!!!
哈夫曼的创建
哈夫曼树的创建是基于堆来实现的,所以事先需要对堆有所了解,查看上篇博客QAQ。。
哈夫曼树树的建树原理,想必大家都知道,就是根据权值数组来建立的:

过程是:1.从权值数组中挑选出两个最小的权值,建立两个树节点,作为左右儿子,父节点的值为左右儿子值的和。
2.将父节点的权值放入权值数组中,然后从步骤1继续开始,直到权值数组为空。

那么,哪里会用到堆????
①利用堆,来存储权值数组,实现最小权值的获取和新的权值的插入,时间复杂度为logn
------>也许有的童鞋会想 (因为我这个童鞋也在想,QAQ,到底为什么?)

假如我用结构体数组来存储权值,在插入新权值,用二分插入,时间复杂度也是logn呀!!

-------------------大家原谅我的无知,因为堆的实现就是数组TvT!----------------------
②大家应该知道,堆的Insert()插入函数,插入的一个数据data,对于哈夫曼树的创建,则插入的是一个哈夫曼树节点,即如下的一个节点:(也就是平常无奇的一个树节点而已)

typedef struct Huff_Node *huff;
struct Huff_Node{huff left; //右儿子huff right; //左儿子int w; //该节点的权值
};

看到这里,小伙伴们应该知道了,哈夫曼树,其实就是利用堆来搭建起来的(简言之,利用堆来找节点的左儿子和右儿子,然后遍历完数组就完事了!然后整棵树就建立完成,返回根节点,具体看下面代码来深入理解,一言不合就撸代码(→ .→))
Huff树构建
如前面所说,堆存储的哈夫曼节点,故堆heap结构体的定义如下:

typedef struct Heap_Node *heap;
struct Heap_Node{huff data; //哈夫曼节点指针变量int size;
};

创建空堆heap的代码如下:

heap creat_empty_heap(int n){heap tmp = (heap)malloc(sizeof(struct Heap_Node));    //开辟大小为n+1个哈夫曼结构体大小的数组  tmp->data = (huff)malloc(sizeof(struct Hudd_Node) * (n + 1))tmp->size = 0;    tmp->data[0].w = -999; //哨兵return tmp;
}

向堆中插入huff哈夫曼节点代码如下:

void Insert(heap h,struct Huff_Node hu){ //简单的insert操作,堆的插入操作int i= ++h->size;    int w = hu.w;    for (; h->data[i / 2].w > w;i = i/2){h->data[i] = h->data[i / 2];}    h->data[i] = hu;
}

获取最小堆中权值最小的哈夫曼节点,即根节点:

huff delete_minheap(heap h){huff ans = (huff)malloc(sizeof(struct Huff_Node));    *ans = h->data[1];    struct Huff_Node x=  h->data[h->size--];    int parent = 1, child;    for (; parent * 2 <= h->size;parent = child){child = parent *2;        if(child + 1 <=h->size && h->data[child + 1].w < h->data[child].w)            child++;        if(h->data[child] >= x.w)            break;        h->data[parent] = h->data[child];}    h->data[parent] = x;    return ans;
}

创建哈夫曼树,过程如下:

1.定义一个huff节点,左儿子为堆中最小权值节点,右儿子为删除最小权值节点后,二次获取的最小权值节点,该huff节点的权值为两儿子节点权值之和。
2.将生成的新的huff节点插入堆中,继续步骤1,进行h->size - 1步,因为最后堆中只剩一个哈夫曼节点,也就是传说总的huff树根节点
3.最后获取堆中最后一个节点,直接原地返回

代码如下:

huff create_huff(heap h){huff tmp;    int len = h->size;    for (int i = 1; i <len; i++){tmp = (huff)malloc(sizeof(struct Huff_Node));        tmp ->left = delete_minheap(h);        tmp ->right = delete_minheap(h);        tmp->w = tmp->left->w + tmp->right->w;        Insert(h, *tmp);}    tmp = delete_minheap(h);    return tmp;
}

主函数如下:

int main(){int n,data;    heap h;    huff hu;    cin >> n;    h = creat_empty_heap(n);    for (int i = 1; i<=n; i++){cin>>data;hu = (huff)malloc(sizeof(struct Huff_Node));        hu->w = data;        hu->left = NULL;        hu->right = NULL;        Insert(h, *hu);    }    hu = create_huff(p);    return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部