数据结构第五节(树(下))

上次咱们说了二叉搜索树与平衡二叉树,此次我能说树的另外一个应用:堆。node

什么是堆

咱们想象一个情景,须要将任务优先级高的放在前面(优先队列),咱们如何实现呢?ios

若是用数组作的话,插入咱们从尾部插入,寻找优先级最高的元素,以及删除该元素后移动须要的操做都是巨大的,很明显不是一个好方法。数组

若是咱们直接在插入时保证整个数组有序,那么在删除时咱们只须要删除最后一个节点,但插入时虽然可用二分查找下降时间复杂度,但移动人须要很大的时间复杂度。数据结构

若是用链表作的话插入咱们从尾部插入,查找时须要的时间复杂度同数组同样,但删除时只须要\(O(1)\)ide

若是采用有序链表,咱们发现与从尾部插入毫无差别,只是查找复杂度,从删除时转移到了插入时。测试

这些方法都会有使人不满意的地方,那么有没有一种方法,比以上方法都好?那就是用彻底二叉树构成一个堆,(使根结点的值大于它的左右节点,这样的堆咱们又叫它大顶堆,相反的若是小于,它就是小顶堆)。容易发现,从根节点向下画任何一条线,都是有序的,选取下标为1的位置为根结点,树中全部结点的左右儿子为他的二倍和二倍加一,也就是除根结点外,每一个节点的下边除以2就是它的父节点,很容易的咱们发现,这样的数据结构在插入和删除操做时,最坏的时间复杂度都为\(O(logN)\)this

堆的结构表示

#define MAXDATA 99999999999
typedef struct HeapStruct* Heap;

struct HeapStruct
{
	ElementType* Elements;
	int Size;
	int Capacity;
};
//creat heap
Heap CreatHeap(int MaxSize) {
	Heap H = (Heap)malloc(sizeof(struct HeapStruct));
	H->Elements = malloc((MaxSize + 1)*sizeof(ElementType));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Elements[0] = MAXDATA;
	return H;
}

堆的插入

在进行插入操做时,直接插入堆的末尾,由于堆的性质保证路线有序,只需调整插入位置沿复节点到根结点的路径有序便可。编码

void Insert(Heap H,ElementType X) {
	//check the heap is full
	if (IsFull(H)) {
		printf("the heap is full.\n");
		return;
	}
	int i = ++H->Size;
	//if X big than his father,X become father
	for ( ; H->Elements[i / 2]<X; i/=2)
	{
		H->Elements[i] = H->Elements[i / 2];
	}
	H->Elements[i] = X;
}

堆的删除

再进行删除操做时,直接取走头部(这个位置一定最大),并将堆的末尾赋值头部,接着循环比较左右儿子的大小,选出一个大的与其交换,直到路径有序后中止。spa

//delete
ElementType Delete(Heap H) {
	if (IsEmpty(H)) {
		printf("the heap is empty.\n");
		return;
	}
	ElementType MaxItem = H->Elements[1];
	ElementType temp = H->Elements[H->Size--];
	int parent, child;
	for (parent = 1; parent * 2 <= H->Size; parent = child) {
		child = parent * 2;
		//if his right son big the the left son
		if ((child != H->Size) && (H->Elements[child] < H->Elements[child + 1])) {
			child++;
		}
		//the temp is the max item int this sub tree
		if (temp >= H->Elements[child]) {
			break;
		}
		//move the child to the parent location
		else {
			H->Elements[parent] = H->Elements[child];
		}
	}
	H->Elements[parent] = temp;
	return MaxItem;
}

哈夫曼树

什么是哈弗曼树呢?让咱们想象一个情景,须要给不一样分数段区间的学生打分A,B,C,D。每一个分数段的人数不一样。在构造这个断定程序时,如何让比较的次数最少,很天然的想法哪一个分数段的人多,就先从那个条件判断,出现越少的分数段,越晚去判断那个条件。(贪心的思想)
定义:给定N个权值做为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。code

哈夫曼树的构造

