排序(Sorting),就是把一组记录(元素)按照某个域的值的递增或递减的次序重新排列的过程。通常把用于排序的域称为排序域或排序项,把该域中的每一个值(它与一个记录相对应)称为排序码。
一组记录按排序的递增或递减次序排列得到的结果称之为有序表。相应地,把排序前的状态称为无序表。递增次序又称为升序或正序,递减次序又称为降序、逆序或反序。若有序表是按排序码升序排列的,则称为升序表或正序表,若按相反次序排列,则称为降序表或逆序表。
这里先学习一下以下几种排序:插入排序(Insertion Sorting)、直接选择排序(Straight
Select Sorting)、冒泡排序(Bubble Sorting)、快速排序(QuickSorting)。
1、插入排序(Insertion Sorting)
是一种对线性表(数组)进行排序的简单排序方法。
插入排序算法如下:
1)
把线性表list[0]~list[n-1]中共n个元素看做一个有序表和一个无序表,开始时有序表中只有一个元素list[0](一个元素自然有序),无
序表中包含有n-1个元素list[1]~list[n-1]。
2) 把无序表中的第一个元素暂存入x。
3)
从有序表表尾元素list[i-1]开始,依次向前使每一个元素list[j](0<=j<=i-1)同暂存入x的元素值进行比较,若x
后移一个位置,直到x>=list[j]或j<=0为止,此时已空出的下标为j+1的位置就是x的插入位置,把x的值插入到list[j+1]即可。
4) 上步完成后,有序表增加了一个元素,无序表减少了一个元素。
5)重复第2-第4步,经过n-1次后,有序表中包含n个元素,无序表变为一个空表,整个排序结束。
插入排序算法特点:
a) 稳定性强,相同值位置不发生改变。
b) 排序时间长。
比较次数 移动次数
Cmin=n-1 Mmin=2(n-1)
Cmax=1/2n(n-1) Mmax=1/2(n的平方+3n-4)
Cave=1/4(n的平方+n-2) Mave=1/4(n的平方+7n-8)
在最好情况下的时间复杂度为O(n),在平均和最差情况下的时间均为O(n的平方)。
//插入排序实例
import java.util.Arrays;
class InsertionSorting {
public static void main(String[] args) {
int[] arraysSource = {27, 8,
57, 23,9};//, 41, 65, 19, 0, 1, 2, 4, 5};
insertionSorting(arraysSource,
0, arraysSource.length-1); //对整个数组进行排序,排序范围可以改变。
System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
System.out.println(Arrays.toString(arraysSource));
}
public static void insertionSorting(int[] a, int
from, int to) {
int j ; //为有序表参与的当前元素下标
int x;//用来暂存当前无序表中第一个元素的值
for (int k = from+1; k
<= to; k++){
x =
a[k];//把无序表中第一个元素的值暂存
//从有序表的表尾向前顺序与x比较,若小于则向后移动,循环到不小于x的元素或排序区域的第一个元素。
for( j = k -
1 ; j>=0 ; j--)
if(x
a[j+1]
= a[j] ;
System.out.println(
Arrays.toString(a) + " j:" + j );}
else
break;//当前有序表元素值不小于x,退出与当前无序表元素的比较
a[j+1] =
x;
System.out.println("---------------------------------");
System.out.println(
Arrays.toString(a) + " K:" +k +" x:" +x );
System.out.println("");
}
}
}
2、直接选择排序(Straight Select Sorting)
一种简单的排序方法。它每次从待排序的区间中选择出具有最小排序码的元素,把该元素与该区间的第一个元素交换位置。
直接选择排序算法如下:
1)第一次待排序包含所有元素A[0]~A[n-1],经过选择和交换后,A[0]为具有最小排序码的元素;
2)第二次待排序区间为A[1]~A[n-1],经过选择和交换后,aA[1]为仅次于A[0]的具有最小排序码的元素;
3)第三次待排序区间为A[2]~A[n-1],经过选择和交换后,aA[2]为仅次于A[0]和A[1]的具有最小排序码的元素;
4)依次类推,经过n-1次选择和交换后,A[0]~A[n-1]就成为了有序表,排序结束。
直接选择排序特点:
a) 稳定性强,相同值位置不发生改变。
b) 排序时间长,但是当记录占用的字节数较多时,通常它比直接插入排序执行速度快些。
比较次数 移动次数
Cmin=n-1 Mmin=0
Cmax=1/2n(n的平方-n) Mmax=3(n-1)
时间复杂度为0(n的平方),移动记录的总次数为O(n)。
//直接选择排序实例
import java.util.Arrays;
class StraightSelectSorting {
public static void main(String[] args) {
int[] arraysSource = {27, 8,
57, 9, 23, 41, 65, 19, 0, 1, 2, 4, 5};
straightSelectSort(arraysSource,
0, arraysSource.length-1);
System.out.println("---------------------------------");
System.out.println(Arrays.toString(arraysSource));
}
public static void straightSelectSort(int[] a,
int from, int to) {
int i ;
//存储当前最小排序码元素下标,初值为排序域第一个元素下标
int min;//交换中介
for (int k = from; k
<= to; k++){//k表示次数,共进行to次选择和交接
i = k;
//从当前排序区间中顺序查找出具有最小排序码的元素a[j]
for(int j =
i+1; j<=to;j++) if (a[j]