强化历程7-排序算法(2023.9.12)

  • 此笔记学习图片来自于如下网址

1https://www.west999.com/info/html/chengxusheji/Javajishu/20190217/4612849.html

文章目录

  • 强化历程7-排序算法
    • 1 冒泡排序(交换排序)
    • 2 选择排序
    • 3 直接插入排序
    • 4 希尔排序
    • 5 归并排序
    • 6 快速排序
    • 7 堆排序
    • 8 计数排序

强化历程7-排序算法

1 冒泡排序(交换排序)

在这里插入图片描述

思想:每轮排序,相邻两个元素比较,如果后面元素小于前面元素,则位置颠倒;

  • 每轮可以确定一个最大值,下轮比较只需比较剩下的n-1个元素,排序结束后,退出循环。
    static int[] maopao(int[] arr) {int temp = 0;//交换位boolean flag = false;//标志位,记录有无交换//外层遍历控制遍历轮数for (int i = 0; i < arr.length - 1; i++) {flag = false; // 每轮排序开始时,将标志位重置为false//内层进行交换,并且下轮比较只需比较剩下的n-1个元素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;}}if (!flag){//如果没交换break;}System.out.print("第" + i + "轮交换结果为:");for (int k : arr) {System.out.print(k + " ");}System.out.println("");}return arr;}
  • 时间复杂度:O(N^2),在冒泡排序中,每个元素需要和其他元素进行比较,因此总共需要进行 N^2 次比较操作。
  • 空间复杂度:O(1) ,在冒泡排序中,只需要使用一个临时变量进行数值交换,因此空间复杂度为 O(1)。

2 选择排序

在这里插入图片描述

思想:每轮对未排序元素选择一个最小(或最大的)的标记,放到未排序元素的最左边(或最右边)

       static int[] xuanze(int[] arr) {int temp; //交换位for (int i =0;i< arr.length-1;i++){int minIndex = i;//最小值下标//遍历未排序部分并最小的值for (int j = i+1; j < arr.length; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// 将找到的最小值与未排序部分的第一个元素交换位置temp = arr[minIndex];arr[minIndex] = arr[i];arr[i] = temp;}return arr;}

改进思路:每轮找到未排序元素的最大值和最小值,将他们放到未排序元素两端

  • 时间复杂度:O(N^2)

  • 空间复杂度:O(1)

3 直接插入排序

在这里插入图片描述

思想:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。
    static int[] charu(int[] arr) {for (int i = 1; i < arr.length; i++) {//取出当前元素int currentNum = arr[i];int j = i - 1;  //定位当前元素//对于当前元素,让其从后往前扫描,找出正确位置while (j >= 0 && arr[j] > currentNum) {//比当前元素大的后移一位arr[j + 1] = arr[j];j--;}arr[j+1] = currentNum; //将当前元素插入合适位置}return arr;}
  • 时间复杂度

    • 最坏情况:每次插入每个元素都要挪动一次:O(N^2)
    • 最好情况:O(N)

    越接近顺序时间复杂度越低,元素越少效率越高,因为交换少,因此Arrays.sort()底层length<47为插入排序

  • 空间复杂度:O(1)

4 希尔排序

在这里插入图片描述

思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,然后依次缩减增量(gap)再进行排序,直到增量为1时,进行最后一次直接插入排序。

  • 相当与改进的直接插入排序,只不过原来间隔为1,改为现在的gap了,减少比较和移动的次数,从而提高排序效率。
     static int[] xier(int[] arr) {//将元素分组//增量gap设置为n/2,这意味着我们将数组分成多个子序列,每个子序列包含相隔一个增量的元素。for (int gap = arr.length / 2; gap > 0; gap /= 2) {//对分组进行插入排序for (int i = gap;i<arr.length;i++){int currentNum = arr[i];//当前元素int j =i; while (j>=gap&&arr[j-gap]>currentNum){// 将比当前元素大的元素向右移动一个增量arr[j] = arr[j - gap];j -= gap;}// 将当前元素插入到正确的位置arr[j] = currentNum;}}return arr;}
  • 时间复杂度:O(NlogN)
  • 空间复杂度:O(1)

5 归并排序

在这里插入图片描述

思想:归并排序的思想是将待排序序列分成若干个子序列,每个子序列都是有序的。然后,将这些有序的子序列合并成一个整体有序的序列。

  • 思路: 不停递归分解数组,当分解到自己则退出

    然后开始合并排序

public class guibing {static void guibingGroup(int[] arr, int left, int right) {//递归,相遇时退出,也就是分解遇到自己if (left >= right) {return;}//获取中间元素int mid = (left + right)/2;guibingGroup(arr, left, mid); //左边序列guibingGroup(arr, mid + 1, right);//右边序列//合并guibingheBing(arr, left, mid, right);}private static void guibingheBing(int[] arr, int left, int mid, int right) {int s1 = left;//归并左边第一个数据int s2 = mid + 1;//归并右边第一个数据int temp[] = new int[right - left + 1];int index = 0;//表示temp数组下标while (s1 <= mid && s2 <= right) {//两边都不为空//比较s1和s2的值if (arr[s1] <= arr[s2]) {//放到数组后,下个数字temp[index++] = arr[s1++];} else {temp[index++] = arr[s2++];}}while (s1 <= mid) {temp[index++] = arr[s1++];}while (s2 <= right) {temp[index++] = arr[s2++];}for (int  i=0;i< temp.length;i++){//右边元素放到自己的位置arr[i+left] = temp[i];}}
}
  • 时间复杂度 Nlog(NlogN)
  • 空间复杂度O(N)

6 快速排序

在这里插入图片描述

思想:从左边(或者右边)找一个基准数。

然后从两边开始检索,( 如果左边为基准数从右开始检索,如果右边为基准数从左边开始检索),一边检索出比基准数小的,另一边检索比基准数大的。

如果检索到就停下,然后交换这两个元素,然后再继续检索。

这两个元素一旦相遇则停止检索,把基准数和相遇位置的元素交换。(第一轮结束):左边元素都比基准数小,右边元素都比基准数大。。。

    private static void kuaipai(int[] arr, int left, int right) {//左边索引大于右边,直接返回if (left >= right) {return;}int base = arr[left];//基准数int i = left;//指向左边元素int j = right;//指向右边元素//i和j不相遇while (i != j) {//先由j从右往左检索比基准数小的,如果检索到比基准数小停止while (arr[j] >= base && i < j) {j--;}//先由i从左往右检索比基准数大的,如果检索到比基准数大停止while (arr[i] <= base && i < j) {i++;}//找到了对于数组,交换i和j位置的元素int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}//如果上述条件不成立,i和j相遇arr[left] = arr[i];arr[i] = base;//基准数在这里归位//排基准数左面kuaipai(arr,left,i-1);//排右边kuaipai(arr,j+1,right);}

7 堆排序

在这里插入图片描述

  • 下标为i的节点的父节点下标: (i- 1)/2

  • 下标为i的节点的左孩子下标:i*2+1

  • 下标为i的节点的右孩子下标:i*2+2

思想:子节点要小于父节点

    private static void duipai(int[] tree, int current, int length) {int left = 2 * current + 1; //左节点索引int right = 2 * current + 2;//右节点索引int maxIndex = current; //最大节点索引// 左节点大于最大值if (left < length && tree[left] > tree[maxIndex]) {maxIndex = left;}// 右节点大于最大值if (right < length && tree[right] > tree[maxIndex]) {maxIndex = right;}// 如果当前索引和最大索引不相等if (current != maxIndex) {int temp = tree[current];tree[current] = tree[maxIndex];tree[maxIndex] = temp;duipai(tree,maxIndex,length);}}

将任意树调整为大顶堆

从倒数第一个非叶子结点开始,从后往前,按下标,依次作为根去向下调整即可。

  	//构建大顶堆private static void buildMaxHeap(int[] tree){int lastNode = tree.length-1;int parent = (lastNode-1)/2;for (int k= parent;k>=0;k--){duipai(tree,k);}}

排序

重新构建大顶堆

private static void duiSort(int[] arr){  //重新构建大顶堆  buildMaxHeap(arr);  for (int i=arr.length-1;i>=0;i--){  //最大值放到数组最后  int temp = arr[0];  arr[0] = arr[i];  arr[i] = temp;  //将最大值砍掉  duipai(arr,0,i);  // 重新调整堆  if (i != 0) {  duipai(arr, 0, i);  }  } 

8 计数排序

在这里插入图片描述

思想:它的基本思想是通过计算各个数值出现的次数,然后根据这些次数重新组织待排序数组,从而实现排序。

   public static void jishu(int[] array) {//找出数组中的最大值int max = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > max) {max = array[i];}}//初始化计数数组int[] countArray = new int[max + 1];//统计每个元素的出现次数for (int i = 0; i < array.length; i++) {countArray[array[i]]++;}//重新生成排序后的数组int index = 0;for (int i = 0; i < countArray.length; i++) {while (countArray[i] > 0) {array[index++] = i;countArray[i]--;}}}

  1. 1 ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107134.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT for andriod

QT for andriod 开发 apk软件&#xff0c;因为一些特殊的原因&#xff0c;在这里简单的记录一哈自己开发apk的流程和心得。 首先说明我采用的环境有哪些&#xff1f; 1、QT的版本&#xff0c;个人建议5.15.2的版本及以上&#xff0c;我是用的5.15.2。 2、andriod studio 可以…

记录一次Docker与Redis冲突

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 报错以及Bug ✨特色专栏&#xff1a; …

sql 时间函数

1&#xff0c;前提 今天看同事写的sql里面出现了时间类的函数&#xff0c;平时自己也经常用到&#xff0c;每次都要百度&#xff0c;还不如自己整理记录在一起&#xff0c;方便后续使用。 2&#xff0c;sql时间函数 2.1 获取当前时间&#xff1a; selectNOW() as 当前日期时…

Autojs 小游戏实践-神农百草园

概述 最近一直再写刷视频软件脚本&#xff0c;比如手机视频软件太多&#xff0c;每天都需要手动提现羊毛&#xff0c;太累&#xff0c;使用Autojs来帮助我提现&#xff0c;签到&#xff0c;扯远了&#xff0c;因为做刷视频脚本感觉有点无聊&#xff0c;所以试着做小游戏找图脚…

【GO语言基础】变量常量

系列文章目录 【Go语言学习】ide安装与配置 【GO语言基础】前言 【GO语言基础】变量常量 【GO语言基础】数据类型 文章目录 系列文章目录常量和枚举变量声明全局变量声明大小写敏感 总结 常量和枚举 使用const关键字声明常量&#xff0c;并为每个常量提供显式的值。Go语言没有…

IDEA启动时选择项目

IDEA默认情况下&#xff0c;启动时会选择上一次打开的项目继续。如果我们希望每次启动时都需要手动选择项目&#xff0c;可以按照下列顺序修改&#xff1a; 【File】-【Settings】-【Apperance&Behavior】-【System Settings】-【Startup/Shutdown】 取消选中Reopen last…

LayoutLM【论文翻译】

文章目录 基础信息0 ABSTRACT1 INTRODUCTION2 LAYOUTLM2.1 The BERT Model2.2 The LayoutLM Model2.3 Model Architecture2.4 Pre-training LayoutLM2.5 Fine-tuning LayoutLM 3 EXPERIMENTS3.1 Pre-training Dataset3.2 Fine-tuning Dataset3.3 Document Pre-processing3.4 Mo…

200个常用的Python编程相关英语词汇以及它们的中文释义

大家好&#xff0c;我是涛哥。 好多小伙伴反馈说在学习python的过程中&#xff0c;遇到的英文比较多&#xff0c;为自己的学习和开发产生了很大的阻力&#xff0c;所以为大家梳理了一份 Python编程相关常用的英语词汇以及它们的中文释义&#xff0c;当你刚开始学习Python编程的…

profinet是什么?

profinet是什么&#xff1f; 参考&#xff1a;一文读懂Profibus、Profinet、Ethernet的区别 PROFINETPROFIbusetherNET&#xff0c;把Profibus的主从结构移植到以太网上&#xff0c;所以profinet会有Controller和Device&#xff0c;他们的关系可以简单的对应于profibus的Maste…

【C++模拟实现】手撕红黑树(含图解)

【C模拟实现】手撕红黑树&#xff08;含图解&#xff09; 目录 【C模拟实现】手撕红黑树&#xff08;含图解&#xff09;红黑树的介绍&#xff08;百度百科&#xff09;简介特征&#xff08;十分重要&#xff0c;红黑树的基础&#xff09; 红黑树的实现代码&#xff08;insert部…

C++之weak_ptr与shared_ptr智能指针实例(一百九十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

美陆军推动人工智能算法的持续更新

源自&#xff1a;蓝德智库 声明:公众号转载的文章及图片出于非商业性的教育和科研目的供大家参考和探讨&#xff0c;并不意味着支持其观点或证实其内容的真实性。版权归原作者所有&#xff0c;如转载稿涉及版权等问题&#xff0c;请立即联系我们删除。 “人工智能技术与咨询”…