知道了哈夫曼树的性质那咱们该如何写出一个哈夫曼树呢?上面咱们已经说过,出现几率最小的越晚判断,很天然的,首先咱们找出2个权值最小的点,做为树的初始叶节点,同时计算这两个点的权值和。接着找两个最小的权值点,范围也包括咱们上次生成权值和,递归的作合并直到全部的节点都被链接 。找最小的两个点,咱们能够用上面所讲到的堆,每次出两个最小的(Delete),再将他们的权值和插入。

typedef struct HuffmanNode* HuffmanTree;
struct HuffmanNode
{
	ElementType1 weight;
	HuffmanTree Left;
	HuffmanTree Right;
};
//creat huffmantree
HuffmanTree creat(Heap H) {
	HuffmanTree T;
	for (int i = 1; i < H->Size; i++)
	{
		T = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
		T->Left = Delete(H);
		T->Right = Delete(H);
		T->weight = T->Left->weight + T->Right->weight;
		Insert(H, T);
	}
	T = Delete(H);
	return T;
}

哈夫曼树的特色

  1. 没有度为1的节点
    这个很容易想到,由于在构造哈夫曼树的过程当中,老是用左右两个节点去合并,全部的节点都有左右儿子或者没有儿子
  2. N个叶子节点的哈夫曼树有2N-1个节点
    咱们以前说过对于任何一二叉树,度为0的节点等于度为2的节点+1(\(n_0\)=\(n_2\)+1),根据上一条性质没有度为1的节点。故整个树拥有的节点为\(n_0\)+\(n_2\) = 2*\(n_0\) - 1,即\(2N-1\)
  3. 哈弗曼树任何一个节点的左右指数相交换仍然是哈弗曼树
    由于咱们在生成时并无规定左右哪一个大哪一个小,因此很天然该条成立。

哈夫曼编码的实现

上面咱们已经说到如何构建一棵哈夫曼树,接下来经过对一颗哈弗曼树的遍历,咱们就能够实现哈弗曼编码。递归的去作中序遍历,若是遍历到的节点既没有左儿子也没有右儿子,那么能够说明,该节点为叶节点也就是咱们须要输出编码的节点,同时,在递归的遍历过程当中,进入左边就0,进入右边就加1,下面给出代码实现。

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string>
#define ElementType HuffmanTree
#define ElementType1 int
#define MAXSIZE 100
#define MAXDATA -99999999
using namespace std;
typedef struct HuffmanNode* HuffmanTree;
struct HuffmanNode
{
	ElementType1 weight;
	char c ;
	HuffmanTree Left;
	HuffmanTree Right;
};

typedef struct HeapStruct* Heap;
struct HeapStruct 
{
	ElementType Elements[MAXSIZE];
	int Size;
	int Capacity;
};

//creat heap
Heap CreatHeap(int MaxSize) {
	HuffmanTree M;
	M = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
	M->Left = NULL;
	M->Right = NULL;
	M->weight = MAXDATA;
	Heap H = (Heap)malloc(sizeof(struct HeapStruct));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Elements[0] = M;
	return H;
}

//check is full
bool IsFull(Heap H) {
	if (H->Capacity <= H->Size) {
		return true;
	}
	else {
		return false;
	}
}

//check is empty
bool IsEmpty(Heap H) {
	if (H->Size == 0) {
		return true;
	}
	else {
		return false;
	}
}

//insert
void Insert(Heap H, ElementType X) {
	if (IsFull(H)) {
		printf("the heap is full.\n");
		return;
	}
	
	int i = ++H->Size;
	//if X big than his father,X become father
	for (; (H->Elements[i / 2])->weight> X->weight; i /= 2)
	{
		H->Elements[i] = H->Elements[i / 2];
	}
	H->Elements[i] = X;
	return;
}

