首页 > 编程语言 >排序——数据结构与算法学习

排序——数据结构与算法学习

时间:2022-11-06 17:34:47浏览次数:70  
标签:arr arrIndex int insertIndex gap 算法 排序 数据结构

排序

冒泡排序法(交换)

基本原理:依次比较相邻元素的值,使值较大的元素逐渐前移或者后移,因为每一轮排序后值最大的元素一定是后移了一位。

xxx

//手写冒泡排序法
public static void bubbleSort(int arr[]){
    int temp = 0;//定义交换用的临时变量
    boolean flag = false;//定义一个局部变量
    for (int i = 0; i < arr.length - 1; i++) {//比较的轮次
        for (int j = 0; j < arr.length - 1 - i; j++) {//比较的具体数字
            if(arr[j] > arr[j + 1]){
                flag = true;
                temp = arr[j];//就是一个很简单的清空的思想
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if(!flag){//一旦出现已经不需要再交换的轮次,直接退出,对于大规模处理能够节省很多时间。
            break;
        }else{
            flag = false;
        }
    }
}

冒泡排序法的核心其实就是双重循环,知道每一轮要比较哪些内容就好。

选择排序法(交换)

基本原理:就是一个简单的迭代思想,每一轮逐步缩小范围

 //手写选择排序法
    public static void selectSort(int arr[]){
        for (int i = 0; i < arr.length - 1; i++) {//比较的轮次
            int minIndex = i;
            boolean flag = false;//设置一个索引便于后期优化
            int min = arr[minIndex];//暂时的最小值
            for (int j = i + 1; j < arr.length - 1; j++) {//找到最小值
                if (arr[j] < min){
                    min = arr[j];
                    minIndex = j;
                }
            }
            if(minIndex != i){//就是将最小值与i交换
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
        }
    }

插入排序法(移位)

基本思想:将元素看成一个有序表和一个无序表,将无序表中的元素插入到有序表中(所以只要找到一个有序列表就好做了)

//重写插入排序
    public static void insertSort(int arr[]){
        int insertVal = 0;//待插入的数
        int insertIndex = 0;//待插入的索引
        for (int i = 1; i < arr.length ; i++) {
            insertVal = arr[i];//要插入的数字
            insertIndex = i - 1;//要比较的索引
            //用一个循环找到要插入的索引(因为是无序表向有序表插入,所以还是蛮容易的)
            while(insertIndex >= 0 && insertVal < arr[insertIndex]){
                arr[insertIndex + 1] = arr[insertIndex];//肯定要向往前插入了,那么就要后推一步
                insertIndex--;//向前查找
            }
            if(insertIndex + 1 != i){//等于i就相当于不需要移动了,节省资源
                arr[insertIndex + 1] = insertVal;
            }
        }
    }

注意:其实就是一个思想:就是后面的空出一个位置,然后前面的往后退,留出一个位置用来插入。

希尔排序法(移位)

注意:希尔排序是对简单插入排序的一种改进,由于当需要插入的数较小时,简单插入排序需要后移过多位数,即为缩小增量插入排序

原理

 //手工书写希尔排序算法
    public static void shellSort3(int arr[]){
        //首先进行希尔排序的分组
        for(int gap = arr.length / 2; gap > 0; gap /= 2){
            for (int i = gap; i < arr.length; i++) {//对分组进行插入排序
                int arrIndex = i;//要比较的索引
                int arrVal = arr[arrIndex];//要插入的数据,提前保存一下
                if(arr[arrIndex] < arr[arrIndex - gap]){
                    while(arrIndex - gap >= 0 && arrVal < arr[arrIndex - gap]){
                        arr[arrIndex] = arr[arrIndex - gap];//移位,相当于覆盖了
                        arrIndex -= gap;//待插入位置向前移动
                    }
                    arr[arrIndex] = arrVal;//找到索引后插入
                }
            }
        }
    }

快速排序法(递归)

思路:是对冒泡排序的改进:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序, 整个排序过程可以递归进行,以此达到整个数据变成有序序列

代码

 public static void fastSort(int[] arr,int begin,int end){
        if(begin > end)//代表该轮已经排序完毕,返回上一轮
            return;
        int tmp = arr[begin];//定义基准变量
        int i = begin;//左边的哨兵指针
        int j = end;//右边的哨兵指针
        while(i != j){//哨兵指针寻找的过程
            while(arr[j] >= tmp && j > i)
                j--;
            while(arr[i] <= tmp && j > i)
                i++;
            if(j > i){//将两个哨兵指针的值对换
                int t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }
        }
        //其实就是完成基准数与第一个数的交换,temp为辅助变量
        arr[begin] = arr[i];//将基准变量的值赋给第一个变量
        arr[i] = tmp;//将基准变量的值赋给i
        fastSort(arr, begin, i-1);//左右两边的递归排序
        fastSort(arr, i+1, end);
    }

本质上就是两个哨兵指针的不断查询与交换,通过递归完成

帮助理解原理的两篇博文

快速排序法

快速排序法图解

不同排序算法的复杂度比较

排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度
冒泡排序 O(n2) O(n) O(n2) O(1)
选择排序 O(n2) O(n2) O(n2) O(1)
插入排序 O(n2) O(n) O(n2) O(1)
希尔排序 O(nlog2n) O(nlog2n) O(nlog2n) O(1)
快速排序 O(nlog2n) O(nlog2n) O(n2) O(logn):涉及到递归

​ ——因为for循环和while循环如果完全执行就是n次的复杂度,这种最好情况就是不需要完全执行,比如冒泡排序法比较了一轮就退出。就是执行循环和不执行循环的区别。

标签:arr,arrIndex,int,insertIndex,gap,算法,排序,数据结构
From: https://www.cnblogs.com/robyn2022/p/16863105.html

相关文章

  • 实验二:逻辑回归算法实验
    实验二:逻辑回归算法实验 【实验目的】理解逻辑回归算法原理,掌握逻辑回归算法框架;理解逻辑回归的sigmoid函数;理解逻辑回归的损失函数;针对特定应用场景及数据,能应用逻......
  • RSA加密算法
    RSA加密算法概述    RSA算法是一种经典的非对称加密算法,密钥一般由三个数字构成:N、E、D。对于一些信息,我们总有办法将其转化为数字,设该数字为X,对应的密文是Y。则......
  • P2824 [HEOI2016/TJOI2016]排序
    P2824[HEOI2016/TJOI2016]排序题目大意这个难题是这样子的:给出一个\(1\)到\(n\)的排列,现在对这个排列序列进行\(m\)次局部排序,排序分为两种:0lr表示将区间\(......
  • 数据结构
    常见的数据结构线性结构包括:线性表、站、队列、双端队列、数组和串1.顺序表(数组)静态顺序表,顺序表只能采用依次遍历的方法2.链表单向非循环链表,双向循环链表3.栈(做递......
  • 【节点免疫】基于时空特性的节点免疫算法的故障诊断matlab仿真
    1.软件版本MATLAB2017b2.算法理论整体算法流程图:步骤一、网络节点的状态初始化,随机产生不同的网络节点,以及对各个网络节点赋值初始的状态信息。步骤二、对每个需要检......
  • 手撕四大限流算法
    在开发高并发系统时,有三把利器用来保护系统:缓存、降级和限流。那么何为限流呢?顾名思义,限流就是限制流量,就像你宽带包了1个G的流量,用完了就没了。通过限流,我们可以很好地控......
  • 逻辑回归算法实验
    【实验目的】理解逻辑回归算法原理,掌握逻辑回归算法框架;理解逻辑回归的sigmoid函数;理解逻辑回归的损失函数;针对特定应用场景及数据,能应用逻辑回归算法解决实际分类问题。......
  • 实验二:逻辑回归算法实验
    【实验目的】理解逻辑回归算法原理,掌握逻辑回归算法框架;理解逻辑回归的sigmoid函数;理解逻辑回归的损失函数;针对特定应用场景及数据,能应用逻辑回归算法解决实际分类问题。......
  • 实验二:逻辑回归算法实验
    【实验目的】理解逻辑回归算法原理,掌握逻辑回归算法框架;理解逻辑回归的sigmoid函数;理解逻辑回归的损失函数;针对特定应用场景及数据,能应用逻辑回归算法解决实际分类问题。......
  • 实验二:逻辑回归算法实验
    实验二:逻辑回归算法实验 【实验目的】1.理解逻辑回归算法原理,掌握逻辑回归算法框架;2.理解逻辑回归的sigmoid函数;3.理解逻辑回归的损失函数;4.针对特定应用场景及数据,......