快速排序与二分查找文档格式.docx
《快速排序与二分查找文档格式.docx》由会员分享,可在线阅读,更多相关《快速排序与二分查找文档格式.docx(8页珍藏版)》请在冰豆网上搜索。
基础实验大楼A508实验时间:
一、实验室名称:
软件实验室
二、实验项目名称:
数据结构与算法一快速排序与二分查找
三、实验学时:
4
四、实验原理:
快速排序的基本思想是:
通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。
一躺快速排序的算法是:
1)设置两个变量I、J,排序开始的时候I:
=1,J:
=N
2)以第一个数组元素作为关键数据,赋值给X,即X:
=A[1];
3)从J开始向前搜索,即(J:
=J-1),找到第一个小于X的值,两者交换;
4)从I开始向后搜索,即(I:
=1+1),找到第一个大于X的值,两者交换;
5)重复第3、4步,直到I=J。
二分法查找(折半查找)的基本思想:
(1)确定该区间的中点位置:
mid=
(low+high)/2
min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置
(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:
A)如果R[mid].key>
a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中,这时high=mid-1;
B)如果R[mid].key<
a,则等于a的关键字如果存在,必然在R[mid].key右边的表中。
这时low=mid;
C)如果R[mid].key=a,则查找成功。
(3)下一次查找针对新的查找区间,重复步骤
(1)和
(2)
(4)在查找过程中,low逐步增加,high逐步减少,如果high<
low,则查找失败。
五、实验目的:
本实验通过实现快速排序和折半查找算法,使学生理解如何实现快速查
找和排序的基本算法思想。
通过练习,加强对算法的理解,提高编程能力。
六、实验内容:
(1)实现数据序列的输入;
(2)实现快速排序算法,并对输入的序列排序后输出;
(3)实现折半查找算法,并在步骤
(2)排序后的序列上,进行任意地查找,并输出查询结果。
七、实验器材(设备、元器件):
PC机一台,装有C/C++语言集成开发环境。
八、数据结构及程序
/****************************************
******************
**
*
*陈家浩
*****************************************
****************
#include<
stdio.h>
#defineMAX100
intData[MAX+1]={0};
int
Quick_Part(int
Data[],int
i,intj);
//一
趟排
序
Quick_Sort(int
s,intt);
//递归排
Quick_Find(int
data,int
n);
//二
分查找
intmain(void)
I
intchoose=-1inti,k,data;
;
//选择功能
intn;
//数据序列长度
while
(1)
{
printf("
+排序与查找-
+\n"
"
|
1:
输入数据序列
|\n"
2:
序列排序
3:
查找信息
0:
退出
++++++++++++\n"
请选择:
"
);
scanf("
%d"
&
choose);
switch(choose)
case1:
请输入序列数据个数:
scanf("
if(n>
MAX){
数据过多!
\n\n"
break;
}
else{
请输入数据序列:
\n"
for(i=1;
i<
=n;
i++)scanf("
Data[i]);
读取成功!
\n\n"
break;
case2:
Quick_Sort(Data,1,n);
//快速排序
排序成功!
序列如下:
for(i=1;
i++)
%d"
Data[i]);
printf("
case3:
请输入待查找的数据:
data);
k=Quick_Find(Data,data,n);
//二分
法查找
if(k)
查找成功!
数据\"
%d\"
位于序列第%d位。
data,k);
else
查找失败!
没有你要查找的数据!
default:
return0;
intQuick_Part(intData[],inti,intj)
{//快速排序
Data[0]=Data[i];
while(i<
j){
while((i<
j)&
&
(Data[0]<
=Data[j]))
j--;
//右边目标元比划
分元大,j往左移
if(i<
Data[i]=Data[j];
//比划分元小的关键字交换到左边
i++;
}while((i<
(Data[0]>
=Data[i]))
//左边目标元比划
分元小,i往右移
Data[j]=Data[i];
//比划分元大的关键字交换到右边
Data[i]=Data[0];
//划分元存入正
//返回划分元
确位置
returni;
的位置
intQuick_Sort(intData[],ints,intt)
inti=Quick_Part(Data,s,t);
//调用划分过程将顺序表分成两部分
if(i>
s)
Quick_Sort(Data,s,i-1);
//递归调用排序
if(i<
t)
Quick_Sort(Data,i+1,t);
//递归调用排序
//二分查
intQuick_Find(intData[],intdata,intn){
找
intlow=1;
inthigh=n;
intmid;
//中间位置
//查找成功返回
while(low<
=high){mid=(low+high)/2;
if(data==Data[mid])returnmid;
位置
elseif(data>
Data[mid])low=mid+1;
high=mid-1;
II查找失败
返回0
九、程序运行结果:
十、实验结论:
通过实现快速排序和折半查找算法,基本达到了实验目的。
快速排序的基本思想是每次确定一个划分元,将比划分元大的数据存储到划分元右边,比他小的存储到他左边,通过递归排序实现整个顺序表的排序。
然而,其中的递归调用很难,需要思考其中参数的变化,这需要细心。
十^一、总结及心得体会:
1对错误输入的解决方案还有待完善;
2快速排序递归调用结束的条件需要慎重考虑,否则极易陷入死循环。
例如课本上的while(svt)结束条件,第一次递归的s,t根本不会发生改变,以至于程序进入了死循环;
3、顺序表的存储方式可以有多种,这里为了方便采用了整形数组方式存储,当然也可以用结构数组来存储;
4、函数的返回值作用很大,要仔细决定;
5、实验虽然简单,淡水在以后的各个方面都会用到,所以应仔细完成,深刻理解内容。