//delete
ElementType Delete(Heap H) {
	if (IsEmpty(H)) {
		printf("the heap is empty.\n");
		return NULL;
	}
	HuffmanTree MinItem = H->Elements[1];
	HuffmanTree temp = H->Elements[H->Size--];
	int parent, child;
	for (parent = 1; parent * 2 <= H->Size; parent = child) {
		child = parent * 2;
		//if his right son small than the left son
		if ((child != H->Size) && (H->Elements[child]->weight > H->Elements[child + 1]->weight)) {
			child++;
		}
		//the temp is the min item int this sub tree
		if (temp->weight <= H->Elements[child]->weight) {
			break;
		}
		//move the child to the parent location
		else {
			H->Elements[parent] = H->Elements[child];
		}
	}
	H->Elements[parent] = temp;
	return MinItem;
}

//creat huffmantree
HuffmanTree creat(Heap H) {
	HuffmanTree T;
	int end = H->Size;
	for (int i = 1; i < end; i++)
	{
		T = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
		T->Left = Delete(H);
		T->Right = Delete(H);
		T->weight = T->Left->weight + T->Right->weight;
		Insert(H, T);
	}
	T = Delete(H);
	return T;
}

//中序遍历
void InOrderTraversal(HuffmanTree T,string s) {
	//若是是空树就不遍历
	if (T) {
		InOrderTraversal(T->Left,s+"0");
		if (!T->Left&&!T->Right) {
			printf("%c :%s\n", T->c,s.c_str());
		}
		InOrderTraversal(T->Right,s+"1");
	}
}

int main() {
	Heap H = CreatHeap(MAXSIZE);
	int n;
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)
	{
		int temp;
		char c;
		scanf_s(" %c",&c,1);
		scanf_s("%d",&temp);
		HuffmanTree M;
		M = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
		M->c = c;
		M->Left = NULL;
		M->Right = NULL;
		M->weight = temp;
		Insert(H, M);
	}
	HuffmanTree huff = creat(H);
	InOrderTraversal(huff,"");
	return 0;
}
//运行结果
5
A 5
E 10
B 15
D 30
C 40
C :0
D :10
B :110
A :1110
E :1111

课后练习题(三个小题)

05-树7 堆中的路径 (25point(s))

将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。

输入格式:
每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及须要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。

输出格式:
对输入中给出的每一个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。

输入样例:

5 3
46 23 26 24 10
5 4 3

输出样例:

24 23 10
46 23 10
26 10

题解
就是简单模拟,构造一个最小堆后,对指定的下标位置不断除以2,直到根节点便可。

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define ElementType int
#define MAXDATA -1215752191
typedef struct HeapStruct* Heap;

struct HeapStruct
{
	ElementType* Elements;
	int Size;
	int Capacity;
};
//creat heap
Heap CreatHeap(int MaxSize) {
	Heap H = (Heap)malloc(sizeof(struct HeapStruct));
	H->Elements = malloc((MaxSize + 1) * sizeof(ElementType));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Elements[0] = MAXDATA;
	return H;
}
//check is full
bool IsFull(Heap H) {
	if (H->Capacity <= H->Size) {
		return true;
	}
	else {
		return false;
	}
}
//check is empty
bool IsEmpty(Heap H) {
	if (H->Size == 0) {
		return true;
	}
	else {
		return false;
	}
}
//insert
void Insert(Heap H, ElementType X) {
	if (IsFull(H)) {
		printf("the heap is full.\n");
		return;
	}
	int i = ++H->Size;
	//if X big than his father,X become father
	for (; H->Elements[i / 2] > X; i /= 2)
	{
		H->Elements[i] = H->Elements[i / 2];
	}
	H->Elements[i] = X;
}
//delete
ElementType Delete(Heap H) {
	if (IsEmpty(H)) {
		printf("the heap is empty.\n");
		return;
	}
	ElementType MaxItem = H->Elements[1];
	ElementType temp = H->Elements[H->Size--];
	int parent, child;
	for (parent = 1; parent * 2 <= H->Size; parent = child) {
		child = parent * 2;
		//if his right son small the the left son
		if ((child != H->Size) && (H->Elements[child] > H->Elements[child + 1])) {
			child++;
		}
		//the temp is the min item int this sub tree
		if (temp <= H->Elements[child]) {
			break;
		}
		//move the child to the parent location
		else {
			H->Elements[parent] = H->Elements[child];
		}
	}
	H->Elements[parent] = temp;
	return MaxItem;
}
void printL(Heap H,int n) {
	bool isF = true;
	for (int i = n; i >=1; i/=2)
	{
		if (isF) {
			printf("%d", H->Elements[i]);
			isF = false;
		}else{
			printf(" %d", H->Elements[i]);
		}
	}
	printf("\n");
}
int main() {
	int n, k;
	scanf("%d %d\n", &n, &k);
	Heap H = CreatHeap(n);
	for (int i = 0; i < n; i++)
	{
		int temp;
		scanf("%d", &temp);
		Insert(H, temp);
	}
	for (int i = 0; i < k; i++)
	{
		int p;
		scanf("%d", &p);
		printL(H, p);
	}
}

