哈夫曼树称为最优树,即是一类带权路径长度最短的数
图解:
结构:
主要有四部分,data存数据,left,right指向左右。
parent=1代表该结点已经被写入树里面,parent=0代表还没被写进树里面
下面一行数如何变成哈夫曼树
构造后如下:
下图可知每一层从左到右都是增加的;
构造函数编写思路:
第一步:先定义一个Node类型的数组:Node *a[100];
然后赋值:
a[i]=new Node;
cin >>a[i]->data;
a[i]->parent = 0;
第二步:从里面获取最小的两个数
int x=0,xx=0, y=0,yy=0; //x第一个最小数的值,xx第一个最小数的下标,y,yy是第二个
for (int i = 0; i < n; i++)
{
if (a[i]->parent == 0)
{
x = a[i]->data; xx = i; //找到第一个parent=0的结点,即还未被加入树中
}
}
for (int i = 0; i < n; i++)
{
if (a[i]->data <= x && a[i]->parent==0) //通过循环找到最小的
{
x = a[i]->data;
xx = i;
}
}
a[xx]->parent = 1; //找到后该值接下来就会被加入树中,所以此处将parent变为1
for (int i = 0; i < n; i++)
{
if (a[i]->parent == 0)
{
y = a[i]->data; yy = i; //跟上面类似(第二个)
}
}
for (int i = 0; i < n; i++)
{
if (a[i]->data <= y && a[i]->parent==0)
{
y = a[i]->data;
yy = i;
}
}
a[yy]->parent = 1;
第三步:
for (int i = 0; i < n - 1; i++)
{
get(a, b, c,n); //得到两个最小值
Node *m = new Node;
Node *n = new Node; //新定义两个新节点,储存两个最小值
m->data = a[b]->data;
n->data = a[c]->data;
Node *k = new Node; //再定义一个,作为前面两个的父节点
k->left = m;
k->right = n;
k->data = m->data + n->data;
a[b]->data = k->data; //将新的的结点重新加入数组中,此处直接替换b的值,循环利用
a[b]->parent = 0; //因为第二步,将b加入树了,所以parent=1;此处因为用k替换了所以,有换为0
}
代码
#include<iostream>
using namespace std;
struct Node
{
int parent;
int data;
Node *left, *right;
};
void get(Node *a[],int &b,int &c,int n)
{
int x=0,xx=0, y=0,yy=0;
for (int i = 0; i < n; i++)
{
if (a[i]->parent == 0)
{
// cout << "b";
x = a[i]->data; xx = i;
}
}
for (int i = 0; i < n; i++)
{
// cout << "a";
if (a[i]->data <= x && a[i]->parent==0)
{
// cout << "b";
x = a[i]->data;
xx = i;
}
}
// cout << xx << " " << x << endl;
a[xx]->parent = 1;
b = xx;
for (int i = 0; i < n; i++)
{
if (a[i]->parent == 0)
{
y = a[i]->data; yy = i;
}
}
for (int i = 0; i < n; i++)
{
if (a[i]->data <= y && a[i]->parent==0)
{
y = a[i]->data;
yy = i;
}
}
// cout << yy << " " << y << endl;
a[yy]->parent = 1;
c = yy;
}
int main()
{
Node *a[100];
int n;
cout << "n个值:";
cin >> n;
for (int i = 0; i < n; i++)
{
a[i]=new Node;
cin >>a[i]->data;
a[i]->parent = 0;
}
int b, c;
for (int i = 0; i < n - 1; i++)
{
get(a, b, c,n);
Node *m = new Node;
Node *n = new Node;
m->data = a[b]->data;
n->data = a[c]->data;
Node *k = new Node;
k->left = m;
k->right = n;
k->data = m->data + n->data;
// cout << k->data <<" "<< endl;
a[b]->data = k->data;
a[b]->parent = 0;
}
// cout << a[b]->data;
getchar();
getchar();
return 0;
}