`
897371388
  • 浏览: 528421 次
文章分类
社区版块
存档分类
最新评论

排序算法(Pascal)

 
阅读更多
排序算法(Pascal)



排序就是将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程。


一、 简单排序
1.选择排序


选择排序的基本思想是:


对待排序的记录序列进行n-1遍的处理,第1遍处理是将L[1..n]中最小者与L[1]交换位置,第 2遍处理是将L[2..n]中最小者与L[2]交换位置,......,第i遍处理是将L[i..n]中最小者与L[i]交换位置。这样,经过i遍处理之后,前i个记录的位置就已经按从小到大的顺序排列好了。


例1:输入序列数据按非减顺序输出.


程序如下:


program xzpx;
const n=7;
var a:array[1..n] of integer;
i,j,k,t:integer;
begin
write('Enter date:');
for i:= 1 to n do read(a[i]);
writeln;
for i:=1 to n-1 do
begin
k:=i;
for j:=i+1 to n do
if a[j]<a[k] then k:=j;
if k<>i then
begin t:=a[i];a[i]:=a[k];a[k]:=t;end;
end;
write('output data:');
for i:= 1 to n do write(a[i]:6);
writeln;
end.
2.插入排序


插入排序的基本思想:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置p,原来p后的元素一一向右移动一个位置,使得L[1..i]又是排好序的序列。


例2:输入序列数据按非减顺序输出.


程序1:


program crpx;
const n=7;
var a:array[1..n] of integer;
i,j,k,t:integer;
begin
write('Enter date:');
for i:= 1 to n do read(a[i]);
writeln;
for i:=2 to n do
begin
k:=a[i];j:=i-1;
while (k<a[j]) and (j>0) do
begin a[j+1]:=a[j];j:=j-1 end;
a[j+1]:=k;
end;
write('output data:');
for i:= 1 to n do write(a[i]:6);
writeln;
end.
3.冒泡排序


冒泡排序又称交换排序其基本思想是:对待排序的记录的关键字进行两两比较,如发现两个


记录是反序的,则进行交换,直到无反序的记录为止。


例:输入序列数据按非减顺序输出。


程序1:


program mppx;
const n=7;
var a:array[1..n] of integer;
i,j,k,t:integer;
begin
write('Enter date:');
for i:= 1 to n do read(a[i]);
for i:=1 to n -1 do
for j:=n downto i+1 do
if a[j-1]<a[j] then
begin t:=a[j-1];a[j-1]:=a[j];a[j]:=t end;
write('output data:');
for i:= 1 to n do write(a[i]:6);
writeln;
end.


二、快速排序


快速排序的思想是:先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1, 处理结束.


例:输入一组数据小到大排序.


程序1:


program kspv;
const n=7;
type
arr=array[1..n] of integer;
var
a:arr;
i:integer;
procedure quicksort(var b:arr; s,t:integer);
var i,j,x,t1:integer;
begin
i:=s;j:=t;x:=b[i];
repeat
while (b[j]>=x) and (j>i) do j:=j-1;
if j>i then begin t1:=b[i]; b[i]:=b[j];b[j]:=t1;end;
while (b[i]<=x) and (i<j) do i:=i+1;
if i<j then begin t1:=b[j];b[j]:=b[i];b[i]:=t1; end
until i=j;
b[i]:=x;
i:=i+1;j:=j-1;
if s<j then quicksort(b,s,j);
if i<t then quicksort(b,i,t);
end;
begin
write('input data:');
for i:=1 to n do read(a[i]);
writeln;
quicksort(a,1,n);
write('output data:');
for i:=1 to n do write(a[i]:6);
writeln;
end.


 


程序2:


program kspv;
const n=7;
type
arr=array[1..n] of integer;
var
a:arr;
i:integer;
procedure quicksort(var b:arr; s,t:integer);
var i,j,x:integer;
begin
i:=s;j:=t;x:=b[i];
repeat
while (b[j]>=x) and (j>i) do j:=j-1;
if j>i then begin b[i]:=b[j];i:=i+1;end;
while (b[i]<=x) and (i<j) do i:=i+1;
if i<j then begin b[j]:=b[i];j:=j-1; end
until i=j;
b[i]:=x;
i:=i+1;j:=j-1;
if s<j then quicksort(b,s,j);
if i<t then quicksort(b,i,t);
end;
begin
write('input data:');
for i:=1 to n do read(a[i]);
writeln;
quicksort(a,1,n);
write('output data:');
for i:=1 to n do write(a[i]:6);
writeln;
end.


三、希尔排序 


基本思想:将整个无序序列分割成若干小的子序列分别进行插入排序或冒泡排序。


序列分割方法:将相隔某个增量h的元素构成一个子序列。在排序过程中,逐次减小这个增量,最后当h减到1时,进行一次插入排序或冒泡排序,排序就完成。增量序列一般采用:d1=n div 2 ,di=di-1 div 2 ;i=2,3,4.....其中n为待排序序列的长度。


程序1:(子序列是插入排序)


program xepx;
const n=7;
type
arr=array[1..n] of integer;
var
a:arr;
i,j,t,d:integer;
bool:boolean;
begin
write('input data:');
for i:=1 to n do read(a[i]);
writeln;
d:=n;
while d>1 do
begin
d:=d div 2;
for j:=d+1 to n do
begin
t:=a[j];i:=j-d;
while (i>0) and (a[i]>t) do
begin a[i+d]:=a[i];i:=i-d;end;
a[i+d]:=t;
end;
end;
write('output data:');
for i:=1 to n do write(a[i]:6);
writeln;
end.


程序2:(子序列是冒泡排序)


program xepx;
const n=7;
type
arr=array[1..n] of integer;
var
a:arr;
i,temp,d:integer;
bool:boolean;
begin
write('input data:');
for i:=1 to n do read(a[i]);
writeln;
d:=n
while d>1 do
begin
d:=d div 2;
repeat
bool:=true;
for i:=1 to n-d do
if a[i]>a[i+d] then
begin temp:=a[i];a[i]:=a[i+d];a[i+d]:=temp; bool:=false end;
until bool;
end;
write('output data:');
for i:=1 to n do write(a[i]:6);
writeln;
end.


四、堆排序与二叉树排序
1.堆排序


堆:设有数据元素的集合(R1,R2,R3,...Rn)它们是一棵顺序二叉树的结点且有


Ri<=R2i 和Ri<=R2i+1(或>=)


堆的性质:堆的根结点上的元素是堆中的最小元素,且堆的每一条路径上的元素都是有序的。


堆排序的思想是:


1)建初始堆(将结点[n/2],[ n/2]-1,...3,2,1分别调成堆)


2)当未排序完时


输出堆顶元素,删除堆顶元素,将剩余的元素重新建堆。


程序如下:


program duipx;
const n=8;
type arr=array[1..n] of integer;
var a:arr;i:integer;
procedure sift(var a:arr;l,m:integer);
var i,j, t:integer;
begin
i:=l;j:=2*i;t:=a[i];
while j<=m do
begin
if (j<m) and (a[j]>a[j+1]) then j:=j+1;
if t>a[j] then
begin a[i]:=a[j];i:=j;j:=2*i; end
else exit;
a[i]:=t;
end;


end;
begin
for i:=1 to n do read(a[i]);
for i:=(n div 2) downto 1 do
sift(a,i,n);
for i:=n downto 2 do
begin
write(a[1]:4);
a[1]:=a[i];
sift(a,1,i-1);
end;
writeln(a[1]:4);
end.
2.二叉树排序


排序二叉树:每一个参加排列的数据对应二叉树的一个结点,且任一结点如果有左(右)子树,则左(右)子树各结点的数据必须小(大)于该结点的数据。中序遍历排序二叉树即得排序结果。程序如下:


program pxtree;
const
a:array[1..8] of integer=(10,18,3,8,12,2,7,3);
type point=^nod;
nod=record
w:integer;
right,left:point ;
end;
var root,first:point;k:boolean;i:integer;
procedure hyt(d:integer;var p:point);
begin
if p=nil then
begin
new(p);
with p^ do begin w:=d;right:=nil;left:=nil end;
if k then begin root:=p; k:=false end;
end
else with p^ do if d>=w then hyt(d,right) else hyt(d,left);
end;
procedure hyt1(p:point);
begin
with p^ do
begin
if left<>nil then hyt1(left);
write(w:4);
if right<>nil then hyt1(right);
end
end;
begin
first:=nil;k:=true;
for i:=1 to 8 do hyt(a[i],first);
hyt1(root);writeln;
end.


五、归并排序


归并就是将多个有序的数列合成一个有序的数列。将两个有序序列合并为一个有序序列叫二路归并(merge).归并排序就是n长度为1的子序列,两两归并最后变为有序的序列。
1.二路归并


例1:将有序表L1=(1,5,7),L2=(2,3,4,6,8,9,10)合并一个有序表 L.


program gb;


const m=3;n=7;


type arrl1=array[1..m] of integer;


arrl2=array[1..n] of integer;


arrl=array[1..m+n] of integer;


var a:arrl1;


b:arrl2;


c:arrl;


i,j,k,r:integer;


begin


write('Enter l1(sorted):');


for i:=1 to m do read(a[i]);


write('Enter l2(sorted):');


for i:=1 to n do read(b[i]);


i:=1;j:=1;k:=0;


while (i<=m) and (j<=n) do


begin


k:=k+1;


if a[i]<=b[j] then begin c[k]:=a[i];i:=i+1; end


else begin c[k]:=b[j];j:=j+1;end;


end;


if i<=m then for r:=i to m do c[m+r]:=a[r];


if j<=n then for r:=j to n do c[n+r]:=b[r];


writeln('Output data:');


for i:=1 to m+n do write(c[i]:5);


writeln;


end.
2.归并排序


program gbpx;
const maxn=7;
type arr=array[1..maxn] of integer;
var a,b,c:arr;
i:integer;
procedure merge(r:arr;l,m,n:integer;var r2:arr);
var i,j,k,p:integer;
begin
i:=l;j:=m+1;k:=l-1;
while (i<=m)and (j<=n) do
begin
k:=k+1;
if r[i]<=r[j] then begin r2[k]:=r[i];i:=i+1 end
else begin r2[k]:=r[j];j:=j+1 end
end;
if i<=m then
for p:=i to m do begin k:=k+1;r2[k]:=r[p] end;
if j<=n then
for p:=j to n do begin k:=k+1;r2[k]:=r[p] end;
end;
procedure mergesort( var r,r1:arr;s,t:integer);
var k:integer; c:arr;
begin
if s=t then r1[s]:=r[s] else
begin
k:=(s+t) div 2;
mergesort(r,c,s,k);
mergesort(r,c,k+1,t);
merge(c,s,k,t,r1)
end;
end;
begin
write('Enter data:');
for i:= 1 to maxn do
read(a[i]);
mergesort(a,b,1,maxn);
for i:=1 to maxn do
write(b[i]:9);
writeln;
end.


六、 线形排序


以上我们讨论的算法均是基于比较的排序算法,在排序算法中有基于数字本身的算法:计数、桶、基数排序。
1.计数排序


基本思想是对于序列中的每一元素x,确定序列中小于x的元素的个数。


例:n个整数序列且每个值在[1,m],排序之。


program jspx;
const m=6;n=8;
var i,j:integer;
a,b:array[1..n] of integer;
c:array[1..m] of integer;
begin
writeln('Enter data:');
for i:=1 to n do read(a[i]);
for i:=1 to m do c[i]:=0;
for i:=1 to n do c[a[i]]:=c[a[i]]+1;
for i:=2 to m do c[i]:=c[i]+c[i-1];
for i:=n downto 1 do
begin
b[c[a[i]]]:=a[i];
c[a[i]]:=c[a[i]]-1;
end;
writeln('Sorted data:');
for i:= 1 to n do
write(b[i]:6);
end.
2.桶排序


桶排序的思想是若待排序的记录的关键字在一个明显有限范围内(整型)时,可设计有限个有序桶,每个桶装入一个值,顺序输出各桶的值,将得到有序的序列。


例:输入n个0到100之间的整数,由小到大排序输出。


program tpx;
const n=7;
var b:array[0..100] of integer;
k:0..100;
i:integer;
begin
write('Enter date:(0-100)');
for i:=0 to 100 do b[i]:=0;
for i:= 1 to n do
begin
read(k);
b[k]:=b[k]+1;
end;
writeln('Output data:');
for i:=0 to 100 do
while b[i]>0 do begin write(i:6);b[i]:=b[i]-1 end;
writeln;
end.
3.基数排序


基本思想是对n个元素依次按k,k-1,...1位上的数字进行桶排序。


program jspx;
const n=8;
type link=^node;
node=record
data:integer;
next:link;
end;
var i,j,l,m,k:integer;
a:array[1..n] of integer;
s:string;
q,head:array[0..9] of link;
p,p1:link;
begin
writeln('Enter data:');
for i:=1 to n do read(a[i]);
for i:=5 downto 1 do
begin
for j:=0 to 9 do
begin
new(head[j]);
head[j]^.next:=nil;
q[j]:=head[j]
end;
for j:=1 to n do
begin
str(a[j],s);
for k:=1 to 5-length(s) do
s:='0'+ s;
m:=ord(s[i])-48;
new(p);
p^.data:=a[j];
p^.next:=nil;
q[m]^.next:=p;
q[m]:=p;
end;
l:=0;
for j:=0 to 9 do
begin
p:=head[j];
while p^.next<>nil do
begin
l:=l+1;p1:=p;p:=p^.next;dispose(p1);a[l]:=p^.data;
end;
end;
end;
writeln('Sorted data:');
for i:= 1 to n do
write(a[i]:6);
end.





七、各种排序算法的比较


1.稳定性比较


插入排序、冒泡排序、二叉树排序、二路归并排序及其他线形排序是稳定的


选择排序、希尔排序、快速排序、堆排序是不稳定的


2.时间复杂性比较


插入排序、冒泡排序、选择排序的时间复杂性为O(n2)


其它非线形排序的时间复杂性为O(nlog2n)


线形排序的时间复杂性为O(n);


3.辅助空间的比较


线形排序、二路归并排序的辅助空间为O(n),其它排序的辅助空间为O(1);


4.其它比较


插入、冒泡排序的速度较慢,但参加排序的序列局部或整体有序时,这种排序能达到较快的速度。


反而在这种情况下,快速排序反而慢了。


当n较小时,对稳定性不作要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序。


若待排序的记录的关键字在一个明显有限范围内时,且空间允许是用桶排序。


当n较大时,关键字元素比较随机,对稳定性没要求宜用快速排序。


当n较大时,关键字元素可能出现本身是有序的,对稳定性有要求时,空间允许的情况下。


宜用归并排序。


当n较大时,关键字元素可能出现本身是有序的,对稳定性没有要求时宜用堆排序。
分享到:
评论

相关推荐

    常用算法pascal-ppt课件

    常用算法 1、穷举法 2、排序算法 3、不同进制数的转换及应用 4、高精度计算 5、回溯算法 6、递推法 7、排列和组合 8、动态规划基础

    pascal排序算法借鉴.pdf

    pascal排序算法借鉴.pdf

    本人利用pascal 写的delphi算法与数据结构的源代码

    ---------拓扑排序--------- f a d c e b ---------用邻接表构造带权有向图--------- b ---- 3 c ---- 2 d ---- 2 e ---- 3 d ---- 4 f ---- 3 f ---- 2 f ---- 1 --------------关键路径--------------- 0 1 1 2 1 ...

    必背经典算法(pascal)

    数论、图论、动归、排序、高精度、树的遍历、进制转换、搜索、链表

    各种数据结构与算法的c++和pascal语言图形化演示程序

    这是一个学习用C++和pascal语言各种数据结构和算法的图形化演示程序。数据结构包括链表,顺序表,串,广义表,二叉树,稀疏矩阵,图,动态查找,静态查找,存储,内部排序,外部排序等。其中所涉及的各种经典算法都...

    Pascal信息竞赛辅导

    子界与枚举类型 第九章 集合类型 第十章 记录与文件类型 第十一章 指针 第十二章 程序调试 常用算法与策略 第一章 算法的概念 第二章 递归 第三章 回溯 第四章 排序 第五章...

    比快排还快的排序算法

    我测试过在500000的范围内比一般的快排快,但是不知道增加数据大小后,两者的优劣(用的Pascal语言)

    数据结构算法演示系统

    数据结构算法:Pascal语言和C语言两种。很详细,包含顺序表、链表、栈、串、稀疏矩阵、广义表、二叉树、图、存储管理、静态查找、动态查找、内部排序、外部排序。数据结构课程老师分享的。

    Pascal的多种退出语句用法.doc

    计算机基础知识 第一章 计算机基础常识 第二章 操作系统简介 第三章 计算机网络 第四章 计算机信息安全基础知识 ...第四章 排序 第五章 查找 第六章 穷举策略 第七章 贪心算法 第八章 分治策略 数据结构

    数据结构算法演示程序(包含PASCAL / C两种语言)

    对数据结构包含的所有算法一步一步的演示,线性表,树,堆栈,图,排序,查找等算法。很细致,很形象化的演示,让读者更加易懂!

    数据结构与算法(C++语言描述)

    书中不仅系统介绍了各种传统的数据结构和搜索、排序算法,还引入了比较高级的数据结构,如伸展树和跳表。本书讨论算法分析和算法设计策略,讨论搜索和排序算法的时间下界,还介绍了随机算法以及NP难度和NP完全问题。...

    pascal历届试题选择题(附答案) 数据结构和算法

    把前几年的noip初赛试题中有关数据结构的做了筛选,专门给学生做

    数据结构与算法演示程序

    数据结构与算法演示程序,可以单步执行,便于深入理解各种数据结构执行步骤 包含顺序表、链表、栈、串、稀疏矩阵、广义表、二叉树、图、存储管理、静态查找、动态查找、内部排序、外部排序等Pascal语言和C语言描述

    cpp-算法精粹

    本书的目标读者是准备去硅谷找工作的码农,也适用于在国内找工作的码农,以及刚接触ACM算法竞赛的新手。 市场上讲解算法的书已经汗牛充栋,为什么还要写这本书呢?主要原因是我对目前市场上的大部分算法书都不太...

    C++数值算法(第二版)的例程

    包含了当代科学计算过程中涉及的大量内容:求特殊函数值、随机数、排序、最优化、快速傅里叶变换、谱分析、小波变换、统计描述和数据建模、偏微分方程数值解、若干编码算法和任意精度计算等。 ·科学性和实用性统一...

    算法经典习题大全

    知识点概括全面的算法习题大全,搞定所有这100多道问题,NOIP提高组一等奖指日可待。每道题包含c++和Pascal两种竞赛常用语言的代码,和多组测试数据,方便大家查错。包含9个模块:高精度,排序,递归,递推,贪心,...

    数据结构算法演示.zip

    该程序以动画的形式向学习者展示各种算法的执行过程,帮助学习者更好的理解。无需安装,解压即用。包括顺序表、链表、栈、串、稀疏矩阵、广义表、二叉树、图、存储管理、静态查找、动态查找、内部排序、外部排序等。...

    经典问题算法的Java实现

    经典问题算法的Java实现/河内塔、费氏数列、Pascal三角形、选择插入气泡排序、快速排序、合并排序、二分查找等。

    数据结构与算法演示软件

    此软件最大优点就是提供了同步演示功能,通过代码与图形相结合,能够很快的理解算法。描述了包括表、树、图、栈、串等数据结构,还包括查询、排序等算法,可选择pascal和c语言

Global site tag (gtag.js) - Google Analytics