05-树8 File Transfer (25point(s))

We have a network of computers and a list of bi-directional connections. Each of these connections allows a file transfer from one computer to another. Is it possible to send a file from any computer on the network to any other?

Input Specification:
Each input file contains one test case. For each test case, the first line contains N (2≤N≤10​^4), the total number of computers in a network. Each computer in the network is then represented by a positive integer between 1 and N. Then in the following lines, the input is given in the format:

I c1 c2

where I stands for inputting a connection between c1 and c2; or

C c1 c2

where C stands for checking if it is possible to transfer files between c1 and c2; or

S

where S stands for stopping this case.

Output Specification:
For each C case, print in one line the word "yes" or "no" if it is possible or impossible to transfer files between c1 and c2, respectively. At the end of each case, print in one line "The network is connected." if there is a path between any pair of computers; or "There are k components." where k is the number of connected components in this network.

Sample Input 1:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
S

Sample Output 1:

no
no
yes
There are 2 components.

Sample Input 2:

5
C 3 2
I 3 2
C 1 5
I 4 5
I 2 4
C 3 5
I 1 3
C 1 5
S

Sample Output 2:

no
no
yes
yes
The network is connected.

题解:
利用并查集,由于给定了 N台电脑以及这N台电脑分别用1~N表示,固开一个大小为N+1的数组com[N+1],初始将全部电脑的值设为-1,在链接时,读入两台电脑的编号先找到他们的根,若是根不一样则将一台电脑的根指向另外一台电脑根(小的指向大的,在这以前还须要把他们共有的电脑累加,由于对于一台指向另外一台电脑存的必定是正数,鼓没有指向的电脑设为负数,他的绝对值表明了他的集合中包含几台电脑 )。

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int getroot(int com[],int k) {
	while (com[k] > 0) {
		k = com[k];
	}
	return k;
}
void magre(int com[],int root1,int root2) {
	//root1 has more computer
	if (com[root1] < com[root2]) {
		com[root1] += com[root2];
		com[root2] = root1;
	}
	else {
		com[root2] += com[root1];
		com[root1] = root2;
	}
	return;
}
int main() { 
	int N,c1,c2;
	char a;
	scanf("%d\n", &N);
	int com[10001];
	memset(com, -1, sizeof(com));
	while (scanf("%c",&a)!=EOF) {
		if (a == 'I') {
			scanf("%d %d\n", &c1, &c2);
			int root1 = getroot(com, c1);
			int root2 = getroot(com, c2);
			if (root1 != root2) {
				magre(com,root1, root2);
			}
		}
		else if (a == 'C') {
			scanf("%d %d\n", &c1, &c2);
			int root1 = getroot(com, c1);
			int root2 = getroot(com, c2);
			if (root1 != root2) {
				printf("no\n");
			}
			else {
				printf("yes\n");
			}
		}
		else {
			int count = 0;
			for (int i = 1; i <= N; i++)
			{
				if (com[i] <0) {
					count++;
				}
			}
			if (count > 1) {
				printf("There are %d components.\n", count);
			}
			else {
				printf("The network is connected.\n");
			}
			break;
		}
	}
	return 0;
}

05-树9 Huffman Codes (30point(s))

