哈夫曼树的c++数据结构实现

大兔子大兔子 提交于 2019-12-23 21:36:02

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

    哈夫曼树在理论上的构造方法很简单,不赘述,现介绍哈夫曼树的c++数据结构实现

    大体来说,是一个由结构体组成的数组,每个结构体都是一个哈夫曼树的节点,数组的所有节点表示哈夫曼树,从实质上来说还是存在于一串连续的内存地址中。

   1, 每个哈夫曼节点,可以用结构体表示,有权重,父子节点。父子节点的值是用节点在数组中的位置表示的。

struct element {
	int weight;
	int lchild, rchild, parent;
};

     2,哈夫曼树的构造有一个规律,将n个节点构造一个哈夫曼树,需要且仅需要n-1次合并,每次合并会产生一个新节点,所以最终的哈夫曼数的数组长度为2*n-1;在初始化数组长度的时候,这一点需要注意

element *hufftree = new element[2 * n - 1];

    3,所需要的子函数有三个:

    构造哈夫曼树的主函数

void createHaffumanTree(element haffTree[], int w[], int n)

    a——将所有节点父节点置为-1,在之后的算法中,父节点是不是-1是判断节点是否为树根的标志:是树根的节能才能参与合并。b——调用选择算法选择权重最小的两个节点,将他们合并成新的节点,并将父子,权重做合适调整。合并成新的节点不是要去创造新节点,新节点一开始就创造好了。这里利用一个k从n开始到2n-1结束的循环,hufftree[k]就是所谓的新的节点。

for (int k = n; k < 2 * n - 1; k++)

   

    选择权重为最小和第二小的函数

void selectMin(element a[], int b, int& s1, int& s2) //b为当前参与构造的哈夫曼树节点个数

    关键是利用两个for循环,分别找出第一和第二权重的节点,找权重第一的节点:先任意选一个parent为-1的节点,再和每一个parent为-1的节点相比较。找权重为第二的节点:找出不与前者相同且权重最小的的节点。

    输出哈夫曼树

void print(element hT[], int n) 

   setw()这个接口可以限定之后输出的字符占几个空格

   遍历直接输出就好

 

    完整的代码

#include<iostream>
#include <iomanip>//这个头文件是声明一些 “流操作符”的
//比较常用的有:setw(int);//设置显示宽度,left//right//设置左右对齐。 setprecision(int);//设置浮点数的精确度。
using namespace std;


struct element {
	int weight;
	int lchild, rchild, parent;
};

void selectMin(element a[], int b, int& s1, int& s2) { //b当前参与构造的哈夫曼树节点个数
	for (int i = 0; i < b; i++) {
		if (a[i].parent == -1) {
			s1 = i;
			break;
		}
	}
	for (int i = 0; i < b; i++) {
		if (a[i].parent == -1 && a[s1].weight > a[i].weight) {
			s1 = i;
		} //至此,权值最小的节点已被选中至s1
	}

	for (int j = 0; j < b; j++) {
		if (a[j].parent == -1 && j != s1) {
			s2 = j;
		}
	}
	for (int j = 0; j < b; j++) {
		if (a[j].parent == -1 && a[s2].weight > a[j].weight && j != s1) {
			s2 = j;
		} //至此,权值第二小的节点已被选中至s2
	}
}

void createHaffumanTree(element haffTree[], int w[], int n) {
	for (int i = 0; i < n; i++) {
		haffTree[i].lchild = -1;
		haffTree[i].rchild = -1;
		haffTree[i].parent = -1;
		haffTree[i].weight = w[i];
	}

	for (int k = n; k < 2 * n - 1; k++) {
		int s1, s2;
		haffTree[k].parent = -1;
		selectMin(haffTree, k, s1, s2);
		haffTree[k].weight = haffTree[s1].weight + haffTree[s2].weight;
		haffTree[k].lchild = s1;
		haffTree[k].rchild = s2;
		haffTree[s1].parent = k;
		haffTree[s2].parent = k;
	}
}


void print(element hT[], int n) {
	cout << "index weight parent lChild rChild" << endl;
	cout << left;
	for (int i = 0; i < n; i++) {
		cout << setw(5) << i << " ";
		cout << setw(6) << hT[i].weight << " ";
		cout << setw(6) << hT[i].parent << " ";
		cout << setw(6) << hT[i].lchild << " ";
		cout << setw(6) << hT[i].rchild << " \n";
	}
}

int main()
{
	int w[] = { 15,29,7,8,14,23,3,11 };
	element *hufftree = new element[2 * 8 - 1];
	createHaffumanTree(hufftree, w, 8);
	print(hufftree, 2*8-1);
	system("pause");
	return 0;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!