【项目3 - 体验复杂度】

在数据结构与算法中,对于算法的选择,要考虑到时间复杂度的重要性,在小规模的计算中,或许不同时间复杂度的程序所用时间并无多少影响,但在实际应用中,大数据时代,我们会明白复杂度不同对于算法的差异,下面将用实际例子体验复杂度。

排序是计算机科学中的一个基本问题,产生了很多种适合不同情况下适用的算法,也一直作为算法研究的热点。本项目提供两种排序算法,复杂度为O(n2)的选择排序selectsort,和复杂度为O(nlogn)的快速排序quicksort,在main函数中加入了对运行时间的统计。

我们将以近十万条数据作为输入测试体验。

选择排序的源程序  (复杂度是O(n2))

//*Copyright  (c)2017,烟台大学计算机与控制工程学院*
//*All rights reservrd.*
//*文件名称 :test.cpp*
//*作者:田长航*
//*完成时间:2017年9月7日*
//*版本号:v1.0*
//*问题描述:体验复杂度为O(n^2)的函数的运算时间*
//*输入描述:文本文档中的近万条数据*
//*程序输出:输出排序所用时间*  
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAXNUM 100000
void selectsort(int a[], int n)
{int i, j, k, tmp;for(i = 0; i < n-1; i++){k = i;for(j = i+1; j < n; j++){if(a[j] < a[k])k = j;}if(k != j){tmp = a[i];a[i] = a[k];a[k] = tmp;}}
}int main()
{int x[MAXNUM];int n = 0;double t1,t2;FILE *fp;fp = fopen("numbers.txt", "r");if(fp==NULL){printf("打开文件错!请下载文件,并将之复制到与源程序文件同一文件夹下。\n");exit(1);}while(fscanf(fp, "%d", &x[n])!=EOF)n++;printf("数据量:%d, 开始排序....", n);t1=time(0);selectsort(x, n);t2=time(0);printf("用时 %d 秒!", (int)(t2-t1));fclose(fp);return 0;
}

快速排序源代码 ( 复杂度为 O(nlogn))

//*Copyright  (c)2017,烟台大学计算机与控制工程学院*
//*All rights reservrd.*
//*文件名称 :test1.cpp*
//*作者:田长航*
//*完成时间:2017年9月7日*
//*版本号:v1.0*
//*问题描述:体验复杂度为O(nlogn)的函数的运算时间*
//*输入描述:文本文档中的近万条数据*
//*程序输出:输出排序所用时间*   
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define MAXNUM 100000
void quicksort(int data[],int first,int last)
{int i, j, t, base;if (first>last)return;base=data[first]; i=first;j=last;while(i!=j) {while(data[j]>=base && i<j) j--;while(data[i]<=base && i<j) i++;/*交换两个数*/if(i<j){t=data[i];data[i]=data[j];data[j]=t;}}data[first]=data[i]; data[i]=base; quicksort(data,first,i-1);quicksort(data,i+1,last);
}int main()
{int x[MAXNUM];int n = 0;double t1,t2;FILE *fp;fp = fopen("numbers.txt", "r");if(fp==NULL){printf("打开文件错!请下载文件,并将之复制到与源程序文件同一文件夹下。\n");exit(1);}    while(fscanf(fp, "%d", &x[n])!=EOF)n++;printf("数据量:%d, 开始排序....", n);t1=time(0);quicksort(x, 0, n-1);t2=time(0);printf("用时 %d 秒!", (int)(t2-t1));fclose(fp);return 0;
}

第一种排序的运行结果如下:

用时达到12秒。

第二种排序方法运行结果如下:

同样的数据,第二种排序方法竟然在瞬间完成。

这样的结果让我们切实的体验到了复杂度在实际应用中的差异。

(2)汉诺塔 
  有一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。 
  可以算法出,当盘子数为n个时,需要移动的次数是f(n)=2n−1。n=64时,假如每秒钟移一次,共需要18446744073709551615秒。一个平年365天有31536000秒,闰年366天有31622400秒,平均每年31556952秒,移完这些金片需要5845.54亿年以上,而地球存在至今不过45亿年,太阳系的预期寿命据说也就是数百亿年。真的过了5845.54亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。据此,2n从数量级上看大得不得了。

用递归算法求解汉诺塔问题,其复杂度可以求得为O(2n),是指数级的算法。体验盘子数discCount为4、8、16、20、24时在时间耗费上的差异。

源代码如下:

//*Copyright  (c)2017,烟台大学计算机与控制工程学院*
//*All rights reservrd.*
//*文件名称 :test2.cpp*
//*作者:田长航*
//*完成时间:2017年9月7日*
//*版本号:v1.0*
//*问题描述:体验复杂度为O(2^n)的函数的运算时间*
//*输入描述:要移动的盘子数量*
//*程序输出:输出完成移动需要的次数*
#include <stdio.h>
#define discCount 4
long move(int, char, char,char);
int main()
{long count;count=move(discCount,'A','B','C');printf("%d个盘子需要移动%ld次\n", discCount, count);return 0;
}long move(int n, char A, char B,char C)
{long c1,c2;if(n==1)return 1;else{c1=move(n-1,A,C,B);c2=move(n-1,B,A,C);return c1+c2+1;}
}

当discount为4时,运行结果如下:

当discount为8时,运行结果如下:

似乎运行时间并没有多大差异

当discount为16时,运行结果如下:

当discount为20时,运行结果如下:

