算法-排序

0、复杂度及稳定性

时间复杂度空间复杂度

稳定性(相等元素相对顺序不变)

冒泡排序

时间复杂度为O(n^2)

最坏/平均:O(n^2)

最好:O(n),序列有序

O(1)稳定
插入排序

时间复杂度为O(n^2)

最坏/平均:O(n^2)

最好:O(n),序列有序

O(1)稳定
选择排序O(n^2)O(1)不稳定
希尔排序O(nlogn) <O( )<O(n^2)O(1)不稳定
快速排序

O(nlogn)

最坏:O(n^2),逆序

O(logn)不稳定
归并排序O(nlogn)O(n)稳定
堆排序O(nlogn)O(1)不稳定
桶排序

最好:O(n)

最坏/平均,与数据分布有关

O(n+k)

k是桶的数量

稳定
计数排序O(n+k)

O(k)

k是待排序序列中最大值与最小值的差

稳定
基数排序

O(d(n+k))

d为位数,n为数据总数

k为最大数的位数

O(n+k)

k为最大数的位数

稳定

一、冒泡排序

比较相邻的元素,若顺序错误则交换

public void bubbleSort(int[] array) {for (int i = 0; i < arr.length - 1; i++) {  for (int j = 0; j < arr.length - i - 1; j++) {  if (array[j] > array[j+1]) {  // 交换 array[j] 和 array[j+1]  int temp = array[j];  array[j] = array[j+1];  array[j+1] = temp;  }  }  }  
}  

二、插入排序

将一个待排序的元素按其大小插入到已排序的序列中的适当位置,直到全部插入完

public void insertionSort(int[] array) {  int n = array.length;  for (int i = 1; i < n; ++i) {  int key = array[i];  int j = i - 1;  while (j >= 0 && array[j] > key) {  array[j + 1] = array[j];  j = j - 1;  }  array[j + 1] = key;  }  
}  

三、选择排序

在未排序序列中找到最小元素,存放到排序序列的起始位置。再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

public void selectionSort(int[] array) {  for (int i = 0; i < array.length - 1; i++) {  // 找到最小元素的索引  int minIndex = i;  for (int j = i + 1; j < array.length; j++) {  if (array[j] < array[minIndex]) {  minIndex = j;  }  }  // 将找到的最小元素交换到已排序序列的末尾  int temp = array[minIndex];  array[minIndex] = array[i];  array[i] = temp;  }  
}  

四、希尔排序

插入排序的一种更高效的改进版

public void shellSort(int[] array) {  int n = array.length;  int gap, i, j, temp;  // Start with a big gap, then reduce the gap  for (gap = n / 2; gap > 0; gap /= 2) {  for (i = gap; i < n; i += 1) {  temp = array[i];  for (j = i; j >= gap && array[j - gap] > temp; j -= gap) {  array[j] = array[j - gap];  }  array[j] = temp;  }  }  
}  

五、快速排序

采用分治法。选择一个“基准”元素,通过一趟排序将待排序的数据分割成独立的两部分,其中一部分的所有数据都比基准元素小,另一部分的所有数据都比基准元素大。以此类推,达到有序

public void quickSort(int[] array, int low, int high) {  if (low < high) {  // 找到基准元素的正确位置  int pi = partition(array, low, high);  // 分别对基准元素两侧的子序列进行递归排序  quickSort(array, low, pi - 1);  quickSort(array, pi + 1, high);  }  
}  /* 基准元素分割 */  
public int partition(int[] array, int low, int high) {  // 选择最右侧的元素作为基准元素  int pivot = array[high];  int i = low - 1; // 指向比基准元素小的元素  for (int j = low; j < high; j++) {  // 如果当前元素小于或等于基准元素  if (array[j] <= pivot) {  i++;  // 交换两个元素  int temp = array[i];  array[i] = array[j];  array[j] = temp;  }  }  // 将基准元素放到正确的位置  int temp = array[i + 1];  array[i + 1] = array[high];  array[high] = temp;  return i + 1;  
}  

六、归并排序

先递归分解数组,再将已有序的子序列合并,得到完全有序的序列

 public void mergeSort(int[] array, int left, int right) {  if (left < right) {  // 找到中间位置  int mid = (left + right) / 2;  // 对左半部分进行归并排序  mergeSort(array, left, mid);  // 对右半部分进行归并排序  mergeSort(array, mid + 1, right);  // 合并左右两部分  merge(array, left, mid, right);  }  
}  public void merge(int[] array, int left, int mid, int right) {  // 创建一个临时数组来辅助归并操作  int[] temp = new int[right - left + 1];  // 左指针和右指针分别指向左半部分和右半部分的起始位置  int i = left;  int j = mid + 1;  int k = 0;  // 合并两个有序数组到临时数组  while (i <= mid && j <= right) {  if (array[i] <= array[j]) {  temp[k++] = array[i++];  } else {  temp[k++] = array[j++];  }  }  // 将左半部分剩余的元素复制到临时数组  while (i <= mid) {  temp[k++] = array[i++];  }  // 将右半部分剩余的元素复制到临时数组  while (j <= right) {  temp[k++] = array[j++];  }  // 将临时数组中的元素复制回原数组  for (i = 0; i < temp.length; i++) {  array[left + i] = temp[i];  }  
}  

七、堆排序

利用堆进行排序

public class Heap <T extends Comparable<T>>{//定义一个数组来存储堆中的元素private T[] items;//记录堆中元素个数private int Num;public Heap(int capacity){//因为T继承了Comparable接口,所以这里是new Comparable类型数组this.items = (T []) new Comparable[capacity+1]; this.Num = 0;}//判断堆中索引i处的元素是否小于索引j处的元素private boolean less(int i, int j){return items[i].compareTo(items[j]);}//交换堆中i索引和j索引处的值private void exchange(int i, int j){T temp = items[i];items[i] = items[j];items[j] = temp;}//往堆中插入一个元素public void insert(T t) {//因为数组数量Num初始化为0,而这里堆中第一个元素item[0]是不存放任何数值的,//所以使用++Num跳过了第一个items【0】items[++Num] = t;rise(Num);}//上浮算法,使索引k处的元素能在堆中处于一个正确的位置private void rise(int k){//通过循环不断比较当前结点的值和其父结点的值,如果当前结点大于父结点就交换两者位置while(k>1){//比较当前结点和其父结点if(less(k/2,k)){exchange(k/2,k);k = k/2;}else{break;}}}//删除堆中最大的元素,并返回这个最大元素public T delMax(){T max = items[1];//交换索引1处元素和最大索引处的元素,让完全二叉树最右侧的元素变为临时根结点exchange(1,Num);//删除交换操作后的最大索引处的元素items[Num] = null;//元素个数减1Num--;//通过下沉算法,重新排列堆sink(1);return max;}//下沉算法,使索引k处的元素能在堆中处于一个正确的位置private void sink(int k){//通过循环不断比较当前k结点和其左子结点2*k以及右子结点2*k+1处的较大值的元素大小//当前结点小,则交换与子节点中最大值的位置while(2*k<=Num){//获取当前结点的子结点的最大结点int max;if(2*k+1<=Num){ //判断当前结点是否有右子结点if(2*k<2*k+1){max = 2*k+1;}else{max = 2*k;}}else{max = 2*k;}//比较当前结点和较大结点的值if(!less(k,max)){break;}//交换k索引的值和max索引处的值exchange(k,max);//交换k的值k = max;}}
}

八、桶排序

1、数据分桶,桶编号 = (数组元素 - 最小值) * (桶个数 - 1) / (最大值 - 最小值)

2、每个桶排序

3、遍历

/*** 桶排序**/
public static void bucketsort(int[] arr, int bucketSize) {// 初始化最大最小值int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;// 找出最小值和最大值for (int num : arr) {max = Math.max(max, num);min = Math.min(min, num);}// 创建bucketSize个桶List<List<Integer>> bucketList = new ArrayList<>();// 声明五个桶for (int i = 0; i < bucketSize; i++) {bucketList.add(new ArrayList<>());// 确定桶的格式为ArrayList}// 将数据放入桶中for (int num : arr) {// 确定元素存放的桶号int bucketIndex = (num - min) * (bucketSize - 1) / (max - min);// 将元素存入对应的桶中List<Integer> list = bucketList.get(bucketIndex);list.add(num);}// 遍历每一个桶for (int i = 0, arrIndex = 0; i < bucketList.size(); i++) {List<Integer> list = bucketList.get(i);// 对每一个桶排序list.sort(null);for (int value : list) {arr[arrIndex++] = value;}}
}

九、计数排序

/*** 计数排序**/
public static void countingSort(int[] arr) {if (arr.length == 0) {return;}// 原数组拷贝一份int[] copyArray = Arrays.copyOf(arr, arr.length);// 初始化最大最小值int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;// 找出最小值和最大值for (int num : copyArray) {max = Math.max(max, num);min = Math.min(min, num);}// 新开辟一个数组用于统计每个元素的个数(范围是:最大数-最小数+1)int[] countArray = new int[max - min + 1];// 增强for循环遍历for (int num : copyArray) {// 加上最小偏差是为了让最小值索引从0开始,同时可有节省空间,每出现一次数据就加1// 真实值+偏差=索引值countArray[num - min]++;}// 获取数组的长度int length = countArray.length;// 计数数组变形,新元素的值是前面元素累加之和的值for (int i = 1; i < length; i++) {countArray[i] = countArray[i] + countArray[i - 1];}// 遍历拷贝数组中的元素,填充到原数组中去,从后往前遍历for (int j = copyArray.length - 1; j >= 0; j--) {// 数据对应计数数组的索引int countIndex = copyArray[j] - min;// 数组的索引获取//(计数数组的值n就是表示当前数据前有n-1个数据,数组从0开始,故当前元素的索引就是n-1)int index = countArray[countIndex] - 1;// 数组中的值直接赋值给原数组arr[index] = copyArray[j];// 计数数组中,对应的统计值减1countArray[countIndex]--;}
}

十、基数排序

/*** 基数排序**/
public static void radixSort(int[] arr) {// 初始化最大值int max = Integer.MIN_VALUE;// 找出最大值for (int num : arr) {max = Math.max(max, num);}// 我们这里是数字,所以初始化10个空间,采用LinkedListLinkedList<Integer>[] list = new LinkedList[10];for (int i = 0; i < 10; i++) {list[i] = new LinkedList<>();// 确定桶的格式为ArrayList}// 个位数:123 / 1 % 10 = 3// 十位数:123 / 10 % 10 = 2// 百位数: 123 / 100 % 10 = 1for (int divider = 1; divider <= max; divider *= 10) {// 分类过程(比如个位、十位、百位等)for (int num : arr) {int no = num / divider % 10;list[no].offer(num);}int index = 0; // 遍历arr原数组// 收集的过程for (LinkedList<Integer> linkedList : list) {while (!linkedList.isEmpty()) {arr[index++] = linkedList.poll();}}}
}

  • 计数排序:每个桶只存储单一键值
  • 桶排序:每个桶存储一定范围的数值
  • 基数排序:根据键值的每位数字来分配桶

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

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

相关文章

可视化场景(2):电商大屏-引爆业绩,直观呈现

hello&#xff0c;我是贝格前端工场&#xff0c;本期分享可视化大屏在电商领域的应用&#xff0c;如需要定制&#xff0c;可以与我们联络&#xff0c;开始了。 电商领域的可视化大屏可以提供实时的销售数据、用户行为分析、库存管理等信息&#xff0c;帮助企业实时监控经营状况…

java jdk17 HashMap解读

类描述 基于Hash表的Map接口实现。此实现提供了所有的可选的map操作&#xff0c;并且避免了null值和null键。&#xff08;HashMap类大体上等价于Hashtable,除了它是非同步的和禁止null&#xff09;。此类不保证map的顺序。特别是&#xff0c;不保证随着时间的变化顺序保持不变…

不知道吧,腾讯云轻量应用服务器使用有一些限制!

腾讯云轻量应用服务器相对于云服务器CVM是有一些限制的&#xff0c;比如轻量服务器不支持更换内网IP地址&#xff0c;不支持自定义私有网络VPC&#xff0c;内网连通性方面也有限制&#xff0c;轻量不支持CPU内存、带宽或系统盘单独升级&#xff0c;只能整个套餐整体升级&#x…

题目 2021: 坐标排序

题目描述: 请将坐标x,y,z依照以下规则排序&#xff1a; x为第一关键字&#xff0c;当x相同时&#xff0c;依照y&#xff08;第二关键字&#xff09;大小来排序&#xff0c;当y相同时&#xff0c;依照z大小来排序&#xff08;第三关键字&#xff09; 给出了若干坐标&#xff0c…

【AIGC调研系列】大模型的system prompt破解调研

大模型的system prompt破解方法实践主要涉及到prompt工程和提示注入等技术。首先&#xff0c;prompt工程是指通过精心设计prompt&#xff0c;以提高与大模型的交互效率和准确性。这包括了如何清晰地表达任务要求和期望结果[2]&#xff0c;如何有效使用prompt[4]&#xff0c;以及…

Anthropic 公司最新宣布,他们的 AI 聊天机器人模型击败了 OpenAI 的 GPT-4

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Unity Text文本实现滚动跑马灯效果

在一些公告上我们经常会看到文字滚动跑马灯的效果。 那么在Unity上如何实现&#xff1f; 1、首先创建一个Text(或者TextMeshPro)组件&#xff0c;然后输入需要显示的文本内容&#xff0c;如图&#xff1a; 2、编写控制脚本TextRoll.cs&#xff1a; using System.Collections…

【MGR】MySQL Group Replication 监控

目录 17.4 Monitoring Group Replication 17.4.1 Group Replication Server States 17.4.2 The replication_group_members Table 17.4.3 The replication_group_member_stats Table 17.4 Monitoring Group Replication 17.4.1 Group Replication Server States 服务器实例…

钉钉h5应用 globalthis is not defined vite client

钉钉h5应用 globalthis is not defined vite client problem 背景 钉钉h5应用使用 vue3 vite 构建的前端工程 问题 h5页面在pc端浏览器和pc端钉钉打开正常h5页面在移动端钉钉打开异常 页面空白 通过调试工具找到报错信息 globalthis is not defined vite client reason …

ULTRAL SCALE FPGA TRANSCEIVER速率

CPLL支持2-6.25速率 QPLL支持速率 实际使用CPLL最高可以超过这个&#xff0c;QPLL最低也可以低于这个&#xff0c;xilinx留的阈量还是比较大。

数仓开发-2023/2/29

1.简单自我介绍 2.介绍下之前的公司离线数仓项目 3.sql和hivesql区别&#xff1f; 4.sql的执行顺序&#xff1f; 5.hive的优化 6.说下你之前公司来&#xff0c;你的技能层次在每个公司&#xff1f;你怎么评价你的技能&#xff1f; 7.你的之前业务主要是做什么&#xff1f;我说了…

谈一谈mysql的删除操作 DELETE、TRUNCATE和DROP

MySQL中的删除操作可以通过多种语句实现&#xff0c;包括DELETE、TRUNCATE和DROP。具体来看&#xff1a; DELETE&#xff1a; 属于数据库的DML&#xff08;Data Manipulation Language&#xff09;操作语言。 可以删除一行或多行数据&#xff0c;但不会删除表结构。 在InnoD…

这是谁的女儿?其母亲早已红过头了,现在小小年纪的她也爆红网络,没想到吧?

这是谁的女儿&#xff1f;其母亲早已红过头了&#xff0c;现在小小年纪的她也爆红网络&#xff0c;没想到吧&#xff1f; 原来&#xff0c;作母亲的她在红极一时后似乎沉寂了下来&#xff0c;没想到她11岁的女儿近年来也在社交媒体上走红&#xff0c;她为何也成了小网红呢&…

mock项目:

为什么不使用react严格模式 <React.StrictMode><App /></React.StrictMode>,使用严格模式有一些好处&#xff0c;它会执行额外的检查以帮助发现常见的问题&#xff0c;并提供更好的错误和警告信息。 第三方库的兼容性问题&#xff1a;有些第三方库可能不支持…

数字化转型导师坚鹏:大模型的应用实践(金融)

大模型的应用实践 ——开启人类AI新纪元 打造数字化转型新利器 课程背景&#xff1a; 很多企业和员工存在以下问题&#xff1a; 不清楚大模型对我们有什么影响&#xff1f; 不知道大模型的发展现状及作用&#xff1f; 不知道大模型的针对性应用案例&#xff1f; 课程…

C# 高级特性(十一):多线程之async,await

之前使用Thread和Task启动多线程时都会遇到一个麻烦&#xff0c;就是如何反馈结果。在代码里就是如何设计回调函数。如果带界面还得考虑UI线程的问题。 而使用async&#xff0c;await可以达到两个效果。 1 不用设计回调函数&#xff0c;直接按单线程的格式写。 2 不用考虑UI…

【决策树】预测用户用电量

决策树预测用户用电量 文章目录 决策树预测用户用电量  &#x1f449;引言&#x1f48e;一、 数据预处理数据预处理初步数据分析 二、 机器学习算法决策树回归预测用电量决策树模型介绍&#xff1a;回归预测 三、 可视化结果四、 数据分析与结论代码如下 &#x1f449;引言&a…

2024山东国际健康产业博览会·口腔医疗与医疗器械馆

China-DJK山东健博会|第六届中国国际大健康产业博览会5月27-29日在济南盛大举办&#xff1b; 2024第6届中国&#xff08;济南&#xff09;国际大健康产业博览会&#xff08;China-DJK山东健博会&#xff09; The 2024 sixth China (Jinan) International Big Health Industry …

代码随想录算法训练营第四天|24.两两交换链表中的节点、19.删除链表的倒数第N的节点、07.链表相交、142.环形链表II

代码随想录算法训练营第四天|24.两两交换链表中的节点、19.删除链表的倒数第N的节点、07.链表相交、142.环形链表II 24.两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成…

Vue+OpenLayers7入门到实战:OpenLayers7点聚合(聚散点)功能,地图缩小显示聚集数量,点击聚集点散开和地图放大后显示要素图片

返回《Vue+OpenLayers7》专栏目录:Vue+OpenLayers7入门到实战 前言 本章介绍如何使用OpenLayers7在地图上实现地图点聚合(聚散点)功能,实现地图缩小显示聚集数量,点击聚集点和地图放大后显示要素对应icon图片的功能。 二、依赖和使用 "ol": "7.5.2"…