Java数组排序.docx
《Java数组排序.docx》由会员分享,可在线阅读,更多相关《Java数组排序.docx(10页珍藏版)》请在冰豆网上搜索。
Java数组排序
Java数组排序
学习目的:
不是为了在工作中使用(这三个算法性能不高),而是为了练习for循环和数组
在工作中JavaAPI提供了现成的优化的排序方法,效率很高,以后工作中直接使用即可
选择排序、冒泡排序、插入排序等排序算法在公司笔试题中会经常出现,所以是很有必要掌握的
选择排序原理:
✓将数组中每个元素与第一个元素比较,如果这个元素小于第一个元素,则交换这两个元素
✓循环第1条规则,找出最小元素,放于第1个位置
✓经过n-1轮比较完成排序
简单而言,每轮都找到最小的放到前面。
例:
{8,2,3,7,1}的排序过程如下所示:
数组:
ary={8,2,3,7,1}
第1轮:
ary={1|8,3,7,2}
第2轮:
ary={1,2|8,7,3}
第3轮:
ary={1,2,3|8,7}
第4轮:
ary={1,2,3,7|8}
第5轮:
ary={1,2,3,7|8}
过程分析:
✓i代表第一个数据的位置
✓j代码后部每一个数据的位置
ary
i
j
ary[i]
ary[j]
ary[i]>ary[j]
[i]交换[j]
第1轮
{8|2,3,7,1}
[0]
[1]
8
2
true
8<->2
{2|8,3,7,1}
[0]
[2]
2
3
false
--
{2|8,3,7,1}
[0]
[3]
2
7
false
--
{2|8,3,7,1}
[0]
[4]
2
1
true
2<->1
{1,8|3,7,2}
第2轮
{1,8|3,7,2}
[1]
[2]
8
3
true
8<->3
{1,3|8,7,2}
[1]
[3]
3
7
false
--
{1,3|8,7,2}
[1]
[4]
3
2
true
3<->2
{1,2,8|7,3}
第3轮
{1,2,8|7,3}
[2]
[3]
8
7
true
8<->7
{1,2,7|8,3}
[2]
[4]
7
3
true
7<->3
{1,2,3,8|7}
第4轮
{1,2,3,8|7}
[3]
[4]
8
7
true
8<->7
{1,2,3,7|8}
第5轮
{1,2,3,7,8|}
[4]
--
8
--
--
--
1.2.冒泡排序**
冒泡排序原理:
✓比较相邻的元素,将小的放到前面。
依次比较相邻的两个数,将小数放在前面,大数放在后面。
即在第一趟:
首先比较第1个和第2个数,将小数放前,大数放后。
然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
至此第一趟结束,将最大的数放到了最后。
在第二趟:
仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。
如此下去,重复以上过程,直至最终完成排序。
由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。
用二重循环实现,外循环变量设为i,内循环变量设为j。
外循环重复9次,内循环依次重复9,8,...,1次。
每次进行比较的两个元素都是与内循环j有关的,它们可以分别用a[j]和a[j+1]标识,i的值依次为1,2,...,9,对于每一个i,j的值依次为1,2,...10-i。
冒泡排序例:
{8,2,3,7,1}的排序过程如下所示:
ary={8,2,3,7,1}
ary={2,8,3,7,1}
ary={2,3,8,7,1}
ary={2,3,7,8,1}
ary={2,3,7,1|8}
ary={2,3,7,1|8}
ary={2,3,7,1|8}
ary={2,3,1|7,8}
ary={2,3,1|7,8}
ary={2,1|3,7,8}
ary={1,2,3,7,8}
过程分析:
✓i代表次数
✓j代表比较位置
ary
i
j
j+1
ary[j]
ary[j+1]
ary[j]>ary[j+1]
[j]交换[j+1]
{8,2,3,7,1}
0
[0]
[1]
8
2
true
8<->2
{2,8,3,7,1}
0
[1]
[2]
8
3
true
8<->3
{2,3,8,7,1}
0
[2]
[3]
8
7
true
8<->7
{2,3,7,8,1}
0
[3]
[4]
8
1
true
8<->1
{2,3,7,1|8}
1
[0]
[1]
2
3
false
--
{2,3,7,1|8}
1
[1]
[2]
3
7
false
--
{2,3,7,1|8}
1
[2]
[3]
7
1
true
7<->1
{2,3,1|7,8}
2
[0]
[1]
2
3
false
--
{2,3,1|7,8}
2
[1]
[2]
3
1
true
3<->1
{2,1|3,7,8}
3
[0]
[1]
2
1
true
2<->1
{1,2,3,7,8}
备注:
✓i的取值范围是:
i=0~✓j的取值范围是:
j=0~✓交换步骤伪代码如下:
if([j]>[j+1]){[j]<->[j+1]}
1.3.插入排序**
在开始学习插入排序之前,让我们先对for循环做个补充:
如下是关于for循环结束时,i的取值的
插入排序原理:
✓将数组分为两部分,将后部分的第一个逐一与前部分每一个元素比较,在合理位置插入
✓插入排序算法效率要高于选择排序和冒泡排序
假定一个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止.这具算法在排完前k个数之后,可以保证a[1…k]是局部有序的,保证了插入过程的正确性.
一般来说,插入排序都采用in-place在数组上实现。
具体算法描述如下:
1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果该元素(已排序)大于新元素,将该元素移到下一位置
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5.将新元素插入到下一位置中
6.重复步骤2
插入排序例:
{8,2,3,7,1}的排序过程如下所示:
第1步,假设第一个元素是已排序的{8|2,3,7,1}
第2步,用2和"|"之前的所有元素比较,幵插入{8|2,3,7,1}取出2(temp=2)temp和8比,比8小,将2的位置赋值为大数(ary[1]=8){8|8,3,7,1}因为已到边界,直接赋值(ary[0]=2){2,8|3,7,1}2和8排序完成
第3步,用3和"|"之前的所有元素比较,幵插入{2,8|3,7,1}取出3(temp=3)temp和8比,比8小,3的位置赋值给大数(ary[2]=8){2,8|8,7,1}temp和2比,比2大,插入2后面(ary[1]=3){2,3,8|7,1}3、2、8排序完成
第4步,用7和"|"之前的所以元素比较,幵插入{2,3,8|7,1}取出7(temp=7)temp和8比,比8小,7的位置赋值给大数(ary[3]=8){2,3,8|8,1}temp和3比,比3大,插入3后面(ary[2]=7){2,3,7,8|1}7、2、3、8排序完成
第5步,用1和"|"之前的所以元素比较,幵插入{2,3,7,8|1}取出1(temp=1)temp和8比,比8小,1的位置赋值给大数8{2,3,7,8|8}temp和7比,比7小,8的位置赋值给大数7{2,3,7,7|8}temp和3比,比3小,7的位置赋值给大数3{2,3,3,7|8}temp和2比,比2小,3的位置赋值给大数2{2,2,3,7|8}到边界,赋值(ary[0]=1){1,2,3,7,8|}1、2、3、7、8排序完成
过程分析:
✓temp代表取出待插入的元素
✓i代表后组待插入元素的位置
✓j代表前组每个元素的位置
ary
i
temp
j
ary[j]
temp[j]移动j+1]
t插入j+1]
{8|2,3,7,1}
[1]
2
[0]
8
true
8->[j+1]
--
{8|8,3,7,1}
[1]
2
[-1]
--
--
--
2->[j+1]
{2,8|3,7,1}
[2]
3
[1]
8
true
8->[j+1]
--
{2,8|8,7,1}
[2]
3
[0]
2
false
--
3->[j+1]
{2,3,8|7,1}
[3]
7
[2]
8
true
8->[j+1]
--
{2,3,8|8,1}
[3]
7
[1]
3
false
--
7->[j+1]
{2,3,7,8|1}
[4]
1
[3]
8
true
8->[j+1]
--
{2,3,7,8|8}
[4]
1
[2]
7
true
7->[j+1]
--
{2,3,7,7|8}
[4]
1
[1]
3
true
3->[j+1]
--
{2,3,3,7|8}
[4]
1
[0]
2
true
2->[j+1]
--
{2,2,3,7|8}
[4]
1
[-1]
--
--
--
1->[j+1]
{1,2,3,7,8|}
[5]
--
--
--
--
--
--
备注:
✓i的取值范围是:
i=1~✓j的取值范围是:
j=i-1~>=0,j--j--
✓伪代码如下:
temp=[i];if(temp<[j]){[j]->[j+1]//移动}else{breakj;}temp->[j+1];//插入