收藏 分享(赏)

排序算法及应用.ppt

上传人:myw993772 文档编号:7966974 上传时间:2019-05-31 格式:PPT 页数:43 大小:117.50KB
下载 相关 举报
排序算法及应用.ppt_第1页
第1页 / 共43页
排序算法及应用.ppt_第2页
第2页 / 共43页
排序算法及应用.ppt_第3页
第3页 / 共43页
排序算法及应用.ppt_第4页
第4页 / 共43页
排序算法及应用.ppt_第5页
第5页 / 共43页
点击查看更多>>
资源描述

1、第二讲 排序算法及应用,排序算法的种类:,1、选择排序 2、冒泡排序 3、插入排序 4、快速排序 5、堆排序,1、选择排序 算法基本思想: 对待排序的序列进行n-1遍处理:第1遍处理是从a1,a2,an中选择最小的放在a1位置;第2遍处理是从a2,a3,an中选择最小的放在a2位置;第I遍处理是将a i ,a i+1,an中最小的数与a i 交换位置,这样经过第i遍处理后,ai是所有的中的第i小。即前i个数就已经排好序了。 N-1遍处理后,剩下的最后一个一定是最大的,不需要再处理了。,排序的关键字: 20 30 10 15 16 13 8,第i个和后边的依次比较,找最小的放在i处。,a:待排序

2、的数组;/从小到大排序 简单选择排序:for i:=1 to n-1 do 从第一个元素开始,进行n-1遍处理 for j:=i+1 to n do 第i遍处理 If aiaj then 交换ai和aj begin t:=ai; ai:=aj; aj:=t;end;,/简单选择排序:从小到大 const maxn=1000; var n,i,j,t:integer;a:array1maxn of integer; beginrandomize; /随机过程初始化readln(n);for i:=1 to n do ai:=random(1000); /产生n个0,999之间的整数。for i:

3、=1 to n-1 dofor j:=i+1 to n doif aiaj thenbegin t:=ai; ai:=aj; aj:=t; end;for i:=1 to n-1 do write(ai, );writeln(an); end.,算法的改进: 减少交换次数,排序的关键字: 20 30 10 15 16 13 8,右表格体现其变化规律,for i:=1 to n-1 dobegink:=i;for j:=i+1 to n doif aji thenbegin t:=ak; ak:=ai; ai:=t; end;end;,2、冒泡排序算法: 基本思想:(从小到大排序)将待排序的数据

4、看作竖派排的一列”气泡“,小的数据比较轻,从而要上浮。 共进行n-1遍处理,每一遍处理,就是从底向上检查序列,如果相邻的两个数据顺序不对,即轻(小)的在下面,就交换他们的位置。第一遍处理完后,“最轻”的就浮到上面。第二遍处理完后,“次轻”的就浮到上面。共需要n-1遍处理即完成排序。,排序的关键字:从小到大 20 30 10 15 16 13 8,/ 简单的冒泡排序for i:=1 to n-1 dofor j:=n downto i+1 doif ajaj-1 thenbegin t:=aj; aj:=aj-1; aj-1:=t; end;,算法的改进,关键字 20 30 40 50 60 1

5、0,/ 判断标志: flag=true 已有序 /改进后的冒泡排序 for i:=1 to n-1 dobeginflag:=true;for j:=n downto i+1 doif ajaj-1 thenbegint:=aj; aj:=aj-1; aj-1:=t;flag:=false;end;if flag=true then break; /某一轮没有交换,说明都已经有序了end;,3、插入排序算法:,基本思想: 经过i-1遍处理后,a1,a2,ai-1已排好序。 第i遍处理是将元素ai插入到a1,a2,ai-1的适当的位置,从而使得a1,a2,ai-1,ai又是排好的序列。,排序的关

6、键字:从小到大 20 30 10 15 16 13 8,基本思想: 每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。,a:array0n of integer; a0记录当前待插元ai for i:=2 to n dobegina0:=ai; 取第i个元素作为待插入元素j:=i-1; 从已排好的最后一个ai-1开始比较while a0=aj时循环结束aj+1:=a0; 在第j+1个位置插入ai元素end;,4、快速排序算法:,基本思想:把待排序的n个元素放到一个中的任一个元素数组中,先取数组中的某一个元素作为一个基准元素,把

