本文为慕课网实战课程《算法与数据结构》学习笔记
基础排序算法O(n^2)
选择排序
在剩下未排序的数里选择最小的排序
i向前,j在i+1~n内比较
时间复杂度 O ( n 2 ) O(n^2) O(n2)
public static void sort(Comparable[] arr){
int n = arr.length;
for( int i = 0 ; i < n ; i ++ ){
// 寻找[i, n)区间里的最小值的索引
int minIndex = i;
for( int j = i + 1 ; j < n ; j ++ )
if( arr[j].compareTo( arr[minIndex] ) < 0 )
minIndex = j;
swap( arr , i , minIndex);
}
}
插入排序及优化
类似扑克摸牌插牌过程,新数与之前的数比较
i每次往前,j向后(backward)比较
public static void sort(Comparable[] arr){
int n=arr.length;
for (int i = 1; i < n ; i++) {
// j与j-1相比,向后比较
for(int j=i;j>0; j--) {
if (arr[j].compareTo(arr[j-1]) < 0)
sort.swap( arr , j , j-1);
else
break;
}
}
}
优化1:减少交换次数
记录i,比j大的右移
public static void sort(Comparable[] arr){
int n=arr.length;
for (int i = 1; i < n ; i++) {
// 保存当前副本
Comparable temp=arr[i];
// 只交换1次,其余赋值
int j;
for( j = i; j > 0 && arr[j-1].compareTo(temp)>0 ; j--) {
arr[i]=arr[j-1];
}
arr[j]=temp;
}
}
优化2:记录最大最小值,减少比较次数
分成左右两部分及记录最大最小值
左右窗口渐渐缩小
public static void sort(Comparable[] arr){
int left = 0, right = arr.length - 1;
while(left < right){
int minIndex = left;
int maxIndex = right;
// 在每一轮查找时, 要保证arr[minIndex] <= arr[maxIndex]
if(arr[minIndex].compareTo(arr[maxIndex]) > 0)
sort.swap(arr, minIndex, maxIndex);
// i向右移动,时刻比较与最大最小值的比较大小
for(int i = left + 1 ; i < right; i ++) {
if (arr[i].compareTo(arr[minIndex]) < 0)
minIndex = i;
else if (arr[i].compareTo(arr[maxIndex]) > 0)
maxIndex = i;
}
sort.swap(arr, left, minIndex);
sort.swap(arr, right, maxIndex);
left ++;
right --;
}
}
冒泡排序及优化
每一次循环中最大的放末位。窗口缩小
public static void sort(Comparable[] arr){
int n =arr.length;
//边界问题
for (int i = 0; i < n-1 ; i++) {
for (int j = 0; j < n-i-1 ;j++){
if(arr[j].compareTo(arr[j+1])>0)
sort.swap(arr,j,j+1);
}
}
优化:改进循环
//优化了n
public static void sort(Comparable[] arr){
int n =arr.length;
boolean swap=false;
do {
for (int i = 1; i < n - 1; i++) {
if (arr[i - 1].compareTo(arr[i]) > 0) {
sort.swap(arr, i - 1, i);
swap=true;
}
}
n--;
}while (swap);
}
希尔排序及优化
分组([i]与[i+h]、[i+2h]…为一组)、有增量(h)的插排。增量递减,为1时停止。
public static void sort(Comparable[] arr){
int n=arr.length;
int gap=2;//增量的比例
int h=1;
while (h<n/gap)
h=gap*h+1;
while(h>0) {
for (int i = h; i < n; i++) {
// 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
for (int j = i; j >= h; j = j - h) {
// 最右端往前比较
if (arr[j].