当discount为24时,运行结果如下:

这些次数,望而生畏,连程序计算都稍微卡顿了一下

当discount为26时

运行已经明显有将近2秒的延迟了

当discount为30时

程序整整运行了14秒之久,可见复杂度在实际应用中的差异。

数据结构上机实践第二周项目3——体验复杂度相关推荐

  1. 数据结构上机实践第二周项目2- 程序的多文件组织

    [项目2 - 程序的多文件组织] 学习数据结构,目标就是要编制出有相当规模的程序的.将所有的代码放在一个文件中的做法,不能适用现阶段的需求了. 通过这个项目,确认有能力用多文件组织程序.方便以后各章, ...

  2. 数据结构上机实践第二周项目1

    [项目1 - C/C++语言中函数参数传递的三种方式] C语言提供了两种函数参数传递的方式:传值和传地址.在C++中,又拓展了引用方式.通过本项目,确认自己已经掌握了这三种方式的原理,为后续学习做好准 ...

  3. 数据结构上机实践第九周项目3 - 利用二叉树遍历思想解决问题

    利用二叉树遍历思想解决问题 学以致用,知行合一,学了知识就要会运用,否则跟背课文没什么区别,上次实践,做了二叉树递归遍历的算法实现,本次实践,将利用遍历思想解决问题,将遍历思想真正的运用到实际问题需求 ...

  4. 数据结构上机实践第九周项目1 - 二叉树算法库

    二叉树算法库 学了新的内容就应该有新的应用,本次实践将进行二叉树算法库的建立,来适应更多工程的需求,丰富算法库. 注:在main函数中,创建的用于测试的二叉树如下 首先本次建立算法库实践将会运用到多文 ...

  5. 数据结构上机实践第九周项目2 - 二叉树遍历的递归算法

    二叉树遍历的递归算法 递归问题总会成为我们的难点,代码量少,思维量确是很大,难是在所难免的,所以,在思维理解的同时结合实现代码理解,这样就很有可能让我们打开思路,理解的更深,本次实践将在二叉树算法的基 ...

  6. 数据结构上机实践第四周项目7 - 多项式求和

    项目6 - 多项式求和 用单链表存储一元多项式,并实现两个多项式的加法. 提示:  1.存储多项式的数据结构  多项式的通式是pn(x)=anxn+an−1xn−1+...+a1x+a0.n次多项式共 ...

  7. 数据结构上机实践第四周项目6- 循环双链表应用

    数据结构实践--循环双链表应用 线性表都是单向的?链表都是单向的? 本次实践将利用循环双链表进行实际应用,感受这种数据结构的好处 要求如下: 设非空线性表ha和hb都用带头节点的循环双链表表示.设计一 ...

  8. 数据结构上机实践第四周项目5 - 猴子选大王

    数据结构实践--猴子选大王 首先呢,小普及一下 读者:难道你当我不知道 读者想对小编说: 进入正题,项目要求如下: 一群猴子,编号是1,2,3 -m,这群猴子(m个)按照1-m的顺序围坐一圈.从第1只 ...

  9. 数据结构上机实践第四周项目4 - 建设双链表算法库

    数据结构之自建算法库--双链表 各种算法结构都有各自的用途,在实际中我们会碰到各种工程,单链表有时无法或者不能很好的满足我们的需求,这个时候,双链表不失为一种好的数据结构.本次实践将建立双链表算法库, ...

最新文章

  1. 项目四-用循环求(2)
  2. ObservableCollection和List的区别总结
  3. jquery.zSlide.js-基于CSS3/HTML5演示文档jQuery插件
  4. 毛坯房装修需要哪些材料
  5. CodeForces - 528D Fuzzy Search(多项式匹配字符串)
  6. mods文件夹怎么创建_TCL电视怎么安装蜜蜂视频通用教程
  7. RHEL6上课笔记之background_process_command
  8. android 应用升级sdk版本号,Bugly Android 应用升级 SDK 常见问题
  9. 美团知识图谱问答技术实践与探索
  10. SSH2-Spring Framework2 struts2 hibernate
  11. mobile 部署和/或注册失败 0x8973190e 解决办法
  12. 数据库分区分片(Shards)技术概览
  13. 0ctf – mobile – boomshakalaka writeup
  14. 贼有趣:朱茵变杨幂,人工智能换脸让明星不再担心自己演技?
  15. UE4 骨骼动画 蓝图中调节某一根骨骼
  16. p2p银行充值功能模块 支付宝调用
  17. 【CSS 定位之 display 属性】
  18. 计算机教室八字格言,浅谈如何深化多媒体电脑教学|教学理念八字格言
  19. 大数据分析(一)——虚拟机环境配置
  20. 正则表达式 去掉字符串后面所有的内容

热门文章

  1. python 一个简单的天气预报程序
  2. python基础系列教程——Python3.x标准模块库目录
  3. matlab2c使用c++实现matlab函数系列教程-sortrows函数
  4. c#字符编码,System.Text.Encoding类,字符编码大全:如Unicode编码、GB18030、UTF-8,UTF-7,GB2312,ASCII,UTF32,Big5
  5. 汇编语言上机考试三星题——加密的key和明文字符串
  6. c++树及树与二叉树的转换
  7. python学习笔记之函数(方法)(四)
  8. 初探Bootstrap
  9. struts2.3+spring3.2+hibernate4.2例子
  10. VC++网络安全编程范例(2)-创建自签名证书