Java 数组排序

张春  论坛元老 | 2025-1-18 12:59:40 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1032|帖子 1032|积分 3096

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目录
1.Java冒泡排序(Bubble Sort)
1.冒泡排序
2.冒泡排序的算法原理
3.冒泡排序的复杂度和性能
4.形成代码
2.Java快速排序(Quick Sort)
3.Java归并排序(Merge Sort)
4.Java选择排序(Selection Sort)
5.Java直接插入排序
6.Java希尔排序(Shell Sort)

1.Java冒泡排序(Bubble Sort)

1.冒泡排序

冒泡排序(Bubble Sort)是编程中较简单的一种排序算法。它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误,就把它们互换过来。重复地进行走访数列的工作直到没有再需要互换的元素,这也就意味着该数列已经完成排序。
冒泡排序就像气泡从水中出现一样,在气泡排序中最小或最大的数字,取决于我们是按升序还是降序排序数组,气泡朝着数组的开始或结束冒出。
2.冒泡排序的算法原理

1)比较相邻的元素,如果第一个比第二个大,就互换他们两个。
2)对每一对相邻元素做同样的工作,从开始第一对到末端的最后一对,在这一点,最后的元素应该会是最大的数。
3)针对全部的元素重复以上的步骤,除了最后一个。
4)一连对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
3.冒泡排序的复杂度和性能

与其他排序算法,诸如快速排序、归并排序或shell排序相比,冒泡排序表现不佳。这些算法的平均情况复杂度为O(nlogn),而冒泡排序平均情况复杂度为O(n^2)。
在最佳情况下,冒泡排序比具有O(n)性能的快速排序更好。冒泡排序比快速排序或归并排序慢三倍,即使n=100,但它更轻易实现和记忆。
冒泡排序的复杂度和性能如下:
1)冒泡排序最差情况性能O(n^2)
2)冒泡排序最佳情况性能O(n)
3)冒泡排序平均情况性能O(n^2)
4.形成代码

  1. //冒泡排序
  2. public static void bubbleSort(int[] arr) {
  3.     //外层循环用来控制数组循环的圈数
  4.     for(int i=0;i<arr.length-1;i++) {
  5.         //内层循环用来完成元素值比较,把大的元素值互换到后面
  6.         for(int j=0;j<arr.length-1-i;j++) {
  7.             if(arr[j] > arr[j+1]) {
  8.                 int temp = arr[j];
  9.                 arr[j] = arr[j+1];
  10.                 arr[j+1] = temp;
  11.             }
  12.         }
  13.     }
  14.     //输出结果
  15.     for(int n:nums) {
  16.         System.out.println(n);
  17.     }
  18. }
复制代码
例如:
  1. public class Main {
  2.     public static void main(String[] args) {
  3.         int a[] = {6,1,15,32,9};
  4.         for(int i=1;i<a.length;i++) {
  5.             for(int j=0;j<a.length-1;j++) {
  6.                 if(a[j] > a[j+1]) {
  7.                     int temp = a[j];
  8.                     a[j] = a[j+1];
  9.                     a[j+1] = temp;
  10.                 }
  11.             }
  12.         }
  13.         System.out.println("冒泡排序的结果是:");
  14.         for(int temp:a) {
  15.             System.out.print(temp+" ");
  16.         }
  17.     }
  18. }
复制代码
运行结果如下:
  1. 冒泡排序的结果是:
  2. 1 6 9 15 32
复制代码
2.Java快速排序(Quick Sort)

快速排序(Quick Sort)是基于二分思想,对冒泡排序的一种改进。主要思想是建立一个基数,将小于基数的数字放到基数的左边,大于基数的数字放到基数的右边,然后再对这两部分数字进一步排序,从而实现对数组的排序。
优点是服从高,时间复杂度平均为O(nlogn),顾名思义,快速排序是最快的排序算法,泯灭的资源少,最佳情况下,空间复杂度为O(logn),每一次都平分数组的情况,代码较为简单。
缺点是不稳定,初始序列有序或根本有序时,时间复杂度降为O(n^2)。
例如:
  1. public class Main {
  2.     //快排实现方法
  3.     public static void quickRow(int[] array,int low,int high) {
  4.         int i,j,pivot;
  5.         //结束条件
  6.         if(low >= high) {
  7.             return;
  8.         }
  9.         i = low;
  10.         j = high;
  11.         //选择的节点,这里选择的数组的第一数作为节点
  12.         pivot = array[low];
  13.         while(i<j) {
  14.             //从右往左找比节点小的数,循环结束要么找到了,要么i=j
  15.             while(array[j] >= pivot && i<j) {
  16.                 j--;
  17.             }
  18.             //从左往右找比节点大的数,循环结束要么找到了,要么i=j
  19.             while(array[i] <= pivot && i<j) {
  20.                 i++;
  21.             }
  22.             //如果i!=j说明都找到了,就交换这两个数
  23.             if(i<j) {
  24.                 int temp = array[i];
  25.                 array[i] = array[j];
  26.                 array[j] = temp;
  27.             }
  28.         }
  29.         //i==j一轮循环结束,交换节点的数和相遇点的数
  30.         array[low] = array[i];
  31.         array[i] = pivot;
  32.         //数组“分两半”,再重复上面的操作
  33.         quickRow(array,low,i-1);
  34.         quickRow(array,i+1,high);
  35.     }
  36.     public static void main(String[] args) {
  37.         int[] array = {6,17,38,59,2,10};
  38.         int low = 0,high = array.length-1;
  39.         quickRow(array,low,high);
  40.         for (int i : array){
  41.             System.out.println(i);
  42.         }
  43.     }
  44. }