In 1953, David A. Huffman published his paper "A Method for the Construction of Minimum-Redundancy Codes", and hence printed his name in the history of computer science. As a professor who gives the final exam problem on Huffman codes, I am encountering a big problem: the Huffman codes are NOT unique. For example, given a string "aaaxuaxz", we can observe that the frequencies of the characters 'a', 'x', 'u' and 'z' are 4, 2, 1 and 1, respectively. We may either encode the symbols as {'a'=0, 'x'=10, 'u'=110, 'z'=111}, or in another way as {'a'=1, 'x'=01, 'u'=001, 'z'=000}, both compress the string into 14 bits. Another set of code can be given as {'a'=0, 'x'=11, 'u'=100, 'z'=101}, but {'a'=0, 'x'=01, 'u'=011, 'z'=001} is NOT correct since "aaaxuaxz" and "aazuaxax" can both be decoded from the code 00001011001001. The students are submitting all kinds of codes, and I need a computer program to help me determine which ones are correct and which ones are not.

Input Specification:
Each input file contains one test case. For each case, the first line gives an integer N (2≤N≤63), then followed by a line that contains all the N distinct characters and their frequencies in the following format:

c[1] f[1] c[2] f[2] ... c[N] f[N]

where c[i] is a character chosen from {'0' - '9', 'a' - 'z', 'A' - 'Z', '_'}, and f[i] is the frequency of c[i] and is an integer no more than 1000. The next line gives a positive integer M (≤1000), then followed by M student submissions. Each student submission consists of N lines, each in the format:

c[i] code[i]

where c[i] is the i-th character and code[i] is an non-empty string of no more than 63 '0's and '1's.

Output Specification:
For each test case, print in each line either "Yes" if the student's submission is correct, or "No" if not.

Note: The optimal solution is not necessarily generated by Huffman algorithm. Any prefix code with code length being optimal is considered correct.

Sample Input:

7
A 1 B 1 C 1 D 3 E 3 F 6 G 6
4
A 00000
B 00001
C 0001
D 001
E 01
F 10
G 11
A 01010
B 01011
C 0100
D 011
E 10
F 11
G 00
A 000
B 001
C 010
D 011
E 100
F 101
G 110
A 00000
B 00001
C 0001
D 001
E 00
F 10
G 11

Sample Output:

Yes
Yes
No
No

题解:
首先根据他所给出的字符出现频率,构建一颗哈弗曼树,计算它的wpl(最优储存空间大小),对于他提供的每一种编码,用string数组保存,读入时同时计算wpl。若是他所给出的编码wpl和咱们以前计算的不一样,说明此并不是最优编码。反之,开始验证他所给出的编码是否有前缀冲突,经过构建一棵哈夫曼树来检查。
代码:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string>
#include<iostream>
#define ElementType HuffmanTree
#define ElementType1 int
#define MAXSIZE 100
#define MAXDATA -99999999
using namespace std;

int WPL = 0;
typedef struct HuffmanNode* HuffmanTree;
struct HuffmanNode
{
	ElementType1 weight;
	char c;
	HuffmanTree Left;
	HuffmanTree Right;
};

typedef struct HeapStruct* Heap;
struct HeapStruct
{
	ElementType Elements[MAXSIZE];
	int Size;
	int Capacity;
};

//creat heap
Heap CreatHeap(int MaxSize) {
	HuffmanTree M;
	M = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
	M->Left = NULL;
	M->Right = NULL;
	M->weight = MAXDATA;
	Heap H = (Heap)malloc(sizeof(struct HeapStruct));
	H->Size = 0;
	H->Capacity = MaxSize;
	H->Elements[0] = M;
	return H;
}

//check is full
bool IsFull(Heap H) {
	if (H->Capacity <= H->Size) {
		return true;
	}
	else {
		return false;
	}
}

//check is empty
bool IsEmpty(Heap H) {
	if (H->Size == 0) {
		return true;
	}
	else {
		return false;
	}
}

//insert
void Insert(Heap H, ElementType X) {
	if (IsFull(H)) {
		printf("the heap is full.\n");
		return;
	}

	int i = ++H->Size;
	//if X big than his father,X become father
	for (; (H->Elements[i / 2])->weight > X->weight; i /= 2)
	{
		H->Elements[i] = H->Elements[i / 2];
	}
	H->Elements[i] = X;
	return;
}

