第七章 神奇的树

第1节 开启"树"之旅
第2节 二叉树
第3节 堆--神奇的优先队列
p194 建堆及堆排序

 1 #include <stdio.h>
 2 int h[ 101];//用来存放堆的数组
 3 int n;//用来存储堆中元素的个数,也就是堆的大小
 4
 5
 6 //交换函数,用来交换堆中的两个元素的值
 7 void swap(int x,int y)
 8 {
 9     int t;
10     t=h[ x];
11     h[ x]=h[ y];
12     h[ y]=t;
13 }
14
15
16 //向下调整函数
17 void siftdown(int i) //传入一个需要向下调整的结点编号i,这里传入1,即从堆的顶点开始向下调整
18 {
19     int t,flag=0;//flag用来标记是否需要继续向下调整
20     //当i结点有儿子的时候(其实是至少有左儿子的情况下)并且有需要继续调整的时候循环窒执行
21     while( i*2<=n && flag==0 )
22     {
23         //首先判断他和他左儿子的关系,并用t记录值较小的结点编号
24         if( h[ i] > h[ i*2] )
25             t=i*2;
26         else
27             t=i;
28         //如果他有右儿子的情况下,再对右儿子进行讨论
29         if(i*2+1 <= n)
30         {
31             //如果右儿子的值更小,更新较小的结点编号
32             if(h[ t] > h[ i*2+1])
33                 t=i*2+1;
34         }
35         //如果发现最小的结点编号不是自己,说明子结点中有比父结点更小的
36         if(t!=i)
37         {
38             swap(t,i);//交换它们,注意swap函数需要自己来写
39             i=t;//更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整
40         }
41         else
42             flag=1;//则否说明当前的父结点已经比两个子结点都要小了,不需要在进行调整了
43     }
44 }
45
46
47 //建立堆的函数
48 void creat()
49 {
50     int i;
51     //从最后一个非叶结点到第1个结点依次进行向上调整
52     for(i=n/2;i>=1;i--)
53     {
54         siftdown(i);
55     }
56 }
57
58
59 //删除最大的元素
60 int deletemax()
61 {
62     int t;
63     t=h[ 1];//用一个临时变量记录堆顶点的值
64     h[ 1]=h[ n];//将堆得最后一个点赋值到堆顶
65     n--;//堆的元素减少1
66     siftdown(1);//向下调整
67     return t;//返回之前记录的堆得顶点的最大值
68 }
69
70
71 int main()
72 {
73     int i,num;
74     //读入数的个数
75     scanf("%d",&num);
76
77
78     for(i=1;i<=num;i++)
79         scanf("%d",&h[ i]);
80     n=num;
81
82     //建堆
83     creat();
84
85     //删除顶部元素,连续删除n次,其实夜就是从大到小把数输出来
86     for(i=1;i<=num;i++)
87         printf("%d ",deletemax());
88
89     getchar();
90     getchar();
91     return 0;
92 }
93
94 /*
95
96 14
97 99 5 36 7 22 17 46 12 2 19 25 28 1 92
98
99 */

p197 堆排序代码

  1 #include <stdio.h>
  2 int h[ 101];//用来存放堆的数组
  3 int n;//用来存储堆中元素的个数,也就是堆的大小
  4
  5
  6 //交换函数,用来交换堆中的两个元素的值
  7 void swap(int x,int y)
  8 {
  9     int t;
 10     t=h[ x];
 11     h[ x]=h[ y];
 12     h[ y]=t;
 13 }
 14
 15
 16 //向下调整函数
 17 void siftdown(int i) //传入一个需要向下调整的结点编号i,这里传入1,即从堆的顶点开始向下调整
 18 {
 19     int t,flag=0;//flag用来标记是否需要继续向下调整
 20     //当i结点有儿子的时候(其实是至少有左儿子的情况下)并且有需要继续调整的时候循环窒执行
 21     while( i*2<=n && flag==0 )
 22     {
 23         //首先判断他和他左儿子的关系,并用t记录值较大的结点编号
 24         if( h[ i] < h[ i*2] )
 25             t=i*2;
 26         else
 27             t=i;
 28         //如果他有右儿子的情况下,再对右儿子进行讨论
 29         if(i*2+1 <= n)
 30         {
 31             //如果右儿子的值更大,更新较小的结点编号
 32             if(h[ t] < h[ i*2+1])
 33                 t=i*2+1;
 34         }
 35         //如果发现最大的结点编号不是自己,说明子结点中有比父结点更大的
 36         if(t!=i)
 37         {
 38             swap(t,i);//交换它们,注意swap函数需要自己来写
 39             i=t;//更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整
 40         }
 41         else
 42             flag=1;//则否说明当前的父结点已经比两个子结点都要大了,不需要在进行调整了
 43     }
 44 }
 45
 46
 47 //建立堆的函数
 48 void creat()
 49 {
 50     int i;
 51     //从最后一个非叶结点到第1个结点依次进行向上调整
 52     for(i=n/2;i>=1;i--)
 53     {
 54         siftdown(i);
 55     }
 56 }
 57
 58
 59 //堆排序
 60 void heapsort()
 61 {
 62     while(n>1)
 63     {
 64         swap(1,n);
 65         n--;
 66         siftdown(1);
 67     }
 68 }
 69
 70
 71 int main()
 72 {
 73     int i,num;
 74     //读入n个数
 75     scanf("%d",&num);
 76
 77
 78     for(i=1;i<=num;i++)
 79         scanf("%d",&h[i]);
 80     n=num;
 81
 82
 83     //建堆
 84     creat();
 85
 86
 87     //堆排序
 88     heapsort();
 89
 90
 91     //输出
 92     for(i=1;i<=num;i++)
 93         printf("%d ",h[i]);
 94
 95
 96     getchar();
 97     getchar();
 98     return 0;
 99 }
