文章目录
〇、前言
这两周开始跟着【MOOC-浙江大学-陈越、何钦铭-数据结构】进行数据结构与算法的学习,特此记录复习一下,虽然记不住,但是一直记一直记一直记,成为复读机就好了。
一、堆
优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序。
二、堆的基本操作
- MaxHeap Create( int MaxSize ):创建一个空的最大堆。
- Boolean IsFull( MaxHeap H ):判断最大堆H是否已满。
- Insert( MaxHeap H, ElementType item ):将元素item插入最大堆H。
- Boolean IsEmpty( MaxHeap H ):判断最大堆H是否为空。
- ElementType DeleteMax( MaxHeap H ):返回H中最大元素(高优先级)。
三、哈夫曼树
四、集合及运算
- 集合运算:交、并、补、差,判定一个元素是否属于某一集合
- 并查集:集合并、查某元素属于什么集合
- 并查集问题中集合存储如何实现?
- 可以用树结构表示集合,树的每个结点代表一个集合元素
五、堆中的路径
六、课后题
1、05-树7 堆中的路径 (25分)
输入样例:
5 3
46 23 26 24 10
5 4 3
输出样例:
24 23 10
46 23 10
26 10
#include <stdio.h>
#define MAXN 1001
#define MINH -10001
int H[MAXN], size;
void Create ()
{
size = 0;
H[0] = MINH;
/*设置“岗哨”*/
}
void Insert ( int X )
{
/* 将X插入H。这里省略检查堆是否已满的代码 */
int i;
for (i=++size; H[i/2] > X; i/=2)
H[i] = H[i/2];
H[i] = X;
}
int main()
{
int n, m, x, i, j;
scanf("%d %d", &n, &m);
Create(); /* 堆初始化 */
for (i=0; i<n; i++) { /*以逐个插入方式建堆 */
scanf("%d", &x);
Insert(x);
}
for (i=0; i<m; i++) {
scanf("%d", &j);
printf("%d", H[j]);
while (j>1) { /*沿根方向输出各结点*/
j /= 2;
printf(" %d", H[j]);
}
printf("
");
}
return 0;
}
2、05-树8 File Transfer (25分)
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.
#include <stdio.h>
#define MaxSize 10001
typedef int ElementType; /*默认元素可以用非负整数表示*/
typedef int SetName; /*默认用根结点的下标作为集合名称*/
typedef ElementType SetType[MaxSize];
SetName Find( SetType S, ElementType X )
{
/* 默认集合元素全部初始化为-1 */
for ( ; S[X]>=0; X=S[X] ) ;
return X;
}
void Union( SetType S, SetName Root1, SetName Root2 )
{
if ( S[Root2]<S[Root1] ){
S[Root2] += S[Root1];
S[Root1] = Root2;
}
else {
S[Root1] += S[Root2];
S[Root2] = Root1;
}
}
void Input_connection( SetType S )
{
ElementType u, v;
SetName Root1, Root2;
scanf("%d %d
", &u, &v);
Root1 = Find(S, u-1);
Root2 = Find(S, v-1);
if ( Root1 != Root2 )
Union( S, Root1, Root2 );
}
void Check_connection( SetType S )
{
ElementType u, v;
SetName Root1, Root2;
scanf("%d %d
", &u, &v);
Root1 = Find(S, u-1);
Root2 = Find(S, v-1);
if ( Root1 == Root2 )
printf("yes
");
else printf("no
");
}
void Check_network( SetType S, int n )
{
int i, counter = 0;
for (i=0; i<n; i++) {
if ( S[i] < 0 ) counter++;
}
if ( counter == 1 )
printf("The network is connected.
");
else
printf("There are %d components.
", counter);
}
Initialization( SetType S, int n ){
int i;
for(i = 0; i < n; i++) S[i] = -1;
}
int main()
{
SetType S;
int n;
char in;
scanf("%d
", &n);
Initialization( S, n );
do {
scanf("%c", &in);
switch (in) {
case 'I': Input_connection( S ); break;
case 'C': Check_connection( S ); break;
case 'S': Check_network( S, n ); break;
}
} while ( in != 'S');
return 0;
}
3、05-树9 Huffman Codes (30分)
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Maxn 64
int N, w[Maxn];
char ch[Maxn];
int codelen, cnt1, cnt2;
typedef struct TreeNode* Tree;
struct TreeNode {
int Weight;
Tree Left, Right;
};
typedef struct HeapNode* Heap;
struct HeapNode {
struct TreeNode Data[Maxn];
int Size;
};
Tree CreatTree() {
Tree T;
T = (Tree)malloc(sizeof(struct TreeNode));
T->Left = T->Right = NULL;
T->Weight = 0;
return T;
}
Heap CreatHeap() {
Heap H;
H = (Heap)malloc(sizeof(struct HeapNode));
H->Size = 0;
H->Data[0].Weight = -1;
return H;
}
void Insert(Heap H, struct TreeNode T) {
int i = ++H->Size;
for( ; T.Weight < H->Data[i/2].Weight; i /= 2)
H->Data[i] = H->Data[i/2];
H->Data[i] = T;
}
Tree Delete(Heap H) {
int parent, child;
struct TreeNode Temp = H->Data[H->Size--];
Tree T = CreatTree();
*T = H->Data[1];
for(parent = 1; 2*parent <= H->Size; parent = child) {
child = 2 * parent;
if(child != H->Size && H->Data[child].Weight > H->Data[child+1].Weight) child++;
if(Temp.Weight < H->Data[child].Weight) break;
H->Data[parent] = H->Data[child];
}
H->Data[parent] = Temp;
return T;
}
Tree Huffman(Heap H) {
Tree T = CreatTree(); //分配空间
while(H->Size != 1) {
T->Left = Delete(H);
T->Right = Delete(H);
T->Weight = T->Left->Weight + T->Right->Weight;
Insert(H, *T);
}
T = Delete(H);
return T;
}
int WPL(Tree T, int Depth) {
if(!T->Left && !T->Right) { return Depth*T->Weight; }
else return WPL(T->Left, Depth+1) + WPL(T->Right, Depth+1);
}
void JudgeTree(Tree T) {
if(T) {
if(T->Left && T->Right) cnt2++;
else if(!T->Left && !T->Right) cnt1++;
else cnt1 = 0;
JudgeTree(T->Left);
JudgeTree(T->Right);
}
}
int Judge() {
int i, j, wgh, flag = 1;
char s1[Maxn], s2[Maxn];
Tree T = CreatTree(), pt = NULL;
for(i = 0; i < N; i++) {
scanf("%s%s", s1, s2);
if(strlen(s2) > N) return 0;
for(j = 0; s1[0] != ch[j]; j++); wgh = w[j];
pt = T;//每次建树前先将指针移动到根节点上;
for(j = 0; s2[j]; j++) {
if(s2[j] == '0') {
if(!pt->Left) pt->Left = CreatTree();
pt = pt->Left;
}
if(s2[j] == '1') {
if(!pt->Right) pt->Right = CreatTree();
pt = pt->Right;
}
if(pt->Weight) flag = 0;
if(!s2[j+1]) {
if(pt->Left || pt->Right) flag = 0;//判断是否为前缀
pt->Weight = wgh;
}
}
}
if(!flag) return 0;
cnt1 = cnt2 = 0;
JudgeTree(T);//判断是否不存在度数1的节点
if(cnt1 != cnt2 + 1) return 0;
if(codelen == WPL(T, 0)) return 1;
else return 0;
}
int main() {
int i, n;
Heap H;
Tree T;
H = CreatHeap();
T = CreatTree();
scanf("%d", &N);
for(i = 0; i < N; i++) {
getchar();
scanf("%c %d", &ch[i], &w[i]);
H->Data[H->Size].Left = H->Data[H->Size].Right = NULL;
T->Weight = w[i];
Insert(H, *T);
}
T = Huffman(H); //PreTravel(T);
codelen = WPL(T, 0);
scanf("%d", &n);
while(n--) {
if(Judge()) printf("Yes
");
else printf("No
");
}
return 0;
}
总结
简单总结下这周的学习内容,我哭了,笔断了,电脑死机了,
如果想要更多的资源,欢迎关注 @我是管小亮,文字强迫症MAX~
回复【数据结构】即可获取我为你准备的大礼!!!
想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~