目录
交换排序:
基本思想:
两两比较待排序的数,一旦两个数不满足次序要求则进行交换,直到整个序列满足要求(及有序)为止。而交换排序大致为以下两种:1:冒泡排序.2:快速排序.
1:冒泡排序:
基本思想:
冒泡排序是最简单的一种交换排序方法,它通过两两比较相邻的数,如果发生逆序,则两两交换,从而使得小数如气泡般向上逐渐“飘出”(左移),大数如石块一样向下逐渐“坠落”(右移)。
过程:
先看一张演示图:
不难看出,从第一个数开始进行两两比较交换,第一次可获得最大数,在数组最后一位,然后进行第二次两两比较,以此类推。
代码实现:
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] a={2,6,3,8,1,4,2,7};
Bubblesort(a);
}
public static void Bubblesort(int[] s){
int a=s.length-1;//记录需要比较的数组长度
int flag=1;//判断是否发生交换,1为发生交换,2为未发生交换
while(a>0&&flag==1){//未发生交换或者数组长度小于等于0,都说明了数组已经排序为有序数组
flag=0;//先将flag设置为未交换
for (int i=1;i<=a;i++) {
if (s[i] < s[i - 1]) {//将大数往后移动
int temp = s[i];
s[i] = s[i - 1];
s[i - 1] = temp;
flag = 1;//发生交换,设置为1
}
}
--a;//第一趟交换完成后,最大数已经排至最后,所以将需要交换排序的数组长度减一
}
System.out.println(Arrays.toString(s));//输出排好序的数组
}
}
结果:
时间复杂度:
空间复杂度:
算法特点:
(1):稳定排序。
(2):移动次数较多,当初始记录无序,n较大时,不宜采用。
2:快速排序:
基本思想:
快速排序是由冒泡排序改进而来。快速排序方法中可以一次交换消除多个逆序,比冒泡排序一次交换只能消除一个逆序速度更快。
过程:
上图:
在快速排序中先选出一个关键字pivotkey(也就是一个数)然后以数组开头low和数组末尾high同时与关键字进行比较。
low所指数大于关键字则停止移动,high所指数小于关键字则停止移动,交换low和high所指向的数,直到low=high,再将关键字与low与high汇合点所指向的数交换。
这样完成第一次排序,关键字左边全是小于它的数,右边全是大于它的数。再对左子数组和右子数组进行相同排序(递归调用相同方法),直到排序完成(子表长度等于1)。
代码实现:
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] a={2,6,3,8,1,4,2,7};
Quicksort(a,0,a.length);//调用方法,第一次begin默认为0,第一次end默认为数组长度
System.out.println(Arrays.toString(a));//输出排序完成的数组
}
public static void Quicksort(int[] s,int begin,int end) {
end=end-1;//防止数组下标溢出
if (begin<end) {//判断数组长度是否大于1
int temp = s[begin];//取第一个数为初始关键字
int i = begin;
int j = end;
while (i < j) {//循环直到i不小于j
//必须先找j,先找i会排序失败,这样的优点是可以减少比较次数
while (s[j] >= temp && j > i) {//循环直到找到小于关键字的数
j--;//end减一
}
while (s[i] <= temp && j > i) {//循环直到找到大于关键字的数
i++;//begin加一
}
if (j > i) {//判断end是否在begin后面,在则交换两个位置所含数字
int t = s[i];
s[i] = s[j];
s[j] = t;
}
}
s[begin] = s[i];//将关键字与s[i]交换,这样关键字左边都是小于它的数,右边都是大于它的数(此时i=j)
s[i] = temp;
Quicksort(s, begin, i);//递归求左子数组(因为每次递归第一条语句会让end-1,所以使用i而不使用i-1)
Quicksort(s, i + 1, end + 1);//递归求右子数组
}
}
//另一种普通方法:
public static void Quicksort1(int[] s,int begin,int end) {
end=end-1;//防止数组下标溢出
if (begin<end) {//判断数组长度是否大于1
int temp = s[begin];//取第一个数为初始关键字
int i = begin;
int j = end;
while (i<j) {//循环直到i不小于j
//这一种方法先找i或先找j都可
/*while (s[j] >= temp) {//循环直到找到小于关键字的数
j--;//end减一
}*/
while (s[i] <= temp) {//循环直到找到大于关键字的数
i++;//begin加一
}
while (s[j] >= temp) {//循环直到找到小于关键字的数
j--;//end减一
}
if (j > i) {//判断end是否在begin后面,在则交换两个位置所含数字
int t = s[i];
s[i] = s[j];
s[j] = t;
}
}
s[begin] = s[j];//将关键字与s[i]交换,这样关键字左边都是小于它的数,右边都是大于它的数(这里i,j不一定相等)
s[j] = temp;
System.out.println(Arrays.toString(s));
Quicksort(s, begin, j);//递归求左子数组
Quicksort(s, j + 1, end + 1);//递归求右子数组
}
}
}
结果:
时间复杂度:
空间复杂度:
算法特点:
(1):不稳定排序。
(2):适合初始记录无序,n较大情况。