//delete
ElementType Delete(Heap H) {
	if (IsEmpty(H)) {
		printf("the heap is empty.\n");
		return NULL;
	}
	HuffmanTree MinItem = H->Elements[1];
	HuffmanTree temp = H->Elements[H->Size--];
	int parent, child;
	for (parent = 1; parent * 2 <= H->Size; parent = child) {
		child = parent * 2;
		//if his right son small than the left son
		if ((child != H->Size) && (H->Elements[child]->weight > H->Elements[child + 1]->weight)) {
			child++;
		}
		//the temp is the min item int this sub tree
		if (temp->weight <= H->Elements[child]->weight) {
			break;
		}
		//move the child to the parent location
		else {
			H->Elements[parent] = H->Elements[child];
		}
	}
	H->Elements[parent] = temp;
	return MinItem;
}

//creat huffmantree
HuffmanTree creat(Heap H) {
	HuffmanTree T;
	int end = H->Size;
	for (int i = 1; i < end; i++)
	{
		T = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
		T->Left = Delete(H);
		T->Right = Delete(H);
		T->weight = T->Left->weight + T->Right->weight;
		Insert(H, T);
	}
	T = Delete(H);
	return T;
}

//中序遍历计算WPL
void InOrderTraversal(HuffmanTree T,int p) {
	//若是是空树就不遍历
	if (T) {
		InOrderTraversal(T->Left,p+1);
		if (!T->Left && !T->Right) {
			WPL += (T->weight * p);
		}
		InOrderTraversal(T->Right,p+1);
	}
}
HuffmanTree creathuffmannode() {
	HuffmanTree huff = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
	huff->Left = NULL;
	huff->Right = NULL;
	huff->weight = 0;
	return huff;
}
//检查编码是否有问题
bool check(HuffmanTree M,string s) {
	HuffmanTree temp = M;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] == '0') {
			if (temp->Left == NULL) {
				temp->Left = creathuffmannode();
				//已经到了叶节点,使其标记.
				if (i== s.length()-1) {
					temp->Left->weight = -1;
				}
			}
			else if(temp->Left->weight==-1){
				return false;
			}
			else {
				if (i == s.length() - 1) {
					return false;
				}
			}
			temp = temp->Left;
		}
		else if (s[i] == '1') {
			if (temp->Right == NULL) {
				temp->Right = creathuffmannode();
				//已经到了叶节点,使其标记.
				if (i == s.length() - 1) {
					temp->Right->weight = -1;
				}
			}
			else if (temp->Right->weight == -1) {
				return false;
			}
			else {
                if (i == s.length() - 1) {
					return false;
				}
			}
			temp = temp->Right;
		}
		else {
			return false;
		}
	}
	return true;
}
int main() {
	Heap H = CreatHeap(MAXSIZE);
	int n,t;
	int weight[100];
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		int temp;
		char c;
		scanf(" %c", &c);
		scanf("%d", &temp);
		weight[i] = temp;
		HuffmanTree M;
		M = (HuffmanTree)malloc(sizeof(struct HuffmanNode));
		M->c = c;
		M->Left = NULL;
		M->Right = NULL;
		M->weight = temp;
		Insert(H, M);
	}
	HuffmanTree huff = creat(H);
	InOrderTraversal(huff, 0);
	scanf("%d", &t);
	for (int i = 0; i < t; i++)
	{
		int sWPL = 0;
		char c;
		string s[100];
		for (int i = 0; i < n; i++)
		{
			cin >> c >> s[i];
			sWPL += s[i].length()*weight[i];
		}
		if (sWPL!=WPL) {
			printf("No\n");
		}
		else {
			bool isRight = true;
			HuffmanTree huff = creathuffmannode();
			for (int i = 0; i < n; i++)
			{
				if (!check(huff,s[i])) {
					isRight = false;
					break;
				}
			}
			if (isRight) {
				printf("Yes\n");
			}
			else {
				printf("No\n");
			}
		}
	}
	return 0;
}
相关文章
相关标签/搜索