排序算法汇总(java)

算法解决思路,将复杂的算法拆分成简单的问题-》逐步解决。

1)类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)定义为该算法所耗费的存储空间,它也是问题规模n的函数。
2)空间复 杂度(Space Complexity)是对一个算法 在运行过程中临时占用存储空间大小的量度。有的算法需要占用的临时工作单元数与解决问题的规模n有关,它隨着n的增大而增大,当n较大时,将占用较多的存储单元,例如快速排序和归并排序算法,基数排序就属于这种情况。
3)在做算法分析时, 主要讨论的是时间复杂度。从用户使用体验上看,更看重的程序执行的速度。一些缓存产品(redis, memcache)和算法(基数排序)本质就是用空间换时间。

选择排序、快速排序、希尔排序、堆排序不稳定的排序算法,

冒泡排序、插入排序、归并排序和基数排序稳定的排序算法。

一 冒泡排序算法代码实现如下

冒泡排序的时间复杂度是O(n^2),空间复杂度是O(1),是稳定的排序算法

package top.chenxiky.sort;

import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chenxiky
 * @Date: 2022/05/17/17:01
 * @Description:
 */
public class BubbleSort {
    public static void main(String[] args) {
        // 定义一个数组
        int[] arr = {-3, 9, -1, 10, 8,7};
        bubbleSort(arr);
        // 输出排序后的结果
        System.out.println("arr="+Arrays.toString(arr));
    }

    /**
     * 封装冒泡排序
     * @param arr
     */
    private static void bubbleSort(int[] arr) {
        // 比较的趟数(时间复杂程度On^2)
        for (int i = 0; i < arr.length - 1; i++) {
            // 交换数据的临时变量
            int temp = 0;
            // 标识变量,表示是否进行过交换,加快排序结果
            boolean flag = false;
            // 每趟比较的次数
            for (int j = 0; j < arr.length - i - 1; j++) {
                // 比较
                if (arr[j] > arr[j + 1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            // 输出每一趟的效果
            System.out.println("第" + (i + 1) + "趟排序后的数组");
            System.out.println(Arrays.toString(arr));

            // 在一趟排序中,一次交换都发送没有交换过
            if (!flag) {
                // 跳出循环
                break;
            }else {
                flag = false;// 重置flag,进行下次判断
            }
        }
    }
}

二.选择排序

        概念:选择式排序也属于内部排序法,是从欲排序的数据中,按指定的规则选出某一
元素,再依规定交换位置后达到排序的目的。

选择排序的时间复杂度是O(n^2),是不稳定的算法,它相比较冒泡排序,每次比较后,只更新最小值的下标,每轮循环值最多只做一次值交换。时间上得到了很大的提升。但是也是使用了双层循环,时间复杂度和冒泡排序的一样。

思路;

三.直接插入排序法

直接插入排序算法的时间复杂度为O(n^2),整个算法只需要一个key的辅助变量,所以空间复杂度为O(1)。直接插入排序是一种稳定的排序方法。

 

 每次把数组的第一个数据当成有序。

代码实现如下  

package top.chenxiky.sort;

import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chenxiky
 * @Date: 2022/05/17/19:56
 * @Description:
 */
public class InsertSort {
    public static void main(String[] args) {
        // TODO
        int[] arr = {101, 34, 119, 1, -1};
        insertSort(arr);
    }


    // 插入排序
    public static void insertSort(int[] arr) {

        // 初始化
        int insertVal = 0;
        int insetIndex = 0;
        for (int i = 1; i < arr.length; i++) {
            // 定义待插入的数
            insertVal = arr[i]; // 从数组的第二个数开始,也就是下标为1
            insetIndex = i - 1; // 即arr[1]的前面这个数的下标 已经排序的第一个数的下标

            // insetIndex >= 0 保证在给insertVal 找到插入位置不越界,
            // insertVal < arr[insetIndex]待插入的数还未找到插入位置
            while (insetIndex >= 0 && insertVal < arr[insetIndex]) {
                // 将结果向前占一位
                arr[insetIndex + 1] = arr[insetIndex];
                //进行-1操作退出循环 0-1 == -1 后移
                insetIndex--;
            }
            // 当退出循环时,说明要插入的位置找到
            // 这里我们需要判断是否需要赋值
            if (insetIndex + 1 != i) {
                arr[insetIndex + 1] = insertVal;
            }
        }
        System.out.println("排序后=" + Arrays.toString(arr));
    }
}

四.希尔排序

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序法高效的改进版本。希尔排序是非稳定排序算法。时间复杂度为O(n^3/2)

package top.chenxiky.sort;

import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chenxiky
 * @Date: 2022/05/17/22:54
 * @Description: 希尔排序
 */
public class ShellSort {

    public static void main(String[] args) {

        int[] arr = {1, 3, -1, 6, 8, 10};
//        int[] arr = new int[8];
//        for (int i = 0; i < 8; i++) {
//            arr[i] = (int) (Math.random() * 8000000);
//        }
        // 调用封装的函数
        shellSort2(arr);
    }

    /**
     * 希尔交换法
     *
     * @param arr
     */
    public static void shellSort(int[] arr) {
        // 初始化交换辅助量
        int temp = 0;
        // 根据前面的逐步分析,使用循环处理
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
            for (int i = gap; i < arr.length; i++) {
                // 遍历各组中所有元素(共arr.length / 2组,每组有两个元素,步长为 arr.length/2)
                for (int j = i - gap; j >= 0; j -= gap) {
                    // 如果当前元素加上步长后的那个元素,说明交换
                    if (arr[j] > arr[j + gap]) {
                        temp = arr[j];
                        arr[j] = arr[j + gap];
                        arr[j + gap] = temp;
                    }
                }
            }
        }
        // 输出结果
        System.out.println("希尔排序结果-交换方式:" + Arrays.toString(arr));
    }

    /**
     * 希尔排序移位法 优化
     */
    public static void shellSort2(int[] arr) {
        // 增量gap,并逐渐的缩小增量
        for (int gap = arr.length >> 1; gap > 0; gap /= 2) {
            // 从第gap个元素,逐个对其所在的组进行直接插入排序
            for (int i = gap; i < arr.length; i++) {
                // 保存下标值
                int j = i;
                // 临时变量记录插入的数
                int temp = arr[j];
                if (arr[j] < arr[j - gap]) {
                    while (j - gap >= 0 && temp < arr[j - gap]) {
                        // 移动
                        arr[j] = arr[j-gap];
                        j -=gap;
                    }
                    // 当退出while循环的时候,就给temp找到插入的位置
                    arr[j] = temp;
                }
            }
        }
        System.out.println("希尔排序移位法="+Arrays.toString(arr));
    }
}

五.快速排序 

 

package top.chenxiky.sort;

import java.lang.reflect.Array;
import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chenxiky
 * @Date: 2022/05/19/23:01
 * @Description: 快速排序
 */
public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {-9, 78, 0, 23, -657, 70};
        quickSort(arr, 0, arr.length - 1);
        System.out.println("快排" + Arrays.toString(arr));

    }

