当前位置: 首页 > news >正文

常见八大排序算法

今天我们带来数据结构中常见的8大排序算法。

排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性
冒泡排序O(n方)O(n方)O(n方)O(1)稳定
插入排序O(n方)O(n方)O(n方)O(1)稳定
选择排序O(n方)O(n方)O(n方)O(1)不稳定
希尔排序O(n1.3方到1,5方)O(n)O(n方)O(1)不稳定
堆排序O(n log n)O(n log n)O(n log n)O(1)不稳定
快速排序O(n log n)O(n log n)

O(n方)

O(n log n)不稳定
归并排序O(n log n)O(n log n)O(n log n)O(n)稳定
计数排序O(n + k)O(n + k)O(n + k)O(k)不稳定

一,冒泡排序

思路:1,从头到尾比较相邻的元素,2,重复第一步n-1次

代码实现:

public void BubbleSort(int[] array){int[] str = Arrays.copyOf(array,array.length);for (int i = 0; i < str.length; i++) {for (int j = 0; j < str.length-1-i; j++) {if(str[j]<str[j+1]){swap(str,j,j+1);}}}System.out.println(Arrays.toString(str));}

swap是交换,

private void swap(int[] str,int i,int j){int tmp = str[i];str[i] = str[j];str[j] = tmp;}

代码优化: 优化也不会优化到多好基本还是O(n方的复杂度)

 public void BubbleSortLevel(int[] array){int[] str = Arrays.copyOf(array,array.length);for (int i = 0; i < str.length; i++) {boolean a = false;for (int j = 0; j < str.length-1-i; j++) {if(str[j]<str[j+1]){swap(str,j,j+1);a = true;}}if(!a){break;}}System.out.println(Arrays.toString(str));}

二,插入排序

思路; 1,定义两个下标i,j,tmp,i从1开始向后遍历,把初始的下标值赋给tmp 2,j每次从i前面开始向前遍历,比较j下标的元素和tmp的值。

代码实现:

public void InsertSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int j=0;int tmp=0;for (int i = 1; i < str.length; i++) {tmp = str[i];for (j = i-1; j >=0 ; j--) {if(str[j]<tmp){str[j+1] = str[j];}else {break;}}str[j+1] = tmp;}System.out.println(Arrays.toString(str));}

三,选择排序

思路: 1,定义两个下标i,j;i从左向右遍历:2,我们创建一个tmpIndex记录i下标的值,j每次都在i的左边,与tmpIndex的值进行比较,记录新的tmpIndex的值,与i下标交换,重复这个步骤。

代码实现:

public void ChooseSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int j= 0;int tmpIndex = 0;for (int i = 0; i < str.length; i++) {tmpIndex = i;for (j = i+1; j < str.length; j++) {if(str[j]<str[tmpIndex]){tmpIndex = j;}}swap(str,i,tmpIndex);}System.out.println(Arrays.toString(str));}

四,希尔排序

思路: 希尔排序实际就是多次进行快速排序,但是我们每次是不同的几组数进行排序,我们初始一个gap,gap的取值不一,我们一数组长度/2来赋给gap,每次相邻为gap的元素进行插入排序,再对gap/2,直到gap为1,我们的思路是插入排序对越有序的数组排序越有序

代码实现: 

    public void ShellSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int gap = str.length/2;while (gap>=1){ShellSort__InsertSort(str,gap);gap/=2;}System.out.println(Arrays.toString(str));}private void ShellSort__InsertSort(int[] str,int gap){int tmp = 0;int j = 0;for (int i = gap; i < str.length; i++) {tmp = str[i];for (j = i-gap; j >= 0; j-=gap) {if(str[j]<tmp){str[j+gap] =str[j];}else {break;}}str[j+gap] = tmp;}}

五,堆排序

思路: 以升序为例,降序建小根堆,升序建大根堆,

1,建堆  2,栈顶元素与尾元素互换,再进行向下调整  3,直到重复步骤2直到0下标。

