基础排序整理

上代码(java)

冒泡排序, 堆排序,插入排序,希尔排序,归并排序,快速排序,选择排序

冒泡排序

package sort;

/**
 * Created on 2017/6/12
 * Author: youxingyang.
 */
public class BubbleSort {
    public static void main(String[] args) {
        int[] arr = {4, 1, 8, 0, 2, 8, 9, 6, 14, 18, 3};

        //sort(arr);
        sort1(arr);

        for (Integer a : arr) {
            System.out.print(a + " ");
        }
    }

    /**
     * 标准冒泡排序
     * 二层for循环,每次选出一个最值
     * 复杂度:O(n*n)
     *
     * @param arr
     */
    private static void sort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }

    /**
     * 改进版冒泡-用pos记住每次最后一次交换的下标,下次遍历到pos-1下标即可
     *
     * @param arr
     */
    private static void sort1(int[] arr) {
        int i = arr.length - 1;
        while (i > 0) {
            int pos = 0;
            for (int j = 0; j < i; j++) {
                if (arr[j] > arr[j + 1]) {
                    swap(arr, j, j + 1);
                    pos = j;
                }
            }
            i = pos;
        }
    }

    /**
     * 不使用第三个变量交换两个数
     *
     * @param arr
     * @param i
     * @param j
     */
    private static void swap(int[] arr, int i, int j) {
        if (i != j) {
            //arr[i]被存为和,arr[j]没有变
            arr[i] = arr[i] + arr[j];
            //arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
            arr[j] = arr[i] - arr[j];
            //此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
            arr[i] = arr[i] - arr[j];
        }
    }
}

堆排序

package sort;

import java.util.Arrays;

/**
 * Created on 2017/6/15
 * Author: youxingyang.
 */

/**
 * 思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,
 * 使之成为一个 堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。
 * 然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对 它们作交换,
 * 最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。
 * 所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
 */
public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {6, 5, 4, 3, 2, 1, 0};

        //留最后一个空位放第一个最大值
        for (int i = 0; i < arr.length - 1; i++) {
            buildMaxHeap(arr, arr.length - 1 - i);
            //交换堆顶最大值与最后一个空位
            swap(arr, 0, arr.length - 1 - i);
        }

        System.out.println(Arrays.toString(arr));

    }

    /**
     * 建立一个最大堆
     *
     * @param arr
     * @param lastIndex
     */
    private static void buildMaxHeap(int[] arr, int lastIndex) {
        //从最后一个父节点开始建堆
        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
            int k = i;
            //子节点存在
            while (2 * k + 1 <= lastIndex) {
                int biggerIndex = 2 * k + 1;
                //如果biggerIndex小于lastIndex,即biggerIndex+1代表的右节点存在
                if (biggerIndex < lastIndex) {
                    //左节点小于右节点
                    if (arr[biggerIndex] < arr[biggerIndex + 1]) {
                        biggerIndex++;
                    }
                }

                //当前节点值小于两者最大值,把最大值调到堆顶
                if (arr[k] < arr[biggerIndex]) {
                    swap(arr, k, biggerIndex);
                    //保证k节点的值大于其左右子节点的值
                    k = biggerIndex;
                } else {
                    break;
                }
            }
        }
    }

    /**
     * 不使用第三个变量交换两个数
     *
     * @param arr
     * @param i
     * @param j
     */
    private static void swap(int[] arr, int i, int j) {
        if (i != j) {
            //arr[i]被存为和,arr[j]没有变
            arr[i] = arr[i] + arr[j];
            //arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
            arr[j] = arr[i] - arr[j];
            //此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
            arr[i] = arr[i] - arr[j];
        }
    }
}

插入排序

package sort;

import java.util.Arrays;

/**
 * Created on 2017/6/15
 * Author: youxingyang.
 */

/**
 * 思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,
 * 使之成为一个 堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。
 * 然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对 它们作交换,
 * 最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。
 * 所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
 */
public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {6, 5, 4, 3, 2, 1, 0};

        //留最后一个空位放第一个最大值
        for (int i = 0; i < arr.length - 1; i++) {
            buildMaxHeap(arr, arr.length - 1 - i);
            //交换堆顶最大值与最后一个空位
            swap(arr, 0, arr.length - 1 - i);
        }

        System.out.println(Arrays.toString(arr));

    }

    /**
     * 建立一个最大堆
     *
     * @param arr
     * @param lastIndex
     */
    private static void buildMaxHeap(int[] arr, int lastIndex) {
        //从最后一个父节点开始建堆
        for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
            int k = i;
            //子节点存在
            while (2 * k + 1 <= lastIndex) {
                int biggerIndex = 2 * k + 1;
                //如果biggerIndex小于lastIndex,即biggerIndex+1代表的右节点存在
                if (biggerIndex < lastIndex) {
                    //左节点小于右节点
                    if (arr[biggerIndex] < arr[biggerIndex + 1]) {
                        biggerIndex++;
                    }
                }

                //当前节点值小于两者最大值,把最大值调到堆顶
                if (arr[k] < arr[biggerIndex]) {
                    swap(arr, k, biggerIndex);
                    //保证k节点的值大于其左右子节点的值
                    k = biggerIndex;
                } else {
                    break;
                }
            }
        }
    }

    /**
     * 不使用第三个变量交换两个数
     *
     * @param arr
     * @param i
     * @param j
     */
    private static void swap(int[] arr, int i, int j) {
        if (i != j) {
            //arr[i]被存为和,arr[j]没有变
            arr[i] = arr[i] + arr[j];
            //arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
            arr[j] = arr[i] - arr[j];
            //此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
            arr[i] = arr[i] - arr[j];
        }
    }
}