    /**
     * 封装
     */
    public static void quickSort(int[] arr, int left, int right) {
        int l = left; // 做下标
        int r = right; // 右下标
        // pivot中轴
        int pivot = arr[(left + right) / 2];
        int temp = 0; // 临时变量 ,交换时使用
        // while循环的目的是让比pivoit 值小放到左边
        // 比pivot值大的放到右边
        while (l < r) {
            // 在pivot的左边一直找,找到大于等于pivoit值,才退出
            while (arr[l] < pivot) {
                l += 1;
            }
            //在pivot的右边一直找,找到小于等于pivoit值,才退出
            while (arr[r] > pivot) {
                r -= 1;
            }
            //如果l>=r 说明pivot的左右俩的值,已经按照左边全是小于等于pivot,右边全部是大于等于pivot
            if (l >= r) {
                break;
            }
            // 交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //如果交换完后,发现arr[l] == pivot 相等-- 前移
            if (arr[l] == pivot) {
                r -= 1;
            }
            //如果交换完后,发现arr[r] == pivot 相等--后移
            if (arr[r] == pivot) {
                l += 1;
            }
        }
        // 如果l==r,必须l++,r--,否则出现栈溢出
        if (l == r) {
            l += 1;
            r -= 1;
        }
        // 向左递归
        if (left < r){
            quickSort(arr,left,r);
        }
        if (right >l){
            quickSort(arr,l,right);
        }
    }
}

 

未完待遇。。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值