排序算法汇总

稳定性定义:排序前后两个相等的数相对位置不变,则算法稳定。

稳定性得好处:从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。

稳定的:

  1.插入排序(O(n*n)):将一个元素插入到已经排好序的列表中

public void selectionSort(int[] a) {
    if (null ==a || a.length < 2) {
        return;
    }
    for (int i = 1; i < a.length; i++) {
        int temp = a[i]; // 暂存
        int j = i - 1;
        while (j >= 0 && temp < a[j]) {
            a[j+1] = a[j];
            j--;
        }
        a[j+1] = temp;
    }
}

  2.冒泡排序(O(n*n)):相邻两个元素比较大小进行交换,一趟冒泡后会有一个元素到达最终位置

public void bubbleSort(int[] a) {
    if (null == a || a.length < 2) {
        return;
    }
    boolean flag;
    for (int i = 0; i < a.length - 1; i++) {
        flag = false;
        for (int j = 0; j < a.length - 1 - i; j++) {
            if (a[j] > a[j+1]) {
                int temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
                flag = true;
            }
            if (flag == false) {
                return;
            }
        }
    }
}

  3.归并排序(nlogn):两个有序序列的合并,方法:分治 + 递归

public static int[] sort(int[] nums, int low, int high) {
    int mid = (low + high) / 2;
    if (low < high) {
        // 左边
        sort(nums, low, mid);
        // 右边
        sort(nums, mid + 1, high);
        // 左右归并
        merge(nums, low, mid, high);
    }
    return nums;
}

/**
 * 将数组中low到high位置的数进行排序
 * @param nums 待排序数组
 * @param low 待排的开始位置
 * @param mid 待排中间位置
 * @param high 待排结束位置
 */
public static void merge(int[] nums, int low, int mid, int high) {
    int[] temp = new int[high - low + 1];
    int i = low;// 左指针
    int j = mid + 1;// 右指针
    int k = 0;

    // 把较小的数先移到新数组中
    while (i <= mid && j <= high) {
        if (nums[i] < nums[j]) {
            temp[k++] = nums[i++];
        } else {
            temp[k++] = nums[j++];
        }
    }

    // 把左边剩余的数移入数组
    while (i <= mid) {
        temp[k++] = nums[i++];
    }

    // 把右边边剩余的数移入数组
    while (j <= high) {
        temp[k++] = nums[j++];
    }

    // 把新数组中的数覆盖nums数组
    for (int k2 = 0; k2 < temp.length; k2++) {
        nums[k2 + low] = temp[k2];
    }
}

不稳定:

  1.希尔排序(n的1.3次方):按步长进行分组,组内直接插入,缩小增量再次进行此步骤,增量为1时相当于一次直接插入

public void shellSort(int[] a) {
    if (null == a || a.length < 2) {
        return;
    }
    for (int d = a.length/2; d > 0; d/=2) {
        for (int i = d; i < a.length; i++) {
        // 内部直接插入
            int temp = a[i];
            int j = i - d;
            while (j >= 0 && temp < a[j]) {
                a[j+d] = a[j];
                j -= d;
            }
            a[j+d] = temp;
        }    
    }
}

2.选择排序(n*n):每次从无序序列选择一个最小的与第一个元素交换,再从剩下的里面找最小的和第二个元素交换。。

  

public void selectSort(int[] a) {
    if (null == a || a.length < 2) {
        return;
    }

    for (int i = 0; i < a.length; i++) {
        int k = i;
        for (int j = i + 1; j < a.length; j++) {
            if (a[j] < a[k]) {
                k = j;
            }
        }
        if (k != i) {
            int temp = a[k];
            a[k] = a[i];
            a[i] = temp;
        }
    }
}

3.快速排序(nlogn):通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。

public void quickSort(int[] a, int low, int high) {

    if (low < high) {
        int mid = partition(a, low, high);
        quickSort(a, low, mid - 1);
        quickSort(a, mid + 1, high);
    }
}

private int partition(int[] a, int low, int high) {
    int pivot = a[low];

    while (low < high) {
        while (low < high && a[high] >= pivot) {
            high--;
        }
        a[low] = a[high];
        while (low < high && a[low] <= pivot) {
            low++;
        }
        a[high] = a[low];
    }
    a[low] = pivot;

    return low;
}

4.堆排序(nlogn):利用堆的特性,建堆,调整堆

// 堆排序
public void heapSort(int[] a) {
    if (null == a || a.length < 2) {
        return;
    }
    buildMaxHeap(a);

    for (int i = a.length - 1; i >= 0; i--) {
        int temp = a[0];
        a[0] = a[i];
        a[i] = temp;
        adjustHeap(a, i, 0);
    }
}

// 建堆
private void buildMaxHeap(int[] a) {
    for (int i = a.length/2; i >= 0; i--) {
        adjustHeap(a, a.length, i);
    }
}

// 调整堆
private void adjustHeap(int[] a, int size, int parent) {
    int left = 2 * parent + 1;
    int right = 2 * parent + 2;
    int largest = parent;

    if (left < size && a[left] > a[largest]) {
        largest = left;
    }

    if (right < size && a[right] > a[largest]) {
        largest = right;
    }

    if (parent != largest) {
        int temp = a[parent];
        a[parent] = a[largest];
        a[largest] = temp;
        adjustHeap(a, size, largest);
    }
}

 

  

posted @ 2017-06-25 01:22  雪浪snowWave  阅读(205)  评论(0编辑  收藏  举报