排序算法

  • 冒泡排序

冒泡排序会走过每一个数字,如果前后相邻的两个数字大小顺序与要求不相同则调转位置,直至相邻的数字大小顺序与要求相符合。

代码如下:

public class Test {

    public static void main (String[] args) {

        int[] a = new int[10];

        for (int i = 0; i < a.length; i++)
            a[i] = (int) (Math.random() * 100);
        sort (a);
    }

    public static void sort (int[] a) {

        int temp;

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

        for (int i = 0; i < a.length; i++)
            System.out.println(a[i]);
    }
}

  • 选择排序

每一次循环都会将数组中最大(或最小)的一个放在末端,它的位置不会再改变。下一次循环对剩下的数字进行重复的操作,直至排序结束。

代码如下:

public class Test {

    public static void main (String[] args) {

        int[] a = new int[10];

        for (int i = 0; i < a.length; i++)
            a[i] = (int) (Math.random() * 100);
        sort (a);
    }

    public static void sort (int[] a) {

        int length = a.length;
        int min;//最小数字的位置
        int temp;

        for (int i = 0; i < length; i++) {
            min = i;//假定i为最小数字的脚标
            for (int j = i + 1; j < length; j++) {
                if (a[j] < a[min])
                    min = j;//如果脚标j对应的数值小于当前最小值,则最小值的脚标为j
            }
            temp = a[i];
            a[i] = a[min];
            a[min] = temp;
        }

        for (int i = 0; i < a.length; i++)
            System.out.println(a[i]);
    }
}
  • 快速排序

快速排序是找到一个数组中的一个作为“基准”,再将数组中小于(大于)“基准”的数放在它前面(后面),比“基准”大(小)的则反之。

代码如下:

public class Test {

    public static void main (String[] args) {

        int[] a = new int[10];

        for (int i = 0; i < a.length; i++)
            a[i] = (int) (Math.random() * 100);
        quickSort (a);
    }

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

        int i, j, index;

        if (low > high)
            return;//递归的出口
        i = low;
        j = high;
        index = a[low];//用第一个数做基准
        //从两端开始向中间进行扫描
        while (i < j) {
            while (i < j && a[j] >= index)
                j--;//从右边开始找到第一个比基准小的数
            while (i < j && a[i] < index)
                i++;//从左边开始找到第一个比基准大的数
            //交换两个数
            if (i < j) {
                int p = a[i];
                a[i] = a[j];
                a[j] = p;
            }
            //将基准放在小于它与大于它的数之间
            int p = a[i];
            a[i] = a[low];
            a[low] = p;
        }
        //对基准左右两侧的数组进行操作
        sort(a, low, i - 1);
        sort(a, i + 1, high);
    }

    public static void quickSort (int[] a) {
        if (a.length > 0)
            sort(a, 0, a.length - 1);
        for (int i = 0; i < a.length; i++) {
            System.out.println(a[i]);
        }
    }
}

  • 插入排序

插入排序,从数组的第一个数开始看作已经排序好,并开始对数组进行扫描,将数与已经排序好的部分进行比较,插进合适的位置,直至所有数都被扫描完毕。

代码如下:

public class Test {

    public static void main (String[] args) {

        int[] a = new int[10];

        for (int i = 0; i < a.length; i++)
            a[i] = (int) (Math.random() * 100);
        sort (a);
        for (int i = 0; i < a.length; i++)
            System.out.println(a[i]);
    }

    public static void sort (int[] a) {

        int length = a.length;
        int temp;

        for (int i = 1; i < length; i++) {
            //j从i位置开始,向右边扫描,若左边数比右边大,则交换位置直至到j - 1 = 0
            for (int j = i; j > 0 && a[j - 1] > a[j]; j--) {
                temp = a[j];
                a[j] = a[j - 1];
                a[j - 1] =temp;
            }
        }
    }
}
  • 归并排序

归并排序的精髓在于先将数组分解成最小单位,再在组合的过程中进行排序,这样当数组再次完整时,顺序也已经被排好了。

主要过程如下:

  1. 分解
  2. 治理
  3. 合并

代码如下:

public class Test {