7、这个元素放到数组中合适的位置,同时对其他元素进行调整,使得在这个基准元素的右边的所有元素都比这个基准元素大,而基准元素左边的元素都比它小。也就是说,这个基准元素当前所在的位置就是排序后的最终位置。然后再对基准元素的前后两个区间分别进行快速排序,直到每个区间为空或者只有一个元素时,整个快速排序结束。,方法:取数组中的第一个元素作为基准元素:把待排序的数组按照基准元素分为左右两部分的过程称为快速排序的一次划分(一趟排序)。待排数组:a1 an。 一次划分的过程: 设I,j两个指针,开始时,i 1,j n,x ai:基准元素。如果aj=x 那么j j-1,直到找到ajx,然后:aj ai。,35 1

8、2 37 15 40 31 50 30 29 60,35 12 37 15 40 31 50 30 29 60 6 6 29 12 30 15 31 35 50 40 37 60 3 3 15 12 29 30 31 35 50 40 37 60 2 2 12 15 29 30 31 35 50 40 37 60 4 4 12 15 29 30 31 35 50 40 37 60 9 9 12 15 29 30 31 35 37 40 50 60 7 7 12 15 29 30 31 35 37 40 50 60 12 15 29 30 31 35 37 40 50 60,procedure

9、qsort(s,t:integer);s:待排序数组首元素下标,t:末尾元素下标var i,j:integer;x:integer;begini:=s; j:=t; x:=as; x:首元素为基准元素while i=x) and(ji) do dec(j); 从未尾找比x小的元素ajif ij thenbegin ai:=aj; inc(i); end; 把aj放在i处,j处空着while (ai=x)and(ij) do inc(i); 继续从前边找比x大元素aiif ij thenbegin aj:=ai; dec(j); end; 把ai移动到j位置处,i处空着end;ai:=x; 基准

10、元素x放到合适的i位置if s(i-1) then qsort(s,i-1); 对基准元素x的左区间再进行快速排序if (i+1)t then qsort(i+1,t); 对基准元素x的右区间再进行快速排序end;,主程序的调用: qsort(1,n);,const maxn=10000;/快速排序源程序 var a:array1maxn of integer;n,i:integer;procedure qsort(l,r:integer);var i,j:integer;x:integer;begini:=l; j:=r; x:=al;while i=x) and(ji) do dec(j)

11、;if ii) do inc(i);if ij then begin aj:=ai; dec(j); end;end;ai:=x; /i=jif l(i-1) then qsort(l,i-1);if (i+1)r then qsort(i+1,r);end;,beginrandomize;readln(n);for i:= 1 to n do ai:=random(100);for i:=1 to n-1 do write(ai, );writeln(an);qsort(1,n);for i:=1 to n-1 do write(ai, );writeln(an); end.,排序算法的应用

12、,1、排队接水有n个人排队在一个水笼头前接水,每个人的接水时间互不相等。找出一种n个人排队接水的顺序,使他们平均等待的时间最短。 输入:第一行:n(100).第二行:依次为n个人的接水时间。 输出:第一行:所有人的平均等待时间。第二行:接水的顺序。 样例: 输入:52 6 1 3 8 输出:8.403 1 4 2 5,varnum,t:array1100 of integer;n,i,j,sum,tem:integer; beginreadln(n);for i:=1 to n do read(ti);for i:=1 to n do numi:=i;for i:=1 to n-1 dofor

