目录
排序是指根据某一特定标准,将一组“无序”的数据元素调整为“有序”的数据元素的过程。排序是计算机内经常进行的一种操作,其目的是按照一定的规则(如数字大小、字母顺序等)对数据元素进行重新排列,以便更有效地进行搜索、比较和其他数据处理操作。
常见的排序方法有7种,直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序。
先定义一个交换的方法:
- public static void Swap(int[]array,int i,int j){
- int tmp=array[i];
- array[i]=array[j];
- array[j]=tmp;
- }
直接插入排序逻辑:
从一组数据的第二个元素开始,依次和前面的元素进行比较,找到合适的位置进行插入。
代码如下:
- 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;
- }
-
- }
希尔排序的逻辑:
希尔排序是对直接插入排序的优化,先把数据分组进行预排序,然后再整体排序,可以让排序速度加快。
代码如下:
- 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 selectSort(int[]array){
- for (int i = 0; i < array.length; i++) {
- int mindex=i;
- for (int j = i+1; j < array.length; j++) {
- if (array[j]
- mindex=j;
- }
- }
- Swap(array,i,mindex);
- }
- }
双向选择排序逻辑:
对数组进行遍历,找到数组中的最大值和最小值,将它放在数组的最前面和最后面,然后对剩下数据再进行同样的操作。
代码如下:
- public static void DselectSort(int[]array){
-
- int left=0;
-
- int right=array.length-1;
-
- while (left
- int minIndex=left;
- int maxIndex=left;
-
- for (int i = left+1; i <=right; i++) {
- if (array[i] < array[minIndex]) {
- minIndex = i;
- }
- if (array[i] > array[maxIndex]) {
- maxIndex = i;
- }
- }
-
- Swap(array,minIndex,left);
-
- if (maxIndex==left){
-
- maxIndex=minIndex;
- }
- Swap(array,maxIndex,right);
- left++;
- right--;
- }
- }
四、堆排序
堆排序逻辑:
创建一个大根堆,堆顶元素是最大的,让最大值的元素和最后一个元素进行互换,最大值的元素就被移到了最后,然后把其余元素再排成大根堆,将这次堆顶最大值元素和倒数第二个元素进行互换,以此类推,遍历整个大根堆。
代码如下:
- //创建大根堆
- public static void createHeap(int[]array){
- for (int parent = (array.length-1-1)/2; parent >=0; parent--) {
- siftDown(array,parent,array.length);
- }
- }
-
- //向下调整
- private static void siftDown(int[]array, int parent, int length) {
- int child = 2 * parent + 1;
- while (child < length) {
- if (child + 1 < length && array[child] < array[child + 1]) {
- child = child + 1;
- }
- if (array[child] > array[parent]) {
- Swap(array, child, parent);
- parent = child;
- child = 2 * parent + 1;
- } else {
- break;
- }
- }
- }
- //堆排序
- public static void heapSort (int[] array){
- createHeap(array);
- int end = array.length - 1;
- while (end > 0) {
- Swap(array, 0, end);
- siftDown(array, 0, end);
- end--;
- }
- }
五、冒泡排序
冒泡排序的逻辑:
遍历一组数据,从第一个值开始往后进行遍历,如果顺序错误就进行交换。
代码如下:
- public static void bobbleSort(int[]array){
- for (int i = 0; i < array.length-1; i++) {
- boolean flag=false;
- for (int j = 0; j < array.length-i-1; j++) {
- if (array[j]>array[j+1]){
- Swap(array,j,j+1);
- flag=true;
- }
- }
- if (flag==false){
- break;
- }
- }
- }
六、快速排序
快速排序的逻辑:
在数组中,以第一个值为基准,从后往前找到比基准小的值,然后从前往后找到比基准大的值,然后将这两个值进行交互,当从后往前找和从前往后找相遇时,将相遇的值和基准值进行交换,然后再对数组进行递归。
代码如下:
- 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 pivot=partitionHoare(array,start,end);
- quick(array,start,pivot-1);
- quick(array,pivot+1,end);
- }
-
- private static int partitionHoare(int[]array,int left,int right){
- int tmp=array[left];
- int i=left;
- while (left
- while (left
=tmp){ - right--;
- }
- while (left
- left++;
- }
- Swap(array,left,right);
- }
- Swap(array,i,left);
- return left;
- }
七、归并排序
归并排序的逻辑:
将数组进行不断拆分,拆分到只有一个元素时,然后对元素进行有序的组合。
代码如下:
- public static void mergeSort(int[]array){
- mergeSortFun(array,0,array.length-1);
- }
-
- private static void mergeSortFun(int[] array, int start, int end) {
- if (start>=end){
- return;
- }
- int mid=(start+end)/2;
- mergeSortFun(array,start,mid);
- mergeSortFun(array,mid+1,end);
-
- merge(array,start,mid,end);
-
- }
-
- private static void merge(int[] array, int left, int mid, int right) {
- int s1=left;
- int e1=mid;
- int s2=mid+1;
- int e2=right;
-
- int[]tmpArr=new int[right-left+1];
- int k=0;
-
- while (s1<=e1&&s2<=e2){
- if (array[s1]<=array[s2]){
- tmpArr[k++]=array[s1++];
- }else {
- tmpArr[k++]=array[s2++];
- }
- }
- while (s1<=e1){
- tmpArr[k++]=array[s1++];
- }
- while (s2<=e2){
- tmpArr[k++]=array[s2++];
- }
- for (int i = 0; i < tmpArr.length; i++) {
- array[i+left]=tmpArr[i];
- }
- }
-
相关阅读:
Rust生态系统:探索常用的库和框架
linux du 查看文件夹大小
Nginx配置项调优
IT部门不想每天忙“取数”,花了几百万买系统,还是这个办法有效
MFC列表控件的用法(基于对话框的编程)
CentOS8.2安装Nginx1.23.2
运维面试题1
PFSK164 3BSE021180R1 有源滤波器和无源滤波器的主要区别
传输层协议UDP/TCP中的那些端口
python(牛客)试题解析3 - 困难
-
原文地址:https://blog.csdn.net/2301_80706853/article/details/140463308