    public static void main (String[] args) {

        int[] a = new int[10];

        for (int i = 0; i < a.length; i++)
            a[i] = (int) (Math.random() * 100);
        sort (a, 0, a.length - 1);
        for (int i = 0; i < a.length; i++)
            System.out.println(a[i]);
    }

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

        int middle = (low + high) / 2;
        if (low < high) {
            sort(a, low, middle);
            sort(a, middle + 1, high);//分解
            //合并
            merge (a, low, middle, high);
        }
    }

    public static void merge (int[] a, int low, int middle, int high) {
        int[] temp = new int[high - low + 1];//定义一个当前长度的数组(1~3是3个数,故是high-low+1)
        int i = low;
        int j = middle + 1;
        int k = 0;

        //找到较小的数
        while (i <= middle && j <= high) {
            if (a[i] < a[j])
                temp[k++] = a[i++];
            else
                temp[k++] = a[j++];
        }
        //把左边数组的数填进新数组
        while (i <= middle)
            temp[k++] = a[i++];
        //把右边数组的数填进新数组
        while (j <= high)
            temp[k++] = a[j++];
        //将排好序的数组填进原始数组相应位置
        for (int l = 0; l < temp.length; l++) {
            a[l + low] = temp[l];
        }
    }
}
  • 堆排序

通过建立大顶堆或是小顶堆来对数组进行排序

需要知道在堆中i节点的左右孩子节点与其关系为i * 2 + 1和i * 2 + 2

i节点不能大于其左右孩子节点的值,若大于,则交换

主要过程如下:

交换根节点的数与数组最后一个数,从根节点开始进行节点与其左右孩子节点的比较

重复以上步骤直至全部交换比较完毕

代码如下:

public class Test {

    public static void main (String[] args) {

        int[] a = new int[10];

        for (int i = 0; i < a.length; i++)
            a[i] = (int) (Math.random() * 100);
        sort (a);
        for (int i = 0; i < a.length; i++)
            System.out.println(a[i]);
    }

    public static void sort(int[] array) {
        if (array == null || array.length == 1)
            return;

        buildMaxHeap(array); // 第一次排序,构建最大堆,只保证了堆顶元素是数组里最大的

        for (int i = array.length - 1; i >= 1; i--) {
            // 这个是什么意思呢?,经过上面的一些列操作,目前array[0]是当前数组里最大的元素,需要和末尾的元素交换
            // 然后,拿出最大的元素
            swap(array, 0, i);

            // 交换完后,下次遍历的时候,就应该跳过最后一个元素,也就是最大的那个值,然后开始重新构建最大堆
            // 堆的大小就减去1,然后从0的位置开始最大堆
            maxHeap(array, i, 0);
        }
    }

    // 构建堆
    public static void buildMaxHeap(int[] array) {
        if (array == null || array.length == 1)
            return;

        // 堆的公式就是 int root = 2*i, int left = 2*i+1, int right = 2*i+2;
        int cursor = array.length / 2;
        for (int i = cursor; i >= 0; i--) { // 这样for循环下,就可以第一次排序完成
            maxHeap(array, array.length, i);
        }
    }

    // 最大堆
    public static void maxHeap(int[] array, int heapSieze, int index) {
        int left = index * 2 + 1; // 左子节点
        int right = index * 2 + 2; // 右子节点
        int maxValue = index; // 暂时定在Index的位置就是最大值

        //如果左子节点的值,比当前最大的值大,就把最大值的位置换成左子节点的位置
        if (left < heapSieze && array[left] > array[maxValue]) {
            maxValue = left;
        }

        //如果右子节点的值,比当前最大的值大,就把最大值的位置换成右子节点的位置
        if (right < heapSieze && array[right] > array[maxValue]) {
            maxValue = right;
        }

        //如果不相等,说明这个子节点的值有比自己大的,位置发生了交换
        if (maxValue != index) {
            swap(array, index, maxValue); // 就要交换位置元素

            //继续进行排序
            maxHeap(array, heapSieze, maxValue);
        }
    }

    // 数组元素交换
    public static void swap(int[] array, int index1, int index2) {
        int temp = array[index1];
        array[index1] = array[index2];
        array[index2] = temp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值