13、 j:=i+1 to n doif titj thenbegintem:=ti; ti:=tj; tj:=tem;tem:=numi; numi:=numj; numj:=tem;end;sum:=0;for i:=1 to n do sum:=sum+(n+1-i)*ti;writeln(sum/n:0:2);for i:=1 to n-1 do write(numi, );writeln(numn); end.,2、主油管的最优位置Olay教授正在为一家石油公司咨询。该公司正在设计建造一条由东向西的管道,该管道要穿过一个有n口井的油田。从每口井中都有一条喷油管沿最短路径与主管道直接相连(或

14、南或北)。给定各个井的X和Y坐标,Olay教授如何才能选择主管道的最优位置(即使得个喷管长度总和最小的位置)。 输入:3 2 3 3 7 5 4 输出:4,var x,y:array1100of integer;n,i,j,k,m:integer;beginread(n); 油井个数for i:=1 to n do read(xi,yi); 每个油井的坐标for i:=1 to n-1 do 冒泡排序纵坐标:从小到大for j:=i+1 downto n doif yiyj thenbegink:=yi;yi:=yj;yj:=k;end;if n mod 2=1 then write(y(n+

15、1) div 2) 输出中间值else write(yn div 2, ,y n div 2+1); 输出中间区间end.,3、区间合并【问题描述:】 从键盘上任意输入n个区间,然后按从小到大的顺序依次输出n个区间的并集。 【输入:】 第一行,区间个数n(=1000) 以下n行,每行两个整数a、b(-1000000000ab1000000000),相应区间的坐标,中间 一个空格。 【输出:】n个区间的并集,n行,每行一个区间,坐标轴的左边的区间先输出。 【样例输入:】 3 2 5 1 4 7 8 【样例输出:】 1 5 7 8,区间的合并,注意: 1、区间个数n的范围(=1000) 2、区间的

16、数据类型和范围:整数类型、-109-109,算法一:离散化,思路: 设fi:01,初始值全部为0。 每读入一个区间 a bFor i:=1 to nFor j:=a to b do fj=1 最后输出 fj=1 的区间。 时间复杂度: 1012,只能过部分数据。,算法二:直接合并,1、按每个区间的左端的的值升序排列。由于N=1000,任意排序算法。注意数据结构的设置:记录类型二维数组:a:array11000,12 of longint;a:array11000of array12 of longint,2、合并过程, 输出第一个区间 的左端点坐标(最小的) 依次处理后面的 n-1 的区间。,

17、If aI,2=tail Tail不变,If (aI,1=tail)and(tail=aI,2) Tail=aI,2,If tailaI,1 Writeln(tail); Write(aI,1); Tail:=aI,2;,write(a1,1, );tail:=a1,2;for i:=2 to n dobeginif (ai,1=tail)and(tail=ai,2) /2then tail:=ai,2;if tailai,1 then /3beginwriteln(tail);write(ai,1, );tail:=ai,2;end;end;writeln(tail);,constmax=1

18、000;fin=bing.in;fout=bing.out; type data=array12 of longint; vara:array1max of data;n,i,j:integer;procedure init;var t:data;beginassign(input,fin);reset(input);readln(n);for i:=1 to n do readln(ai,1,ai,2);close(input);for i:=1 to n-1 dofor j:=i+1 to n doif ai,1aj,1 thenbegin t:=ai; ai:=aj; aj:=t; en

19、d;end;,procedure main;vari:integer;tail:longint;beginassign(output,fout);rewrite(output);write(a1,1, );tail:=a1,2;for i:=2 to n dobeginif (ai,1=tail)and(tail=ai,2) then tail:=ai,2;if tailai,1 thenbeginwriteln(tail);write(ai,1, );tail:=ai,2;end;end;writeln(tail);close(output);end;,/主程序 begininit;main

20、; end.,4、潜水比赛在马其顿王国举行了一次潜水比赛。其中一个项目是从高山上跳下 水,再潜水达到终点。这是一个团体项目,一支队伍由n人组成。在潜水时必 须使用氧气瓶,但是每只队伍只有一个氧气瓶。最多两人同时使用一个氧气 瓶,但此时两人必须同步游泳,因此两人达到终点的时间等于较慢的一个人 单独游到终点所需要的时间。好在大家都很友好,因此任何两个人后都愿意 一起游水。安排一种潜水的策略,使得最后一名选手尽量的达到终点。 输入: 第一行:队伍的人数n(=1000)。 第二行:n个数,分别是n个人潜水所用的时间ti(=1000)。 样例: 输入: 3 1 3 4 输出: 8,分析: 先从简单入手:

21、,1) n=2 ,时间 t: 1 10 所需的时间为:10,2) n=3, 时间 t: 1 3 4,所需的时间为:3+1+4=8,3) n=4 ,时间 t: 1 10 11 12,所需的时间为:10+1+11+1+12=35,贪心策略方法一:N个人: 每个人所需的时间: t1,t2,tn。假设t1最小。每次由t1接送人和氧气瓶,则,总时间:s=t2+t3+。tn+(n-2)*t1,4)n=4 ,每个人所用时间:1 2 5 8,采用 贪心策略方法一:计算所用的总时间为:,2+5+8+1*2=17,事实上:采用下面策略: 第一步: 1 2一起先过, 用时:2 第二步: 1 送回氧气瓶, 用时:1