代码实现: 

public void HeapSort(int[] array){int[] str = Arrays.copyOf(array,array.length);CreateHeap(str);for (int i = str.length-1; i >=0 ; i--) {swap(str,i,0);ShiftDown(str,0,i);}System.out.println(Arrays.toString(str));}private void CreateHeap(int[] str){int c = str.length-1;int p = (c-1)/2;while (p>=0){ShiftDown(str,p,str.length);p--;}System.out.println(Arrays.toString(str));}private void ShiftDown(int[] str, int parent,int usdSize){int child = 2*parent+1;while (child<usdSize){if(child+1<usdSize && str[child]<str[child+1]){child++;}if(str[child]>str[parent]){swap(str,child,parent);parent = child;child = 2*parent+1;}else {break;}}}

六,快速排序

思路: 1,选择一个基准,定义两个下标,一个从右往左走(先走),一个从左往右走,右边遇到小于基准的与左边大于基准的交换,

2,找到基准,从基准左边和右边递归,重复1的过程。

代码实现(递归实现):

public void QuickSort(int[] array){int[] str = Arrays.copyOf(array,array.length);QuickSortChild(str,0,str.length-1);System.out.println(Arrays.toString(str));}private void QuickSortChild(int[] str,int start,int end){if(start>end){return;}int left = start;int right = end;int part = partition(str,left,right);QuickSortChild(str,start,part-1);QuickSortChild(str,part+1,end);}private int partition(int[] str,int start,int end){int left = start;int right = end;int cmp = str[left];while (left<right){while (left<right && str[right]<=cmp){right--;}while (left<right && str[left]>=cmp){left++;}if(left<right){swap(str,left,right);}}swap(str,start,left);return left;}