希尔排序

package sort;

/**
 * Created on 2017/6/12
 * Author: youxingyang.
 */
public class ShellSort {
    public static void main(String[] args) {
        int[] arr = {4, 1, 8, 0, 2, 8, 9, 6, 14, 18, 3};

        sort(arr);

        for (Integer a : arr) {
            System.out.print(a + " ");
        }
    }

    private static void sort(int[] arr) {
        int k = arr.length / 2;
        while (k >= 1) {
            shellSort(arr, k);
            k /= 2;
        }
    }

    /**
     * 希尔排序:  插入排序 = 希尔排序的增量为1
     *
     * @param arr
     * @param k
     */
    private static void shellSort(int[] arr, int k) {
        for (int i = k; i < arr.length; i++) {
            if (arr[i] < arr[i - k]) {
                int j;
                int tmp = arr[i];
                for (j = i - k; j >= 0 && tmp < arr[j]; j = j - k) {
                    arr[j + k] = arr[j];
                }
                arr[j + k] = tmp;
            }
        }
    }
}

归并排序

package sort;

import java.util.Arrays;

/**
 * Created on 2017/6/15
 * Author: youxingyang.
 */
public class MergeSort {
    public static void main(String[] args) {
        int[] arr = {6, 5, 4, 3, 2, 1, 0};

        sort(arr, 0, arr.length - 1);

        System.out.println(Arrays.toString(arr));
    }

    private static void sort(int[] arr, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            sort(arr, low, mid);
            sort(arr, mid + 1, high);
            merge(arr, low, mid, high);
        }
    }

    /**
     * 归并
     * 将两个(或两个以上)有序表合并成一个新的有序表 即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列
     *
     * @param arr  待排序数组
     * @param low  开始位置
     * @param mid  二分位置
     * @param high 结束位置
     */
    private static void merge(int[] arr, int low, int mid, int high) {
        int[] tmp = new int[high - low + 1];
        int i = low;
        int j = mid + 1;
        int k = 0;

        //把较小的值移入新数组tmp中
        while (i <= mid && j <= high) {
            if (arr[i] < arr[j]) {
                tmp[k++] = arr[i++];
            } else {
                tmp[k++] = arr[j++];
            }
        }

        //左边剩余的数移入
        while (i <= mid) {
            tmp[k++] = arr[i++];
        }

        //右边剩余的数移入
        while (j <= high) {
            tmp[k++] = arr[j++];
        }

        //用tmp数组的值覆盖原数组
        for (int l = 0; l < tmp.length; l++) {
            arr[l + low] = tmp[l];
        }
    }

}

快速排序

package sort;

/**
 * Created on 2017/6/12
 * Author: youxingyang.
 */
public class quickSort {

    public static void main(String[] args) {
        int[] arr = {4, 1, 8, 0, 2, 8, 9, 6, 14, 18, 3};

        sort(arr, 0, arr.length - 1);

        for (Integer a : arr) {
            System.out.print(a + " ");
        }
    }

    private static void sort(int[] arr, int low, int high) {
        if (low < high && arr.length > 0) {
            int index = partition(arr, low, high);
            sort(arr, low, index - 1);
            sort(arr, index + 1, high);
        }
    }

    /**
     * 按照key基准给数组分区
     *
     * @param arr  数组
     * @param low  数组初始下标
     * @param high 数组最大下标
     * @return key基准的下标
     */
    private static int partition(int[] arr, int low, int high) {

        int key = arr[low];
        while (low < high) {
            while (arr[high] >= key && low < high) {
                high--;
            }
            arr[low] = arr[high];

            while (arr[low] <= key && low < high) {
                low++;
            }
            arr[high] = arr[low];
        }
        arr[high] = key;
        return high;
    }
}

选择排序

package sort;

import java.util.Arrays;

/**
 * Created on 2017/6/12
 * Author: youxingyang.
 */
public class SelectSort {
    public static void main(String[] args) {
        int[] arr = {6, 5, 4, 3, 2, 1};

        sort(arr);

        System.out.println(Arrays.toString(arr));
    }

    /**
     * 标准选择排序-每次选取一个最值
     *
     * @param arr
     */
    private static void sort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int index = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[index]) {
                    index = j;
                }
            }
            swap(arr, i, index);
        }
    }

    /**
     * 不使用第三个变量交换两个数
     *
     * @param arr
     * @param i
     * @param j
     */
    private static void swap(int[] arr, int i, int j) {
        if (i != j) {
            //arr[i]被存为和,arr[j]没有变
            arr[i] = arr[i] + arr[j];
            //arr[i](和)减去arr[j](没有变)等于arr[i],赋值给arr[j]
            arr[j] = arr[i] - arr[j];
            //此时的arr[j]为arr[i]的值,和arr[i]没有变,arr[i]减去arr[j]等于原本arr[i]的值,赋值给arr[i]
            arr[i] = arr[i] - arr[j];
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值