算法排序Word格式.docx
- 文档编号:22001254
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:41
- 大小:42.50KB
算法排序Word格式.docx
《算法排序Word格式.docx》由会员分享,可在线阅读,更多相关《算法排序Word格式.docx(41页珍藏版)》请在冰豆网上搜索。
加法的进位、减法的借位、乘法的进位、除法的商与余数见教材p.220~p.225
⑶运算结果的输出。
输出要注意三点:
①数据是正向储存,用递增循环输出;
数据是反向储存,用递减循环输出
②TP是先定义,后运算的。
无法根据机器的运算的结果来定义数组的大小,所以一般定义数组大一些,这样就增加在有效数字前有一些无用的0操作。
在输出时这些在有效数字前无用的0不能输出。
一般在输出有效数字前采用:
WHILE
a[i]=0
DO
i:
=i-1(正向储存)或
a[i[=0
=i+1(反向储存)
③如是用一个字节储存多位数字,输出时要用0来补位。
【例12-10】把输入的数可能有负数也考虑进去的程序,文件名为
P12_10A;
【变量与算法设计】
用两个逻辑变量f与f1。
用f1来控制运算:
当f1为假做加法,当f1为真做减法。
当f为真来控制数前负号的输出。
具体设置如下:
两个数同号f1为假(做加法运算)
两个数都是正数,f为假
两个数都是负数,f为真。
(f为真输出负号,下同)
两个数异号f1为真(做减法运算)
第一个为负数,第二个为正数。
第一个数的绝对值大于第二个数的绝对值。
f为真
第一个为负数,第二个数正数。
第一个数的绝对值小于第二个数的绝对值。
f为假,
第一个数正数,第二个为负数。
第一个为正数,第二个为负数。
【程序清单】
PROGRAM
CONST
n=200;
VAR
str1,str2,str:
STRING;
k,l1,l2,i,j,t:
Integer;
a,b:
ARRAY
[1..n]
OF
fa,fb:
Char;
f1,f:
Boolean;
BEGIN
Write('
'
Input
a
string
str1
:
);
Readln(str1);
str2
Readln(str2);
l1:
=Length(str1);
l2:
=Length(str2);
{以上同教材}
fa:
=str1[1];
fb:
=str2[1];
f1:
=False;
f:
=f1;
{取符号位,设置f1、f的值}
IF
(fa='
-'
)
AND
(fb='
) {如都是负数,去掉符号位}
THEN
BEGIN {重新设置f1、f的值}
=True;
str1:
=Copy(str1,2,l1);
=l1-1;
str2:
=Copy(str2,2,l2);
=l2-1
END
ELSE
fa='
{如第一个数是负数,去掉其符号位,重新设置f1、f的值}
BEGIN
=l1-1
END;
fb='
THEN {如第二个数是负数,去掉其符号位,重新设置f1、f的值}
j:
=l1;
{如第二个数的绝对值大于第一个数的绝对值就交换,重新设置f的值}
(l2>
l1)
OR
f1
(l2=l1)
(str2>
str1)
THEN
=NOT(f);
=l2;
str:
=str1;
=str2;
=str
FOR
=l1
DOWNTO
{字符串分离同时转换成数字,存入a数组}
Val(str1[i],a[l1+1-i],k);
{不能转换成数字时,输出出错信息}
k>
0
Writeln('
Str1
data
error
!
Readln;
Exit
=l2
{字符串分离同时转换成数字,存入b数组}
Val(str2[i],b[l2+1-i],k);
{不能转换成数字时,输出出错信息}
Str2
f1
BEGIN {f1为真做减法}
=1
TO
j
a[i]:
=a[i]-b[i];
k:
=Ord(a[i]<
0);
{减法借位}
=a[i]+k*10;
a[i+1]:
=a[i+1]-k
(a[j]=0)
(j>
0)
=j-1 {有效数字前无用的0不输出}
BEGIN {f1为假做加法}
=a[i]+b[i];
=k
MOD
10;
{加法进位}
=a[i+1]+k
DIV
10
a[i+1]>
=j+1
{最后一次进位}
Xiang
Jia
He
{输出}
j=0
Write(0)
f
{输出符号位}
=j
Write(a[i]) {高精度输出}
Writeln;
Readln
END.
【例12-11】的另一种编法,文件名
P12_11A;
【例12-12】的另一种编法,文件名
P12_12A;
此两程序在盘上有兴趣的可查看
12.4排
序
排序的算法较多。
最常见有六种:
选择排序、冒泡排序、插入排序、希尔排序和归并排序一定要掌握,其基本算法要牢记,在以后一些程序中可作为过程使用。
快速排序的算法较复杂,给出了两个程序,要求能看懂。
一)选择排序(Paixu1.pas)
PaiXu1;
{选择排序}
n=9;
a:
Integer=(9,8,5,6,2,7,1,4,3);
TYPE
ar=ARRAY
b:
ar;
i,j,k,t:
PROCEDURE
Swap(var
Integer);
{过程—交换数据}
t:
=a;
=b;
=t
Print(a:
ar);
{过程—输出数据}
n
Write(a[i]:
5);
Writeln
b[i]:
=a[i];
{读入数据}
Print(b);
{输出无序的原始数据}
n-1
{用两重循环排序}
=i;
{用k先记下要交换的元素的坐标}
=i+1
{用i的下一元素至n,逐一与k元素比较}
b[k]>
b[j]
=j;
{用k记下较小元素的坐标}
i<
>
k
Swap(b[i],b[k])
{把较小元素与i元素交换}
Readln
{输出有序数据}
注:
以下程序省略程序的说明部分、相应的过程和输入输出。
完整的程序在盘上。
二)冒泡排序(paixu2.pas)
=n;
{从数据的最后操作起}
REPEAT
{用直到循环,f控制排序趟数}
=i-1;
{每排一趟,要排序的元素少一个,因最大数已排至最后}
i
{用计数循环进行一趟排序}
b[j+1]<
{如后一个小于前一个,就交换移前}
Swap(b[j+1],b[j]);
=False
{如有交换f为假,还要循环}
UNTIL
f;
{如这趟排序中没有交换,
f一直为真,排序结束}
三)插入排序
如有下列未排序的数组A的元素:
49
38
65
97
76
13
27
45
用插入方法按升序排序为:
45
49
97
可把数据分成两部分前面的数据有序(开始时只有第1个数据),后面的数据无序(开始时2~n个数据无序),然后把无序的数据插入到有序的数据中去。
无序数据减少,有序数据增多。
把无序数据全部插入为止,
程序分为查找插入的位置、移动数据、插入数据等。
查找搜索的方法有三种:
⑴无序表从头向后搜索,有序表从后向前搜索,一一插入(简称从头插入)
⑵无序表从后向前搜索,有序表从前向后搜索,一一插入(简称从尾插入)
⑶无序表从头向后搜索,有序表折半查找搜索,一一插入(简称折半插入)
1)
从头插入(算法见每句后的注释)(paixu3)
开始数据分成两部分:
第1个数据有序,2~n个数据无序。
=2
{从第二个到n个数据一一插入}
{k为要插入的数,j是有序数列的最大下标}
(k<
a[j])
{当k小于此数,且有序数列前面还有数,就}
a[j+1]:
=a[j];
=j-1;
{将此数向后移,拿前面的数再与k比}
{当k大于等于有序数列的某数就退出当循环,将k插入此数之后}
2)
从尾插入(paixu3a)
第n个数据有序,1~n-1个数据无序
=n-1
{从倒数二个到1数据一一插入}
=i+1;
{k为要插入的数,j是有序数列的最小下标}
(k>
(j<
=n)
{当k大于此数,且有序数列后面还有数,就}
a[j-1]:
=j+1;
{将此数前移,拿后面的数再与k比}
{当k小于等于有序数列的某数就退出当循环,将k插入此数之前}
3)折半插入(paixu3b)
用折半查找要插入的位置。
l:
=1;
h:
{k为要插入的数,l和h为折半查找的上下界}
l<
=h
{当上界<
=下界,就做}
m:
=(l+h)
2;
{取中界值的下标m}
k<
a[m]
=m-1
=m+1{如k<
中界值,则下界=m-1,否则上界=m+1}
{出循环时,上界>
下界}
=i-1
l
{将比k大的数据后移,腾出位置供插入}
a[l]:
{将k插入上界位置}
四)希尔排序
上面的三种排序算法简单,但当排序的数据较多时运行时间较长。
其原因无论是交换或插入都是按顺序一个不漏来操作。
1959年希尔对上面的排序算法进行了改进,在顺序中用增量来取代一个一个的操作。
因此排序的趟数就为之减少。
常见的希尔排序有如下两种:
在插入排序的基础上,加上缩小增量的算法的希尔排序
在冒泡排序的基础上,加上缩小增量的算法的希尔排序
下面给出的程序,增量采用折半缩小的方法(教材上增量用键盘输入),具体算法见各个程序语句后的注释。
请与插入排序、冒泡排序比较,找出其不同处
1)希尔排序(插入法)(paixu4a)
{h取n}
{用外直到循环去搜索}
{每次增量减半}
=h+1
{在h+1到n之间去找插入的位置}
=i-h;
{取要插入的数据t,j为相距一间隔的下标}
t<
a[j]
{当t<
a[j],就把数据向后移一间隔}
a[j+h]:
=j-h;
{再找前一间隔的数来比。
注①}
=t;
{出当循环,把插入j+h的位置上}
{当i>
n,一趟排序结束}
h=1
{直到增量为1,整个排序结束}
注①因为当循环的条件是t<
a[j],所以在这里的j值有时可能出现0或负值,在建立a数组时其下界应考虑负值。
2)希尔排序(冒泡法)(paixu4b)
{用内直到循环去搜索一趟排序}
{f控制内直到循环}
n-h
{在1到n-h之间搜索}
a[j+h]<
{如a[j+h]小于a[j],就}
Swap(a[j+h],a[j]);
{交换,有交换f为假}
{没有交换一趟排序结束}
{增量为1时,整个排序结束}
3)希尔排序,增量采用为1,3,7,15,...(paixu4b)
d[m]:
d[m]<
{增量为1,3,7,15,...}
=m+1;
=2*d[m-1]+1
=m;
=k-1;
=d[k];
{增量取d[k]}
{i为间隔后的一个数起到最后的n}
=i-d;
{当x<
=j-h
{再找前一间隔的数来比,注①}
=t
{出当循环,把t插入在j+h的位置上}
END
五)快速排序
快速排序的算法在教材p.229~p.232中已讲解,下面给出回溯算法(PAIXU5)与递归算法(PAIXU5A)的两个程序。
可对比着看,了解如何把递归算法的程序转化为非递归的程序。
这两种算法在以下章节中讲解。
如在此理解有困难可在学习回溯算法与递归算法时再来阅读。
回溯算法的快速排序(paixu5)
PaiXu5;
{用回溯算法的快速排序}
n=15;
s0:
Byte=(60,38,55,94,93,16,86,73,24,58,22,99,49,15,43);
i,j,k,l,h,c,t:
Byte;
s,a,b:
Pr;
{过程----输出一趟排序的结果,并输出变量交换的情况}
i='
5,i,'
j='
5,j,'
t='
5,t,'
t--->
s['
10,i,'
]'
{输出交换分界点}
Write(s[k]:
Writeln
{输出一趟排序的结果}
{读入数据及输出}
s[i]:
=s0[i];
Write(s[i]:
5)
c:
=0;
{l为头指针,h为尾指针,c栈指针}
{用直到循环来完成排序}
{用f来控制直到循环}
h
{当某数据段的l<
h,就做如下操作}
=l;
=h;
=s[l];
{i,j取头尾指针,数据t为比较的依据,分成小于大于两部分}
{当i<
j,就做如下操作}
(i<
j)
(s[j]>
t)
j且x<
=s[j],就向前搜索}
{这时t>
=s[j],如再i<
j,则}
=s[j];
{s[i]取a[j]值,i向后移}
(s[i]<
j且a[i]<
t,i再向后移}
s[j]:
=s[i];
=j-1
{s[j]取a[i]值,j向前移}
{一直操作i=j为止}
s
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 排序