复制代码
运行结果如下:
  1. 2
  2. 6
  3. 10
  4. 17
  5. 38
  6. 59
复制代码
3.Java归并排序(Merge Sort)

归并排序(Merge Sort)是建立在归并操作上的一种有用的稳定的排序算法,该算法是接纳分治法(Divide and Conquer)的一个非常典范的应用。
归并排序将两个有序的子序列合并得到一个完全有序的序列,即先使每个子序列有序,再使子序列段间有序。若将两个有序的列表合并成一个有序的列表,我们称之为二路归并
归并排序的速度仅次于快速排序,时间复杂度为O(nlogn)。其拆分过程中使用了二分思想,是一个递归的过程,为了减少在递归过程中不停开辟空间的问题,我们可以在归并排序之前,先开辟出一个临时空间,在递归过程中统一使用此空间进行归并即可。
例如:
  1. import java.util.Arrays;
  2. public class Main {
  3.     public static void main(String[] args) {
  4.         int[] arr = new int[]{86,23,7,45,19,10};
  5.         int left = 0;
  6.         int right = arr.length-1;
  7.         int[] tem = Arrays.copyOf(arr,arr.length);
  8.         print(arr);
  9.         mergeSort(arr,left,right,tem);
  10.         print(arr);
  11.     }
  12.     public static void mergeSort(int[] arr,int left,int right,int[] tem) {
  13.         if(right-left<1) {
  14.             return;
  15.         }
  16.         int mid = left + (right-left)/2;
  17.         mergeSort(arr,left,mid,tem);
  18.         mergeSort(arr,mid+1,right,tem);
  19.         merge(arr,left,mid,right,tem);
  20.     }
  21.     private static void merge(int[] arr,int left,int mid,int right,int[] tem) {
  22.         int index = 0;
  23.         int l = left,r = mid+1;
  24.         while(l <= mid && r <= right) {
  25.             if(arr[l]<arr[r]) {
  26.                 tem[index++] = arr[l++];
  27.             }else{
  28.                 tem[index++] = arr[r++];
  29.             }
  30.         }
  31.         while(l <= mid) {
  32.             tem[index++] = arr[l++];
  33.         }
  34.         while(r <= right) {
  35.             tem[index++] = arr[r++];
  36.         }
  37.         for(int i=0;i<(right-left+1);i++) {
  38.             arr[left+i] = tem[i];
  39.         }
  40.     }
  41.     private static void print(int[] arr) {
  42.         for (int i : arr) {
  43.             System.out.print(i+"\t");
  44.         }
  45.         System.out.println();
  46.     }
  47. }
复制代码
运行结果如下:
  1. 86  23  7   45  19  10
  2. 7   10  19  23  45  86
复制代码
4.Java选择排序(Selection Sort)

选择排序(Selection Sort)是一种简单直观的排序算法,其算法原理为首先在未排序的序列中找到最小(大)的元素,存放到排序序列的起始位置,然后再从剩余未排序的元素中继续寻找最小(大)的元素,存放到已排序序列的末尾,以此类推,直到全部元素均排序完成。
选择排序一共有“数组数-1”轮排序,每一轮排序又是一个循环,循环的规则如下:
1)先假定当前这轮循环的第一个数是最小数。
2)然后和背面每个数进行比较,如果发现有比当前数更小的数,则重新确定最小数,并得到下标。
3)当遍历到数组的最后时,就得到本轮最小的数。
4)和当前循环的第一个数进行互换。
例如:
  1. import java.util.Arrays;
  2. public class Main {
  3.     public static void main(String[] args) {
  4.         int[] arr = new int[]{19,26,8,35,41,77};
  5.         for(int i=0;i<arr.length-1;i++) { //每次循环都会找出最小的数
  6.             int minIndex = i; //记录最小数的下标
  7.             int minNum = arr[i]; //记录最小数
  8.             for(int j=i+1;j<arr.length;j++) { //每次循环都会找出最小的数
  9.                 if(arr[j]<minNum) { //如果当前数比最小数小,则更新最小数
  10.                     minNum = arr[j]; //更新最小数
  11.                     minIndex = j; //更新最小数的下标
  12.                 }
  13.             }
  14.             arr[minIndex] = arr[i]; //将最小数放到最前面
  15.             arr[i] = minNum; //将标志位放到最小数原来所在的位置
  16.         }
  17.         for(int i=0;i<arr.length;i++) {
  18.             System.out.println(arr[i]);
  19.         }
  20.     }
  21. }
