常见排序算法

137 阅读3分钟

简单排序

冒泡排序

时间复杂度为O(n^2),数量较大时,性能越低。

public static void main(String[] args) {
    Integer[] arr = {4, 3, 5,2, 1, 6};
    Bubble.sort(arr);
    System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5, 6]
}
    

public class Bubble {
    /* 排序 */
    public static void sort(Comparable[] a) {
    	// i 为每轮的最大索引, i 最小为1, 只剩一个元素是,不需要比较,因此只需			要数组长度减1轮
        for (int i = a.length - 1; i > 0; i--) {
        	// j 为每次比较的前驱元素的索引
            for (int j = 0; j < i - 1; j++) {
                if (greater(a[j], a[j + 1])) {
                    exchange(a, j, j+1);
                }
            }
        }
    }

    /* v 是否大于 w */
    public static  boolean greater(Comparable v, Comparable w) {
        return v.compareTo(w) >= 0;
    }

    /* 交换位置 */
    public static void  exchange(Comparable[] a, int i, int j) {
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

选择排序

时间复杂度为O(n^2),数量较大时,性能越低。

public static void main(String[] args) {
    Integer[] arr = {14, 23, 45,24, 31, 16};
    Selection.sort(arr);         			 	System.out.println(Arrays.toString(arr)); 
    // [14, 16, 23, 24, 31, 45]
}
   
public class Selection {
	/* 排序 */
	public static void sort(Comparable[] a) {
	    for (int i = 0; i < a.length - 1; i++) {
	        int minIndex = i;
	        for (int j = i + 1; j < a.length; j++) {
	            if (greater(a[minIndex], a[j])) {
	                minIndex = j;
	            }
	        }
	        exchange(a, minIndex, i);
	    }
	}
	
	/* v 是否大于 w */
	public static  boolean greater(Comparable v, Comparable w) {
	    return v.compareTo(w) >= 0;
	}
	
	/* 交换位置 */
	public static void  exchange(Comparable[] a, int i, int j) {
	    Comparable temp = a[i];
	    a[i] = a[j];
	    a[j] = temp;
	}
}
    

插入排序

将数据分为“已排序”和“未排序“两组 时间复杂度为O(n^2),数量较大时,性能越低。

public static void main(String[] args) {
    Integer[] arr = {98, 12, 23,1, 3, 5};
    Insertion.sort(arr); // [1, 3, 5, 12, 23, 98]
    System.out.println(Arrays.toString(arr));
}
    
/* 排序 */
public static void sort(Comparable[] a) {
    for (int i = 1; i < a.length; i++) {
        for (int j = i; j > 0; j--) {
            if (greater(a[j-1], a[j])) {
                exchange(a, j-1, j);
            }else {
                break;
            }
        }
    }
}

高级排序

希尔排序(插入排序升级版)

public static void main(String[] args) {
    Integer[] arr = {8, 12, 23,1, 3, 5, 7};
    Shell.sort(arr);
    // [1, 3, 5, 7, 8, 12, 23]
    System.out.println(Arrays.toString(arr));
}
    
public static void sort(Comparable[] a) {
    // 确定希尔增量 h
    int len = a.length;
    int h = 1;
    while (h < len / 2 ) {
        h = h * 2 + 1;
    }

    while (h >= 1) {
        for (int i = h; i < len; i++) {
            for (int j = i; j >= h; j-=h) {
                if (greater(a[j-h], a[j])) {
                    exchange(a, j-h, j);
                }else {
                    break;
                }
            }
        }
        h = h / 2;
    }
 }

归并排序(递归思想,分治思想)

需要额外创建数组来辅助排序,增加空间复杂度,以空间换时间

public static void main(String[] args) {
    Integer[] arr = {8, 212, 2323,41, 43, 5, 7};
    Merge.sort(arr);
    // [5, 7, 8, 41, 43, 212, 2323]
    System.out.println(Arrays.toString(arr));
}
    
public class Merge {
    private static Comparable[] temp;

    public static void sort(Comparable[] a) {
        temp = new Comparable[a.length];
        int right = a.length - 1;
        int left = 0;
        sort(a, left, right);
    }

    public static void sort(Comparable[] a, int left, int right) {
        if (left < right) {
            int mid = left + (right - left)/2;
            sort(a, left, mid);
            sort(a, mid + 1, right);
            merge(a, left, mid, right);
        }
    }

    public static void merge(Comparable[] a, int left, int mid, int right) {
        int i = left; // 临时数组的下标
        int p1 = left; // 左边数组的下标
        int p2 = mid + 1; // 右边数组的下标

        while (p1 <= mid && p2 <= right) {
            if (less(a[p1], a[p2])) {
                temp[i++] = a[p1++];
            }else {
                temp[i++] = a[p2++];
            }
        }

        while (p1 <= mid) {
            temp[i++] = a[p1++];
        }
        while (p2 <= right) {
            temp[i++] = a[p2++];
        }

        while (left <= right) {
            a[left] = temp[left];
            left++;
        }
    }

    public static boolean less(Comparable x, Comparable y) {
        return x.compareTo(y) < 0;
    }
}

快速排序

public class Quick {
    public static void main(String[] args) {
        Integer[] a = {4, 6, 2, 8, 2, 12, 9, 25, 23};
        sort(a);
        System.out.println(Arrays.toString(a));
    }

    public static void sort(Comparable[] a) {
        int left = 0;
        int right = a.length - 1;
        sort(a, left, right);
    }

    public static void sort(Comparable[] a, int left, int right) {
        if (left < right) {
            int sep = partition(a, left, right);
            sort(a, left, sep - 1);
            sort(a, sep + 1, right);
        }
    }

    public static int partition(Comparable[] a, int left, int right) {
        Comparable key = a[left];
        int lead = left;
        int trailing = right + 1;
        while (true) {
            while (less(key, a[--trailing])) {
                if (lead == trailing) {
                    break;
                }
            }
            while (less(a[++lead], key)) {
                if (right == lead) {
                    break;
                }
            }
            if (lead >= trailing) {
                break;
            }else {
                exchange(a, lead, trailing);
            }
        }
        exchange(a, left, trailing);
        return trailing;
    }

    public static boolean less(Comparable x, Comparable y) {
        return x.compareTo(y) < 0;
    }

    public static void exchange(Comparable[] a, int t, int w) {
        Comparable temp = a[t];
        a[t] = a[w];
        a[w] = temp;
    }
}