第6章 常用算法与数据结构副本Word格式.docx
- 文档编号:19373474
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:33
- 大小:304.12KB
第6章 常用算法与数据结构副本Word格式.docx
《第6章 常用算法与数据结构副本Word格式.docx》由会员分享,可在线阅读,更多相关《第6章 常用算法与数据结构副本Word格式.docx(33页珍藏版)》请在冰豆网上搜索。
一个插入排序的例子
*/
classArrayIns
{
privatedouble[]a;
//定义double类型的数组
privateintnElems;
//变量nElems存储数据项数
publicArrayIns(intmax)//构造器
{
a=newdouble[max];
nElems=0;
}
publicvoidinsert(doublevalue)//插入数据到数组中
a[nElems]=value;
nElems++;
publicvoiddisplay()//显示数组中的数据
for(intj=0;
j<
nElems;
j++)
System.out.print(a[j]+"
"
);
System.out.println("
"
publicvoidinsertionSort()
intin,out;
for(out=1;
out<
out++)
doubletemp=a[out];
in=out;
while(in>
0&
&
a[in-1]>
=temp)//查找插入的位置
a[in]=a[in-1];
//数据在数组中右移一个位置
--in;
a[in]=temp;
//插入到正确位置
}
}//endinsertionSort()
}//endclassArrayIns
classInsertSortDemo{
publicstaticvoidmain(String[]args)
intmaxSize=100;
//数组初始大小为100
ArrayInsarr;
arr=newArrayIns(maxSize);
//建立排序数组
arr.insert(50);
//插入8个数
arr.insert(32);
arr.insert(63);
arr.insert(97);
arr.insert(75);
arr.insert(13);
arr.insert(26);
arr.insert(45);
排序前:
arr.display();
arr.insertionSort();
//进行插入排序
排序后:
}//endmain()
}//endclassInsertSortDemo
在main()方法中通过调用方法insert(doublevalue)插入了8个数,然后调用方法insertSort()进行排序,display()方法用来输出数据,其结果输出如图6-1所示。
图6-1【例6.1】的运行结果
2、冒泡排序
冒泡排序(BubbleSort)算法的基本思路是把当前数据序列中的各相邻数据两两比较,发现任何一对数据间不符合要求的升序或降序关系则立即调换它们的顺序,从而保证相邻数据间符合升序或降序的关系。
冒泡排序的过程很简单。
首先将序列中的第一个数和第二个数进行比较,若为逆序(即第一个数>
第二个数),则将两个数交换之,然后比较第二个数和第三个数。
依次类推,直至第n-1个数和第n个数进行过比较为止。
上述过程称为第一趟冒泡排序,其结果使得序列中的最大数被安置到最后一个数的位置上。
然后进行第二趟冒泡排序,对前n-1个记录进行相同的操作,其结果是使序列中次大的数被安置到第n-1个数的位置上。
依此类推,每一趟两两比较和交换(称为“扫描”)都将使一个数据就位并使未排序的数据数目减一,所以经过k趟〔1≤k<n〕扫描之后,所有的数据都将就位,未排序数据数目为零,而整个冒泡排序就完成了。
显然,判别冒泡排序结束的条件应该是“在一趟排序过程中没有进行过交换数的操作”。
50,32,63,97,75,13,26,45
则经过第一趟冒泡排序后其序列如下所示:
32,50,63,75,13,26,45,97
【例6.2】冒泡排序
/*ProgramnameBubbleSortDemo.java
一个冒泡排序的例子
*/
classArrayBub
privateint[]a;
//定义int类型的数组
publicArrayBub(intmax)//构造器
a=newint[max];
publicvoidinsert(intvalue)//插入数据到数组中
//数据项增1
publicvoidbubbleSort()
intout,in;
for(out=nElems-1;
out>
1;
out--)
for(in=0;
in<
out;
in++)
if(a[in]>
a[in+1])//若第in个数大于第in+1个数,则
swap(in,in+1);
//交换这两个数据
privatevoidswap(intone,inttwo)
doubletemp=a[one];
a[one]=a[two];
//实现交换
a[two]=temp;
}//endclassArrayBub
classBubbleSortDemo{
ArrayBubarr;
arr=newArrayBub(maxSize);
System.out.println("
arr.bubbleSort();
//进行冒泡排序
}//endclassBubbleSortDemo
在main()方法中通过调用方法insert(doublevalue)插入了8个数,然后调用方法bubbleSort()进行排序,display()方法用来输出数据,其结果输出如图6-2所示。
图6-2【例6.2】的运行结果
在程序中,swap(intone,inttwo)方法用来交换下标为one与下标为two的两个数的位置,其中用临时变量temp暂存数据。
冒泡排序的一种改进方法是,在排序过程中,记下每次扫描时最后依次交换序列中的数发生的下标,显然,低于此下标的数都已排好了序,因而,扫描在此数位置处终止,而不必进行到预先确定的下限。
3、选择排序
选择排序(SelectSort)的基本思想也是把数据序列划分成两个子序列,一个子序列是已经排好序的数据,另一个子序列中是尚未排序的数据。
程序开始时有序子列为空,而无序子列包含了全体数据。
从无序子列中选择一个合适的数据,例如,选择无序子列中的最小数据放到有序子列中,这样有序子列长度增长一,而无序子列减少一,这就是一次选择过程。
重复这个选择过程,每次都在无序子列剩余的未排序数据中选择最小的一个放在有序子列的尾部,使得有序子列不断增长而无序子列不断减少,最终无序子列减少为空,所有的数据都在有序子列中按要求的顺序排列,整个排序的操作也就完成了。
【例6.3】选择排序
/*ProgramnameSelectSortDemo.java
一个选择排序的例子
classArraySel
publicArraySel(intmax)//构造器
publicvoidselectionSort()
intout,in,min;
for(out=0;
nElems-1;
out++)//outerloop
min=out;
//选择最小数
for(in=out+1;
in++)//innerloop
if(a[in]<
a[min])//若a[min]大于a[in]
min=in;
//则得到一个更小的数
swap(out,min);
//且交换之
}//endfor(outer)
}//endselectionSort()
}//endclassArraySel
classSelectSortDemo{
ArraySelarr;
arr=newArraySel(maxSize);
;
arr.selectionSort();
}//endclassSelectSortDemo
在main()方法中通过调用方法insert(doublevalue)插入了8个数,然后调用方法selectionSort()进行排序,display()方法用来输出数据,其结果输出如图6-3所示。
图6-3【例6.3】的运行结果
上面介绍的几种排序算法各有特点,其中插入排序最简单,当序列中的数“基本有序”或n值较小时,它是最佳的排序方法,因此长将它和其它的排序方法结合在一起使用。
冒泡排序适合于排序数据数目不是很多的情况,但是它的操作代价较高,如果有N个数据参加排序,则使用冒泡算法的运算次数是N3数量级的量;
选择排序和插入排序两个算法的代价比冒泡算法低一个数量级,运算次数在N2数量级。
除了上述讲的三种方法外,还有其它许多种排序方法,例如快速排序、归并排序、堆排序等。
6.1.2查找
查找(Searching)是根据给定的某个值,在一个数据集合或数据序列中确定一个其关键字等于给定值的数据元素。
若数据集合或数据序列中存在这样的一个数据元素,则称查找是成功的,此时查找的结果为给出整个数据元素的信息,或指示该数据元素在数据集合或数据序列中的位置;
若数据集合或数据序列中不存在关键字等于给定值的数据元素,则称查找不成功。
例如,表6-1为某学生自然班情况,学生的学号为关键字。
假设给定值为20020115,则通过查找可得该学生的姓名、性别等,此时查找是成功的。
若给定值为20020136,则由于表中没有关键字为20020136的记录,则查找不成功。
表6-1学生自然班情况
学号
姓名
性别
籍贯
其它
┇
20020115
李明
男
北京
20020116
刘丽
女
江西
由于查找需要处理大量的数据,所以查找过程可能会占用较多的系统时间和系统内存;
为了提高查找操作的效率,需要精心设计查找算法来降低执行查找操作的时间和空间代价。
较常用的查找算法有顺序查找、折半查找等。
1、顺序查找
顺序查找(SequentialSearch)是最简单的查找算法,它的查找过程为:
从数据序列的第一个数据开始,若某个关键字和给定值比较相等,则查找成功;
反之,若直至最后一个数据,其关键字和给定值比较都不等,则表明数据序列中没有所查关键字,查找不成功。
顺序查找对于数据序列没有特殊的要求,这个序列可以是排好序的,也可以是未排好序的,对于查找操作都没有影响。
在数据序列中数据数目不多时,使用顺序查找非常方便。
当然,顺序查找也可以从数据序列的最后一个数据开始。
【例6.4】顺序查找
/*ProgramnameSqSearch.java
一个顺序查找的例子
publicclassSqSearch{
//数据数组
publicstaticint[]data={50,32,63,97,75,13,26,45};
publicstaticvoidmain(String[]args)
{if(sequence(63))//查找63
Thedata63found."
else
Thedata63nofound!
if(sequence(25))//查找25
Thedata25found."
Thedata25nofound!
publicstaticbooleansequence(intkey){
inti;
//数组下标变量
for(i=0;
i<
8;
i++)
System.out.print("
["
+data[i]+"
]"
//输出数据
if(key==data[i]){//若查找到数据
System.out.println("
returntrue;
//则返回true
}
returnfalse;
//否则返回false
}
输出结果如图6-4所示。
图6-4【例6.4】的运行结果
2、折半查找
如果数据序列中有N个数据,顺序查找的运算次数是N的数量级,如果N很大,使用顺序查找的代价也相应增大;
如果希望大幅度降低运算次数,可以考虑使用折半查找算法。
使用折半查找要求数据序列必须是已经排好序(升序、降序均可)的有序序列。
折半查找(BinarySearch)的查找过程是:
先确定待查关键字所在的范围(区间),然后逐步缩小范围直到找到或找不到该关键字为止。
它先让待查关键值与有序序列中间的一个数据比较,并利用这个中间数据把有序序列划分成一前一后两个子列;
如果待查关键值大于中间数据,说明序列中如果存在欲查找的数据,那么这个数据必然保存在后一个子列中,因为只有这个子列中的所有数据都大于中间数据;
相反,如果待查关键值小于中间数据,说明欲查找的数据存在于前一个子列中。
这样,通过一次比较,把查找的范围缩小了一半,从整个序列变成一个子列。
同理,继续使用对分方法不断划分更小的子列,缩小查找范围,直至目标子列中只剩余了一个数据;
如果这个数据与待查关键值相匹配,则查找成功;
否则说明原来的整个数据序列中并不存在一个与待查关键值相匹配的数据,查找失败。
例如,已知一组有序序列如下所示:
现要查找数据63和25。
假设指针low和high分别指示待查元素所在范围的下界和上界,指针mid指示区间的中间位置,即mid=(low+high)/2,在本例中,low和high的初值分别为0及7,mid=7/2=3(取不大于该数的最大整数)。
查找数据63的过程如下:
步骤1:
63>
data[3]=45,则low=mid+1=3+1=4,high=7,mid=(4+7)/2=5。
步骤2:
63=data[5],找到数据。
查找数据25的过程如下:
25<
data[3],则low=0,high=mid-1=3-1=2,mid=(0+2)/2=1。
data[1],则low=0,high=mid-1=1-1=0,mid=0。
步骤3:
25>
data[0],则low=mid+1=0+1=1,high=0,因为low>
high,所以未能找到数据。
【例6.5】折半查找
/*ProgramnameBSearch.java
一个折半查找的例子
publicclassBSearch{
publicstaticintmax=8;
publicstaticint[]data={13,26,32,45,50,63,75,97};
publicstaticintcounter=1;
//计算查找的次数的变量
{
for(inti=0;
System.out.print("
//换行
if(BinarySearch(63))//查找63
Searchtime="
+counter);
if(BinarySearch(25))//查找25
publicstaticbooleanBinarySearch(intkey){
intlow;
//下界
inthigh;
//上界
intmid;
//中间位置
low=0;
high=max-1;
while(low<
=high)
{
mid=(low+high)/2;
if(key<
data[mid])//待查找值较小
high=mid-1;
//查找前半段
elseif(key>
data[mid])//待查找值较大
low=mid+1;
//查找后半段
elseif(key==data[mid]){//查找到数据
System.out.println("
data["
+mid+"
]="
+data[
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第6章 常用算法与数据结构 副本 常用 算法 数据结构