复制代码
运行结果如下:
  1. 8
  2. 19
  3. 26
  4. 35
  5. 41
  6. 77
复制代码
5.Java直接插入排序

直接插入排序是指将一个个待排序的元素插入到前面已经排好序的有序序列中去,直到插完全部元素为止,主要步骤如下:
1)先假设第一个元素已经排好序。
2)然后依次取出还需要进行排序的下一个元素,也就是排序完成的元素背面的下一个元素,取出下一个元素,设为待插入元素,在已经排序的元素序列中从后向前扫描,如果该元素(已排序)大于待插入元素,将该元素移到下一位置。
3)重复步骤2,直到找到已排序的元素小于或者等于待排序元素的位置,插入元素。
4)重复步骤2、步骤3,完成排序。
例如:
  1. import java.util.Arrays;
  2. public class Main {
  3.     public static void main(String args[]) {
  4.         int[] arr = new int[]{17,62,39,52,8,24};
  5.         for(int i=1;i<arr.length;i++) { //从第二个元素开始比较
  6.             int temp = arr[i]; //记录当前元素
  7.             for(int j=i-1;j>=0;j--) { //从最后一个元素开始比较
  8.                 if(arr[j]>temp) { //如果比当前元素大
  9.                     arr[j+1] = arr[j]; //从该处往后所有元素向后移动一位
  10.                     arr[j] = temp; //将当前元素插入到arr[j]中
  11.                 }
  12.             }
  13.         }
  14.         for(int i=0;i<arr.length;i++) {
  15.             System.out.print(arr[i]+" ");
  16.         }
  17.     }
  18. }
复制代码
运行结果如下:
  1. 8 17 24 39 52 62
复制代码
6.Java希尔排序(Shell Sort)

希尔排序(Shell Sort)是插入排序的一种,也是直接插入排序的更高效的改进版本,希尔排序充实利用了插入排序的两个特点:
1)当数据规模小的时间非常高效。
2)当给定数据已经有序时的时间复杂度为O(n)。
以是,Shell排序每次把数据分成多少块,来使用插入排序,而且之后在这多少个小块排好序的情况下把它们合成大一点的小块,继续使用插入排序,不停地合并小块,直到最后一个小块。
这里每次分成多少个小块是通过“增量”来控制的,开始的时间增量较大,接近n/2,从而使得分割出来接近n/2个小块,徐徐的减小“增量”,终极减小到1。
例如:
  1. public class Main {
  2.     public static int count = 0;
  3.     public static void shellSort(int[] data) {
  4.         // 计算出最大的h值
  5.         int h = 1;
  6.         while(h <= data.length / 3) {
  7.             h = h * 3 + 1;
  8.         }
  9.         while(h > 0) {
  10.             for(int i=h;i<data.length;i+=h) {
  11.                 if(data[i] < data[i-h]) {
  12.                     int tmp = data[i];
  13.                     int j = i-h;
  14.                     while(j >= 0 && data[j] > tmp) {
  15.                         data[j+h] = data[j];
  16.                         j -= h;
  17.                     }
  18.                     data[j+h] = tmp;
  19.                     print(data);
  20.                 }
  21.             }
  22.             // 计算出下一个h值
  23.             h = (h - 1) / 3;
  24.         }
  25.     }
  26.     public static void print(int[] data) {
  27.         for(int i=0;i< data.length;i++) {
  28.             System.out.print(data[i]+"\t");
  29.         }
  30.         System.out.println();
  31.     }
  32.     public static void main(String[] args) {
  33.         int[] data = new int[]{4,6,1,9,5,8};
  34.         print(data);
  35.         shellSort(data);
  36.         print(data);
  37.     }
  38. }
复制代码
运行结果如下:
  1. 4   6   1   9   5   8  
  2. 1   4   6   9   5   8  
  3. 1   4   5   6   9   8  
  4. 1   4   5   6   8   9  
  5. 1   4   5   6   8   9
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

张春

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表