Java实现八大排序算法,以及这些排序算法时间复杂度、空间复杂度、稳定性等比较

Java实现八大排序算法,以及这些排序算法时间复杂度、空间复杂度、稳定性等比较

冒泡排序

	public void sort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int temp = 0;
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

选择排序

	public void sort(int[] arr) {
        int min = -1;
        int temp = -1;
        for (int i = 0; i < arr.length; i++) {
            min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            if (min != i) {
                temp = arr[i];
                arr[i] = arr[min];
                arr[min] = temp;
            }
        }
    }

插入排序

	public static void sort(int[] arr) {
    	int n = arr.length;
    	for (int i = 1; i < n; ++i) {
        	int value = arr[i];
        	int j = 0;//插入的位置
        	for (j = i-1; j >= 0; j--) {
            	if (arr[j] > value) {
                	arr[j+1] = arr[j];//移动数据
            	} else {
                	break;
            	}
        	}
        	arr[j+1] = value; //插入数据
    	}
	}

希尔排序

	public static void shellSort(int[] arr) {
        int length = arr.length;
        int gap = 1;
        while (gap < length) {
            gap = gap * 3 + 1;
        }
        while (gap > 0) {
            for (int i = gap; i < length; i++) {
                int value = arr[i];
                int index = -1;
                int j = i - gap;
                for (; j >= 0; j = j - gap) {
                    if (value < arr[j]) {
                        arr[j + gap] = arr[j];
                        index = j;
                    } else {
                        break;
                    }
                }
                arr[j + gap] = value;
            }
            gap = gap / 3;
        }
    }

归并排序

	public void mergeSort(int[] arr, int start, int end) {
        if (start < end) {
            int mid = (start + end) / 2;
            // 分治
            mergeSort(arr, start, mid);
            // 分治
            mergeSort(arr, mid + 1, end);
            // 归并
            merge(arr, start, mid, end);
        }
    }

    public void merge(int[] arr, int start, int mid, int end) {
        int[] newArr = new int[end - start + 1];
        int index = 0, i = start, j = mid + 1;
        while (i <= mid && j <= end) {
            newArr[index++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
        }
        while (i <= mid) {
            newArr[index++] = arr[i++];
        }
        while (j <= end) {
            newArr[index++] = arr[j++];
        }
        index = 0;
        while (start <= end) {
            arr[start++] = newArr[index++];
        }
    }

快速排序

	public void quickSort(int[] arr, int start, int end) {
        if (start < end) {
            int pivotPos = partition(arr, start, end);
            quickSort(arr, start, pivotPos - 1);
            quickSort(arr, pivotPos + 1, end);
        }
    }

    public int partition(int[] arr, int start, int end) {
        int pivot = arr[start];
        while (start < end) {
            while (start < end && arr[end] >= pivot) {
                end--;
            }
            arr[start] = arr[end];
            while (start < end && arr[start] <= pivot) {
                start++;
            }
            arr[end] = arr[start];
        }
        arr[start] = pivot;
        return start;
    }

大根堆排序(或者小根堆排序)

	// 主函数
	public static void main(String[] args) {
        int[] arr = new int[]{5,4,8,3,6,2,1,7};
        buildMaxHeap(arr);
        int length = arr.length;
        for (int i = length - 1; i >= 0; i--) {
            // 每一趟形成一个大根堆,然后将根节点排出,将根节点排出得方法是每一趟置换最后一个元素和第一个元素,其余结点继续构建大根堆,以此循环
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            length--;
            sink(arr, 0, length);
        }
    }

	// 构建大根堆	
	public static void buildMaxHeap(int[] arr) {
        for (int i = arr.length / 2; i >= 0; i--) {
            sink(arr, i, arr.length);
        }
    }
	
	// 把大的元素向上浮动,小的元素向下沉
    public static void sink(int[] arr, int index, int length) {
        int leftChild = 2 * index + 1;
        int rightChild = 2 * index + 2;
        int present = index;
        if (leftChild < length && arr[leftChild] > arr[present]) {
            present = leftChild;
        }
        if (rightChild < length && arr[rightChild] > arr[present]) {
            present = rightChild;
        }
        if (present != index) {
            int temp = arr[present];
            arr[present] = arr[index];
            arr[index] = temp;
            // 关键步骤,每次交换之后,得确保子树也是大根堆,因此要继续向下沉
            sink(arr, present, length);
        }
    }

基数排序

基数排序的思想:即桶排序。先按照每个数的各位排序,并放在0-9的桶中,排成一个新的序列;然后再将新的序列按照十位排序,并放入桶中,再形成一个新的序列。然后依次排序百位,千位,直到所有数字位数都用尽,最终序列就是排好序的序列。

public void bucketSort(int[] arr) {
        // 记录最大值
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] >= max) {
                max = arr[i];
            }
        }
        // 构建10个桶,0-9用来装数字
        ArrayList<ArrayList<Integer>> list = new ArrayList();
        for (int i = 0; i < 10; i++) {
            list.add(new ArrayList());
        }
        // 当前排序位置
        int location = 1;
        while (true) {
            int dd = (int)Math.pow(10, location - 1);
            if (dd > max) {
                break;
            }
            // 数据入桶
            for (int i = 0; i < arr.length; i++) {
                int index = (arr[i] / dd) % 10;
                list.get(index).add(arr[i]);
            }
            // 写回数组
            int k = 0;
            for (int i = 0; i < 10; i++) {
                int size = list.get(i).size();
                for (int ii = 0; ii < size; ii++) {
                    arr[k++] = list.get(i).get(ii);
                }
                list.get(i).clear();
            }
            location++;
        }
    }

=====================================================================

八大排序算法比较:

=====================================================================

排序名称 最好情况 平均情况 最坏情况 空间复杂度 是否稳定
插入排序 O(n) O(n^2) O(n^2) O(1)
冒泡排序 O(n) O(n^2) O(n^2) O(1)
选择排序 O(n^2) O(n^2) O(n^2) O(1)
希尔排序 O(1)
快速排序 O(nlogn) O(nlogn) O(n^2) O(n)或者O(logn)
堆排序 O(nlogn) O(nlogn) O(nlogn) O(1)
归并排序 O(nlogn) O(nlogn) O(nlogn) O(n)
基数排序 O(d(n + r)) O(d(n + r)) O(d(n + r))

你可能感兴趣的:(#,剑指offer中不熟悉的题)