交换排序算法
交换类排序主要是通过两两比较待排序的关键字,如果发现与排序要求相逆,则进行元素交换。
1、起泡排序
- 首先比较第一个与第二个元素的关键字,如果发生逆序,则交换两个元素的位置,接着比较第二个与第三个元素,以此类推,直到比较第n-1个元素与第n个元素为止,完成了第一趟排序,此时关键字最大的元素通过交换操作放到了具有n个元素的最后一个位置上;
- 然后进行第二趟排序,将关键字次大的元素放到第n-1个位置上;
- 排序共进行了n-1趟,结束后可使得元素序列按照关键字有序,如下图所示。
代码实现:
import java.util.Arrays;
public class SwapSort {
public static void bubbleSort(int[] array) {
//外层循环设置排序趟数
for(int i=array.length-1;i>=1;i--) {
//两两元素进行比较
for(int j=0;j<=i-1;j++) {
if(array[j]>array[j+1]) {
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
System.out.println(Integer.toString(array.length-i)+":"+Arrays.toString(array));
}
System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int[] array = {26,53,48,11,13,48,32,15};
bubbleSort(array);
}
}
运行结果:
起泡排序的时间复杂度为O(n^2)。
2、快速排序
快速排序是应用了分治法的思想。
- 通过一个枢轴(pivot)元素将n个元素分为左、右两个子序列,其中左子序列的元素均比枢轴元素小,而右子序列的元素均比枢轴元素大;
- 对左、右子序列分别进行快速排序,在将左、右子序列排好序后,则整个序列有序,其中在对左右子序列的排序过程直到子序列中只包含一个元素时结束。
- 具体做法,如图所示:
- 使用两个指针low和high分别指向待划分序列的范围,low指向26,high指向15,取low所指元素为枢轴,即pivot=26;
- 划分首先从high所指位置元素起向前逐一搜索到第一个比pivot小的元素,将该元素设置到low所指的位置,该例中15比26小,因此将15设置到low的位置上;
- 然后从low所指的位置向后逐一搜索到第一个比pivot大的元素,该例中搜索到第二个元素53比26大,将53设置到high指的位置上;
- 不断重复上述两步,直到low=high位置,最后将pivot位置设置到low与high共同指向的位置。
代码实现:
import java.util.Arrays;
public class SwapSort {
//将区间序列划分为两个子序列并返回枢轴元素的位置
public static int partition(int[] array,int low,int high) {
int pivot = array[low];
while(low<high) {
while(array[high]>=pivot && low<high) {
high--;
}
array[low] = array[high];
while(array[low]<=pivot && low<high) {
low++;
}
array[high] = array[low];
}
array[low] = pivot;
System.out.println(Arrays.toString(array));
return low;
}
public static void quickSort(int[] array,int low,int high) {
System.out.println("original:"+Arrays.toString(array));
//终止条件为low=high,表明此时待划分子序列只包含一个元素
if(low<high) {
//首先进行第一次划分,获得枢轴位置
int pa = partition(array,low,high);
//对左、右子序列分别进行快速排序
quickSort(array,low,pa-1);
quickSort(array,pa+1,high);
}
System.out.println("final:"+Arrays.toString(array));
}
public static void main(String[] args) {
int[] array = {26,53,48,15,13,46,32,15};
quickSort(array,0,array.length-1);
}
}
快速排序算法的运行时间依赖于划分是否平衡,而划分平衡又依赖于枢轴元素。
最坏的情况是每次进行划分,所得到的两个子序列中其中一个子序列为空,此时快速排序的时间复杂度仍为O(n^2)。
最好的情况是每次划分,都将序列一分为二,此时快速排序的时间复杂度仍为O(nlogn)。
就平均时间而言,快速排序被认为是目前最好的一种内部排序方法。
参考
数据结构与算法(JAVA语言版—周鹏)
如有侵权,请联系