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

上次实现二叉搜索树与平衡二叉树,这次实现树结构的另一个重要应用:堆。

什么是堆

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

如果用数组实现的话,插入时从尾部插入,寻找优先级最高的元素,以及删除该元素后移动需要的操作量都是巨大的,均需要\(O(n)\),很明显不是一个好方法。

如果直接在插入时保证整个数组有序,那么在删除时只需要删除最后一个节点,虽然插入时虽然可用二分查找降低时间复杂度,但移动人需要很大的时间复杂度。

如果用链表做的话,插入从尾部插入只需要\(O(1)\)的时间,查找时需要的时间复杂度同数组一样为\(O(n)\)

如果采用有序链表,发现与从尾部插入毫无差异,只是查找需要的时间复杂度,从删除时转移到了插入时。

这些方法都会有令人不满意的地方,总是无法避免插入或者删除需要\(O(n)\)的时间。这里实现一个比上面的更好的方法,用完全二叉树构成一个堆,(堆只需要满足所有结点的值均大于它的左右节点,这样的堆我们又叫它大顶堆,相反的如果小于,它就是小顶堆)。容易发现,从根节点向下画任何一条线,都是有序的,因为任何一个节点的父亲总是比他大,选取下标为1的位置为根结点,树中所有结点的左右儿子为他的二倍和二倍加一,也就是除根结点外,每个节点的下边除以2就是它的父节点,很容易的我们发现,这样的数据结构在插入和删除操作时,最坏的时间复杂度都为\(O(logN)\)

堆的结构表示

以下代码为大顶堆的实现

#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;
}

堆的删除

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

//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)。

哈夫曼树的构造

知道了哈夫曼树的性质那该如何写出一个哈夫曼树呢?上面已经说过,出现概率最小的需要越晚判断,很自然的,首先我们从包含所有节点的集合中找出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

集合的表示

并查集

并查集是一种树型的数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题。有一个联合-查找算法(union-find algorithm)定义了两个用于此数据结构的操作。
具体实现代码可以在下面的习题05-树8 File Transfer找到。

课后练习题(三个小题)

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;
}
posted @ 2020-11-09 16:33  W&B  阅读(163)  评论(0编辑  收藏  举报