22、第三步: 5 8一起过, 用时: 8 第四步: 2送回氧气瓶, 用时:2 第五步: 1 和2一起过去, 用时:2 完成。共用时:2+1+8+2+2=1517,贪心策略方法二:,将n个人的时间从小到达排序,假设从小到大为: t1,t2,tn 1:t1和t2过: t2 2:t1带瓶返回:t1 3:最大的两个人:tn tn-1 过:tn 4:t2带瓶返回:t2 把以上看作一趟:把用事最长的两个人tn ,tn-1送过去:用时:2*t2+t1+tn 重复上述过程:用t1和t2在把tn-2 ,tn-3 送过去,用时: 2*t2+t1+tn-2 每趟都用t1和t2,每趟运送2人。,最后如果剩2人:t1,t2

23、: 时间: t2 最后如果剩3人:t1,t2,t3 时间: t1+t2+t3,5)n=5,时间:1 10 11 12 100 101 按照贪心策略方法二:计算总时间:,165,另外的方法: 10 10 1 1 100 101 101 10 10 1 12 12 1 1 1 11 11 1 1 1 10 10,157!,贪心策略方法三:每一趟送用时间最长的两个人时:根据情况选择:用t1和t2两个人还是只用t1一个人。,用t1和t2送一趟用时: x=2*t2+t1+tn,用t1一个人送一趟(2人):y=2*t1+tn+tn-1,每送一趟都要比较x和y的大小: If xy then 用t1送 els

24、e 用t1和t2送,贪心三算法: 数组a存时间: 把时间从小到大排序。 sum:=0;if odd(n) then begin sum:=sum+a2+a1+a3 end else sum:=sum+a2;i:=n;while i3 dobeginx:=2*a2+a1+ai; 用a1和a2送一趟y:=2*a1+ai+ai-1; 用a1送一趟if xy then sum:=sum+x else sum:=sum+y;dec(i,2); i=i-2:每趟送两人end;writeln(sum);,1、成绩排名 【问题描述:】 根据期末考试的成绩单信息,把所有的学生按总分从高到低的顺序输出。 【输入:

25、】 第一行:学生的个数n(n=100)。 以下n行:每行包含一个学生的信息,依次是:学号(1n)、姓名、语文成绩、数学成绩。他们中间有且仅有一个空格隔开,输入信息中没有多余的空格。姓名全是字母,长度不大于200,各科成绩不超过100。 【输出:】 N行,每行包含一个学生的信息:学号、姓名、总分。中间用一个空格隔开,不能有多余的空格。总分相同的学生,学号大的在前。【样例输入:】 4 3 abc 40 50 2 gd 50 40 1 wr 60 60 4 dsd 10 20,【样例输出:】 1 wr 120 3 abc 90 2 gd 90 4 dsd 30,排序算法课后练习:,2、修理牛棚在一个

26、暴风雨的夜晚,农民约翰的牛棚的屋顶、门被吹飞了。 好在许多牛正在度假,所以牛棚没有住满。有些牛棚里有牛,有些没有。 所有的牛棚有相同的宽度,并且一个紧挨着另一个被排成一行。 自门遗失以后,农民约翰很快在牛棚门口之前竖立起新的木板。 他的新木材供应者将会供应他任何他想要的长度,但是供应者只能提供有限数目的木板。 农民约翰想将他购买的木板总长度减到最少。 给出可能买到的木板最大的数目M(1= M=50);牛棚的总数S(1= S=200);牛棚里牛的数目C(1 = C =S)。牛所在的牛棚的编号number(1 = number = S),计算拦住所有有牛的牛棚所需木板的最小总长度。 输出所需木板的最小总长度(每个牛棚的宽度为1)作为的答案。 输入: 第1行:M S C(中间用空格分开) 第 2行共c个整数,表示牛所占的牛棚的编号。 输出:单独的一行包含一个整数,表示所需木板的最小总长度。 样例: 输入: 4 50 18 3 4 6 8 14 15 16 17 21 25 26 27 30 31 40 41 42 43 输出: 25 提示: 一种最优的安排是用板拦住牛棚3-8,14-21,25-31,40-43.,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报