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

排序(Sort)

常见的算法排序

直接插入排序
插入排序

直接插入排序:将数组分为 “已排序区间” 和 “未排序区间”,每次从 “未排序区间” 取一个元素,插入到 “已排序区间” 的合适位置,逐步扩大 “已排序区间”,直到整个数组有序

public class MySort {public static void insertSort(int[] array){for (int i = 1; i <array.length ; i++) {int tmp=array[i];int j = i-1;for (; j >=0 ; j--) {if (array[j]>tmp){array[j+1]=array[j];}else {break;}}array[j+1]=tmp;}}
}
import java.util.Arrays;public class Test {public static void main(String[] args) {MySort sort=new MySort();int[] array={3,25,156,74,7,68,91,6};MySort.insertSort(array);System.out.println(Arrays.toString(array));}}
插入排序的耗时
import java.util.Arrays;
import java.util.Random;public class TimeTest {//顺序public static int[] order(int[] array){for (int i = 0; i < array.length ; i++) {array[i]=i;}return array;}//逆序public static int[] reverseOrder(int[] array){for (int i = 0; i <array.length ; i++) {array[i]=array.length-i;}return array;}//随机顺序public static int[] randomOrderNum(int[] array){Random random=new Random();for (int i = 0; i < array.length ; i++) {array[i]=random.nextInt(10_0000);array[i]=random.nextInt(1_0000);}return array;}public static void insertSortTime(int[] array){array=Arrays.copyOf(array,array.length);long startTime=System.currentTimeMillis();MySort.insertSort(array);long endTime=System.currentTimeMillis();System.out.println(endTime-startTime);}public static void main(String[] args) {int[] array=new int[1_0000];System.out.println("排序顺序的耗时:");insertSortTime(order(array));System.out.println("排序顺序的耗时:");insertSortTime(reverseOrder(array));System.out.println("排序顺序的耗时:");insertSortTime(randomOrderNum(array));}}

希尔排序(缩小增量排序)

希尔排序:先将数组按一定 “增量” 分成多个子序列,对每个子序列进行插入排序;然后逐步缩小增量,重复分组和插入排序的过程,直到增量为 1,最终完成整个数组的排序

public static void shellSort(int[] array){int gap=array.length;while (gap>1){gap/=2;shell(array,gap);}
}private static void shell(int[] array, int gap) {for (int i = gap; i <array.length; i++) {int tmp=array[i];int j=i-gap;for (; j>=0; j-=gap) {if (array[j]>tmp){array[j+gap]=array[j];}else {break;}}array[j+gap]=tmp;}
}
public static void main(String[] args) {MySort mySort=new MySort();int[] array={3,5,15,7,6,8,9,10};MySort.shellSort(array);System.out.println(Arrays.toString(array));
}

希尔排序的耗时

选择排序
选择排序

选择排序:原址比较排序算法,在每一轮迭代中,都会在未排序的元素中找到最小(升序排序)或最大(降序排序)的元素,然后将其与未排序部分的第一个元素交换位置,逐步将未排序部分的元素减少,已排序部分的元素增加,最终完成整个数组的排序

public static void selectSort(int[] array){for (int i = 0; i < array.length ; i++) {int minIndex=i;for (int j = i+1; j < array.length; j++) {if (array[j]< array[minIndex]){minIndex=j;}}swap(array,i,minIndex);}
}private static void swap(int[] array, int i, int minIndex) {int tmp=array[i];array[i]= array[minIndex];array[minIndex]=tmp;
}
public static void main(String[] args) {int[] array={1,24,45,6,2,68,9,5};MySort mySort=new MySort();MySort.selectSort(array);System.out.println(Arrays.toString(array));
}

选择排序的耗时
堆排序

堆排序:将数组构建为二叉堆(通常使用最大堆),然后通过反复提取堆顶元素(最大值)并调整堆结构,最终得到有序数组

public static void heapSort(int[] array){createHeap(array);int end=array.length-1;while (end>0){swap(array,0,end);shiftDown(array,0,end);end--;}
}
private static void createHeap(int[] array){for (int parent = (array.length-1-1)/2; parent >=0 ; parent--) {shiftDown(array,parent,array.length);}
}private static void shiftDown(int[] array, int parent, int length) {int child=2*parent+1;while (child<length){if (child+1<length&&array[child]<array[child+1]){child++;}if (array[child]>array[parent]){swap(array,child,parent);parent=child;child=2*parent+1;}else {break;}}
}
public static void main(String[] args) {int[] array={1,24,45,6,2,68,9,5};MySort mySort=new MySort();MySort.heapSort(array);System.out.println(Arrays.toString(array));
}

堆排序的耗时

交换排序
冒泡排序

冒泡排序:逐轮遍历数组,比较相邻元素并交换逆序对(前元素 > 后元素,升序排序时),每完成一轮遍历,至少有一个 “未归位的最大元素” 会移动到最终位置(数组末尾),因此每轮遍历的范围会逐渐缩小,直到所有元素有序

public static void bubbleSort(int[] array){for (int i = 0; i <array.length-1 ; i++) {boolean flag=false;for (int j = 0; j < array.length-1-i; j++) {if (array[j]>array[j+1]){swap(array,j,j+1);flag=true;}}if (!flag){break;}}
}
public static void main(String[] args) {int[] array={1,24,45,6,2,68,9,5};MySort mySort=new MySort();MySort.bubbleSort(array);System.out.println(Arrays.toString(array));
}
冒泡排序的耗时

快速排序-Hoare版

快速排序:高效的分治排序算法,核心思想通过选择一个 “基准值” 将数组分区,使基准值左侧元素均小于等于它,右侧元素均大于等于它,然后递归处理左右两个子数组,最终实现整体有序

public static void quickSort(int[] array){quick(array,0,array.length-1);
}private static void quick(int[] array, int start, int end) {if (start>=end){return;}int dot=partition(array,start,end);quick(array,start,dot-1);quick(array,dot+1,end);
}private static int partition(int[] array, int left, int right) {int key=array[left];int i=left;while(left<right){while (left<right&&array[right]>=key){right--;}while (left<right&&array[left]<=key){left++;}swap(array,left,right);}swap(array,left,i);return left;
}
public static void main(String[] args) {int[] array={6,1,2,10,7,5,8,9,4,3};MySort mySort=new MySort();MySort.quickSort(array);System.out.println(Arrays.toString(array));
}
快速排序Hoare版的耗时

快速排序-挖坑版
private static void quickDigPit(int[] array, int start, int end) {if (start>=end){return;}int dot=partitionDigPit(array,start,end);quick(array,start,dot-1);quick(array,dot+1,end);
}
private static int partitionDigPit(int[] array,int left,int right){int key=array[left];while (left<right){while (left<right&&array[right]>=key){right--;}array[left]=array[right];while (left<right&&array[left]<=key){left++;}array[right]=array[left];}array[left]=key;return left;
}
public static void main(String[] args) {int[] array={1,24,45,6,2,68,9,5};MySort mySort=new MySort();MySort.quickSortDigPit(array);System.out.println(Arrays.toString(array));
}

快速排序挖坑版的耗时

快速排序的优化——三数取中
private static void quickDigPit(int[] array, int start, int end) {if (start>=end){return;}//三数取中的优化int index=midOfThree(array,start,end);swap(array,start,index);int dot=partitionDigPit(array,start,end);quick(array,start,dot-1);quick(array,dot+1,end);
}private static int midOfThree(int[] array, int left, int right) {int mid=(left+right)/2;if (array[left]<array[right]){if (array[mid]<array[left]){return left;}else if (array[mid]>array[right]){return right;}else {return mid;}}else{if(array[mid]>array[left]){return left;}else if (array[mid]<array[right]){return right;}else {return mid;}}
}
快速排序的优化三数取中的耗时

快速排序的优化——小区间插入排序
private static void quickDigPitInsert(int[] array, int start, int end) {if (start>=end){return;}if (end-start+1<=15){insertQuickSort(array, start,end);return;}int dot=partitionDigPit(array,start,end);quick(array,start,dot-1);quick(array,dot+1,end);
}

快速排序的优化小区间插入排序的耗时
快速排序非递归
public static void nonRecursiveSort(int[]array){int start=0;int end=array.length-1;int dot=partitionDigPit(array,start,end);Deque<Integer> stack=new LinkedList<>();if (dot>start+1){stack.push(start);stack.push(dot-1);}if (dot<end-1){stack.push(dot+1);stack.push(end);}while (!stack.isEmpty()){end=stack.pop();start= stack.pop();dot=partitionDigPit(array,start,end);if (dot>start+1){stack.push(start);stack.push(dot-1);}if (dot<end-1){stack.push(dot+1);stack.push(end);}}
}

归并排序

归并排序:基于分治思想的高效排序算法,核心逻辑是 “先分解再合并”:将数组不断二分拆解为更小的子数组,直到每个子数组只有一个元素(天然有序),然后逐步将有序子数组两两合并,最终得到完整的有序数组

递归实现归并排序
public static void mergeSort(int[] array){decompose(array,0,array.length-1);
}private static void decompose(int[] array, int left, int right) {if (left==right){return;}int mid=(left+right)/2;decompose(array,left,mid);decompose(array,mid+1,right);combination(array,left,mid,right);}private static void combination(int[] array, int left, int mid, int right) {int s1=left;int e1=mid;int s2=mid+1;int e2=right;int[] tempArray=new int[right-left+1];int k=0;while (s1<=e1&&s2<=e2){if (array[s1]<=array[s2]){tempArray[k++]=array[s1++];}else {tempArray[k++]=array[s2++];}}while (s1<=e1){tempArray[k++]=array[s1++];}while (s2<=e2){tempArray[k++]=array[s2++];}for (int i = 0; i <k ; i++) {array[i+left]=tempArray[i];}}

非递归实现归并排序
public static void noRecursiveMergeSort(int[] array){int gap=1;while (gap<array.length){for (int i = 0; i <array.length; i=i+2*gap) {int left=i;int mid=left+gap-1;if (mid>=array.length){mid=array.length-1;}int right=mid+gap;if (right>=array.length){right=array.length-1;}combination(array,left,mid,right);}gap*=2;}
}

计数排序

计数排序:非比较型排序算法,适用于排序整数类型的数据,核心思想是通过统计每个元素的出现次数来确定其在最终有序数组中的位置,无需元素间的比较操作

public static void countSort(int[] array){int max=array[0];int min=array[0];for (int i = 0; i <array.length ; i++) {if(array[i]>max){max=array[i];}if (array[i]<min){min=array[i];}}int[] countArray=new int[max-min+1];int k=0;for (int i = 0; i < array.length; i++) {int index=array[i]-min;countArray[index]++;}for (int i = 0; i <countArray.length ; i++) {while (countArray[i]!=0){array[k]=i+min;k++;countArray[i]--;}}}

排序算法与复杂度的分析

http://www.dtcms.com/a/438700.html

相关文章:

  • [Web网页] Web 基础
  • 做商铺的网站有那些怎么检查网站的死链
  • 网站做qq发送链接广东省建设监理协会网站 - 首页
  • 操作系统应用开发(十八)RustDesk-API服务器数据库——东方仙盟金丹期
  • 济南小型网站建设厦门人才网唯一官方网站
  • 1518. 换水问题
  • 中国空间站完成了多少404错误页面放在网站的哪里
  • 新媒体运营需要哪些技能seo知识分享
  • Java数据类型与字符串操作全解析
  • linux文件系统学习
  • Effective Python 第37条:用组合类实现多层结构,避免嵌套内置类型
  • C语言计算矩阵的逆
  • 如何传递上层变数到编译过的模组当中
  • 广东十大网站建设外贸公司招聘条件
  • C语言类型转换与错误处理
  • 线上宣传方式昆明网络推广优化
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(3):语法 +考え方16+2022年7月N1
  • 51单片机AD/DA
  • 九.寄生参数对变换器参数设计的影响
  • MapSet练习OJ题讲解(2易2中1难)
  • 1.2.1 RAG:构建你的专属知识库
  • 做网站找个人还是公司电商网站建设的意义
  • 网站开发人员定罪成都系统网站建设
  • 小迪web自用笔记49
  • win7 不能安装 scales 1.4.0,ggplot2,无法找到动态链接库的注入点
  • 厦门模板网站极简风格 网站
  • 第四届人工智能与智能信息处理国际学术会议(AIIIP 2025)
  • 网站建设与维护的试卷易点网络科技有限公司
  • wordpress标签调用代码优化师证书
  • 基于ECA-ResNet50的OAM光束相位重建:深度学习在光学涡旋场分析中的突破性应用