zoukankan      html  css  js  c++  java
  • 【2020-MOOC-浙江大学-陈越、何钦铭-数据结构】树和堆(第五周的笔记和编程作业)

    〇、前言

    这两周开始跟着【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~

    回复【数据结构】即可获取我为你准备的大礼!!!

    想看更多文(段)章(子),欢迎关注微信公众号「程序员管小亮」~

  • 相关阅读:
    召开演示会议和总结会议
    召开每天的站立会议
    禅道管理中的项目管理--组织进行任务分解
    linux sort,uniq,cut,wc命令详解
    json2.js的用途(拯救IE)
    memcache的内存回收机制
    memcache内存分配机制
    Linux之Sed命令详解(总结一些实用例子)
    CentOS 设置网络(修改IP&修改网关&修改DNS)--update.14.08.15
    php中文字符串翻转
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13302610.html
Copyright © 2011-2022 走看看