100
101 /*
102
103 14
104 99 5 36 7 22 17 46 12 2 19 25 28 1 92
105
106 */

第4节 擒贼先擒王--并查集
p208 解密犯罪团伙的问题的代码

 1 #include <stdio.h>
 2 int f[1000]={0},n,m,k,sum=0;
 3
 4 void init()
 5 {
 6   int i;
 7   for(i=1;i<=n;i++)
 8     f[i]=i;
 9 }
10
11 int getf(int v)
12 {
13   if(f[v]==v)
14     return v;
15   else
16   {
17     f[v]=getf(f[v]);
18     return f[v];
19   }
20 }
21
22 void merge(int v,int u)
23 {
24   int t1,t2;
25   t1=getf(v);
26   t2=getf(u);
27   if(t1!=t2)
28   {
29     f[t2]=t1;
30   }
31 }
32
33 int main()
34 {
35   int i,x,y;
36   scanf("%d %d",&n,&m);
37
38   init();
39   for(i=1;i<=m;i++)
40   {
41     scanf("%d %d",&x,&y);
42     merge(x,y);
43   }
44
45   for(i=1;i<=n;i++)
46   {
47     if(f[i]==i)
48       sum++;
49   }
50   printf("%d\n",sum);
51
52   getchar(); getchar();
53   return 0;
54 }
55
56 /*
57
58 10 9
59 1 2
60 3 4
61 5 2
62 4 6
63 2 6
64 8 7
65 9 7
66 1 6
67 2 4
68
69 */



oj
以后整理。。。

top

时间: 2024-10-18 22:01:11

第七章 神奇的树的相关文章

《啊哈!算法》第7章 神奇的树

第3节 堆排序 把n个元素建立一个堆,首先将这n个结点以自顶向下.从左到右的方式从1到n编码,这样可以把n个结点转换成一颗完全二叉树 紧接着从最后一个非叶子结点(结点编号为n/2)开始到根节点(结点编号为1),逐个扫描所有结点,根据需要将当前结点向下调整,直到以当前结点为根结点的子树符合堆的特性. #include <iostream> #include <vector> #include <algorithm> using namespace std; //向下调整函

JavaScript DOM编程艺术-学习笔记(第七章)

第七章: 1.dom方法创建并且插入标签:(这种方法并没有改变文档的物理内容,而是在改变dom树) ①创建元素节点:createElement(); ②内部前插入:appendChild() ③创建文本节点:createTextNode(); ④设置属性节点:setAttribute(); ⑤外部前插入:父元素.insertBefore(插入的元素,目标元素);                  插入的元素被插入到,目标元素的前面. ⑥没有inserAfter()函数. 2.小知识点:①appe

第七章、epub文件处理 -- 解析 .xhtml文件 (一)