代码优化(递归实现):(三数取中法

public void QuickSort2(int[] array){int[] str = Arrays.copyOf(array,array.length);QuickSortChild(str,0,str.length-1);System.out.println(Arrays.toString(str));}private void QuickSortChild2(int[] str,int start,int end){if(start>end){return;}int left = start;int right = end;int mid = middle(left,(left+right)/2,right);swap(str,start,mid);int part = partition(str,left,right);QuickSortChild(str,start,part-1);QuickSortChild(str,part+1,end);}private int partition2(int[] str,int start,int end){int left = start;int right = end;int cmp = str[left];while (left<right){while (left<right && str[right]<=cmp){right--;}while (left<right && str[left]>=cmp){left++;}if(left<right){swap(str,left,right);}}swap(str,start,left);return left;}private int middle(int left,int middle,int right){int[] arr = new int[]{left,middle,right};Arrays.sort(arr);return arr[1];}

 代码实现(非递归实现):

public void QuickSort3(int[] array){int[] str = Arrays.copyOf(array,array.length);QuickSortChild3(str,0,array.length-1);System.out.println(Arrays.toString(str));}private void QuickSortChild3(int[] str,int start,int end){Deque<Integer> stack = new ArrayDeque<>();int part = partition3(str,start,end);if (part+1<end){stack.push(end);stack.push(part+1);}if(part-1>start){stack.push(part-1);stack.push(start);}while (!stack.isEmpty()){end = stack.pop();start = stack.pop();part = partition3(str,start,end);if (part+1<end){stack.push(end);stack.push(part+1);}if(part-1>start){stack.push(part-1);stack.push(start);}}}private int partition3(int[] str,int start,int end){int left = start;int right = end;int cmp = str[left];while (left<right){while (left<right && str[right]<=cmp){right--;}while (left<right && str[left]>=cmp){left++;}if(left<right){swap(str,left,right);}}swap(str,start,left);return left;}

七,归并排序

思路: 1,我们把数据平均分为两个部分定义左中右三个下标,左边递归,右边递归,

2,当左下标大于等于右递下标归停止,我们使用合并数组的方法,把每层递归后有序的左右子树有序化

代码实现:

public void MergeSort(int[] array){int[] str = Arrays.copyOf(array,array.length);MergeSortChild(str,0,str.length-1);System.out.println(Arrays.toString(str));}private void MergeSortChild(int[] str,int left, int right){if(left>=right){return;}int mid = (left+right)/2;MergeSortChild(str,left,mid);MergeSortChild(str,mid+1,right);MergeSort__new(str,left,mid,right);}private void MergeSort__new(int[] str,int left,int mid,int right){int s1 = left;int e1 = mid;int s2 = mid+1;int e2 = right;int[] arr = new int[right-left+1];int i=0;while (s1<=e1 && s2<=e2){if(str[s1]<=str[s2]){arr[i] = str[s1];i++;s1++;}if(str[s2]<str[s1]){arr[i] = str[s2];i++;s2++;}}while (s1<=e1){arr[i] = str[s1];i++;s1++;}while (s2<=e2){arr[i] = str[s2];i++;s2++;}for (int k = 0; k < i; k++) {str[k+left] = arr[k];}}

 

八,计数排序

计数排序适合排那些一定范围的大量数据,比如1-100的考试成绩

思路: 1,我们遍历原数组,找出最大值最小值,用他们的差值大小构建一个计数数组,

2,把原数组出现的数字-min放到计数数组里,有一个计数数组就加一,循环遍历计数数组,直到计数数组全部元素都为0

代码实现: 

public void CountIngSort(int[] array){int[] str = Arrays.copyOf(array,array.length);int max = str[0];int min = str[0];for (int i = 0; i <str.length ; i++) {if(str[i]>max){max = str[i];}if(str[i]<min){min = str[i];}}int[] count = new int[max-min+1];for (int i = 0; i < str.length; i++) {int a = str[i];count[a-min]+=1;}int j = 0;int i = 0;while (i<count.length) {while (count[i]!=0){str[j] = i+min;j++;count[i]--;}i++;}System.out.println(Arrays.toString(str));}

 

http://www.lryc.cn/news/461359.html

相关文章:

  • 汽车免拆诊断案例 | 2022款大众捷达VS5车行驶中挡位偶尔会锁在D3挡
  • Linux之HugePage的原理与使用
  • 一步步优化Redis实现分布式锁
  • C++进阶——二叉搜索树
  • Require:业界优秀的HTTP管理方案。
  • 装饰模式(Decorator Pattern)在 Go 语言中的应用
  • Windows系统部署redis自启动服务
  • 34岁IT男的职场十字路口:是失业预警,还是转型契机?
  • 复试经验分享《三、计算机学科专业基础综合》- 数据结构篇
  • 数学建模算法与应用 第16章 优化与模拟方法
  • windows下安装、配置neo4j并服务化启动
  • 【JVM】—深入理解G1回收器—回收过程详解
  • 2、CSS笔记
  • 使用XML实现MyBatis的基础操作
  • 智汇云舟亮相WAFI世界农业科技创新大会,并参编数字农业产业图谱
  • 昇思MindSpore进阶教程--数据处理性能优化(中)
  • Vivado - Aurora 8B/10B IP
  • 图(Java语言实现)
  • GPT 生成绘画_Java语言例子_超详细
  • 华为OD机试 - 小朋友分组最少调整次数 - 贪心算法(Python/JS/C/C++ 2024 E卷 100分)
  • 数字农业与遥感监测平台
  • 2023年12月中国电子学会青少年软件编程(Python)等级考试试卷(一级)答案 + 解析
  • 【优选算法】——双指针(下篇)!
  • C#中函数重载的说明
  • 图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)
  • 源码编译方式安装htppd软件
  • MES制造执行系统原型图动端 Axure原型 交互设计 Axure实战项目
  • flutter 仿淘宝推荐二级分类效果
  • 报错 - LangChain AgentExecutor - ‘function‘ object has no attribute ‘get‘
  • 【DIY小记】通过降低电压和Process Lasso工具优化CPU超频表现