第七章.epub文件处理 -- 解析 .xhtml文件 (一) 本章将介绍代码如何利用ZLTextPlainModel类来分别处理.xhtml文件中的文本信息与标签信息. 本章涉及的核心类是ZLTextPlainModel类.ZLTextWritablePlainModel类.CachedCharStorage类.XHTMLTagAction接口实现类 .xhtml文件中包含着两种信息:文本信息与标签信息.我们需要先正确解析出标签信息代表的结构,才能正确得将文本信息显示在屏幕上. 举个例子:(这

阅读《大型网站技术架构:核心原理与案例分析》第五、六、七章

题目:阅读<大型网站技术架构:核心原理与案例分析>第五.六.七章,结合<XXX需求征集系统>,分析如何增加相应的功能,提高系统的可用性和易用性,撰写一篇1500字左右的博客阐述你的观点 在这一节课上,我们学习了系统质量属性其中的可用性和易用性.那么质量属性是什么呢,质量属性是高于对系统功能(即对系统能力.服务和行为)的基本的要求的.系统质量属性讲重点放在了可用性.可修改性.性能.安全性.可测试性和易用性.从设计师方面,系统质量属性一般存在三个问题:(1)为属性提供的定义并不是可操作

【转】第七章、Linux 文件与目录管理

原文网址:http://vbird.dic.ksu.edu.tw/linux_basic/0220filemanager.php 第七章.Linux 文件与目录管理 最近升级日期:2009/08/26 在第六章我们认识了Linux系统下的文件权限概念以及目录的配置说明. 在这个章节当中,我们就直接来进一步的操作与管理文件与目录吧!包括在不同的目录间变换. 创建与删除目录.创建与删除文件,还有寻找文件.查阅文件内容等等, 都会在这个章节作个简单的介绍啊! 1. 目录与路径 1.1 相对路径与绝对路

第七章解决二叉树的编程问题

第七章      解决二叉树的编程问题 二叉树是n(≥0)个有限元素的集合,该集合或者为空,或者由一个称为根的元素及两个不相交的,被称为左子树和右子树的二叉树组成.当集合为空时,称该二叉树为空二叉树,在二叉树中一个元素也称为一个结点. 二叉树是有序的,即将其左右子树颠倒,就成为另一个不同的二叉树. 结点的度,结点所拥有的子树的个数 叶结点,度为0的结点,也称为终端结点 分支节点,度不为0的结点,也称为非终端结点 孩子.兄弟.双亲结点,树中一个结点的子树的根节点称为这个结点的孩子.这个结点称为孩子

《Programming in Go》第七章并发编程译文

中文译名 Go 编程 外文原文名 Programming in Go 外文原文版出处 the United States on recycled paper at RR Donnelley in Crawfordsville, Indiana. 译 文: 第七章 并发编程 7.1主要概念 7.2例子 7.2.1:过滤器 7.2.2:并发查找 7.2.3:线程安全表 7.2.4:Apache 报告 7.2.5:找重复 并发编程能够让开发者实现并行算法,以及利用多处理器和多核写程序.但是在大多主流变

第七章 本源时空(补充)

                第七章        本源时空(补充) ?      第七章是匆匆结束的,有点文不对题.什么是本源时空,没有详细的论述.2个月来.我一直想做个小结,无奈心不在焉,忙于正业的玩游戏.看小说.其实,真正的原因.后面或许.会说一下吧.     我敢确定相对论.量子论等垃圾理论,100%是错误的,都将成为历史.按照本人30多年的实战经验总结,我的理论95%以上是对的:或许在小节上.不经意的地方有错误吧.嗯.注明一下:我不是"春哥",不需要"信我者永生&

软件构造 第七章第四节 调试

第七章第四节 调试 [bug的常见类型] 数学bug:例如 零除法,算术溢出 逻辑bug:例如 无线循环和无限递归 源头bug:例如 使用了为被定义的变量.资源泄漏,其中有限的系统资源如内存或文件句柄通过重复分配耗尽而不释放.缓冲区溢出,其中程序试图将数据存储在分配存储的末尾. 团队工程bug:例如 评论过时或者评论错误.文件与实际产品的区别 ## 调试的基本过程 Debug是测试的后续步骤:测试发现问题,debug消除问题:当防御式编程和测试都无法挡住bug时,我们就必须进行debug了: D

2017-2018 20172309 《程序设计与数据结构(下)》第七章学习总结

2017-2018 20172309 <程序设计与数据结构(下)>第七章学习总结 一.教材学习内容总结 1.1关于二叉查找树的一些概念 二叉查找树具有附加属性,其左孩子小于父节点.而父节点又小余或者等于右结点. 因此二叉查找树的最右侧会存放最大元素.而其最左侧会存放最小元素. 二叉查找树是二叉树的扩展,它绝大数方法都会用到递归,二叉查找树的平均查找深度为O(log2N). 1.2实现二叉查找树 添加元素(addElement操作) 插入方法首先在插入的时候判断被插入元素的类型是不是Compar