• 常见的排序方法


     

    目录

    一、直接插入排序

    二、希尔排序

    三、选择排序

    四、堆排序

    五、冒泡排序

    六、快速排序

    七、归并排序


    排序是指根据某一特定标准,将一组“无序”的数据元素调整为“有序”的数据元素的过程。排序是计算机内经常进行的一种操作,其目的是按照一定的规则(如数字大小、字母顺序等)对数据元素进行重新排列,以便更有效地进行搜索、比较和其他数据处理操作。

       常见的排序方法有7种,直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序。

    先定义一个交换的方法:

    1. public static void Swap(int[]array,int i,int j){
    2. int tmp=array[i];
    3. array[i]=array[j];
    4. array[j]=tmp;
    5. }

    一、直接插入排序

    直接插入排序逻辑:

      从一组数据的第二个元素开始,依次和前面的元素进行比较,找到合适的位置进行插入。

    代码如下:

    1. public static void insertSort(int[]array){
    2. for (int i = 1; i < array.length; i++) {
    3. int tmp=array[i];
    4. int j=i-1;
    5. for (; j >=0 ; j--) {
    6. if (array[j]>tmp){
    7. array[j+1]=array[j];
    8. }else {
    9. break;
    10. }
    11. }
    12. array[j+1]=tmp;
    13. }
    14. }

    二、希尔排序

    希尔排序的逻辑:

         希尔排序是对直接插入排序的优化,先把数据分组进行预排序,然后再整体排序,可以让排序速度加快。

    代码如下:

    1. public static void shellSort(int[]array){
    2. //分组
    3. int gap=array.length;
    4. while (gap>1){
    5. gap/=2;
    6. shell(array,gap);
    7. }
    8. }
    9. //排序
    10. private static void shell(int[] array, int gap) {
    11. for (int i = gap; i < array.length; i++) {
    12. int tmp = array[i];
    13. int j = i - gap;
    14. for (; j >= 0; j-=gap) {
    15. if (array[j] > tmp) {
    16. array[j + gap] = array[j];
    17. } else {
    18. break;
    19. }
    20. }
    21. array[j + gap] = tmp;
    22. }
    23. }

    三、选择排序

    选择排序有单向选择排序和双向选择排序。

    单向选择排序逻辑:

        对数组进行遍历,找到数组中最小的值,将最小值放到数组最前面,然后再找到除这个值之外的最小值放到上一个最小值的后面,以此类推遍历整个数组。

    代码如下:

    1. public static void selectSort(int[]array){
    2. for (int i = 0; i < array.length; i++) {
    3. int mindex=i;
    4. for (int j = i+1; j < array.length; j++) {
    5. if (array[j]
    6. mindex=j;
    7. }
    8. }
    9. Swap(array,i,mindex);
    10. }
    11. }

    双向选择排序逻辑:

      对数组进行遍历,找到数组中的最大值和最小值,将它放在数组的最前面和最后面,然后对剩下数据再进行同样的操作。

    代码如下:

    1. public static void DselectSort(int[]array){
    2. int left=0;
    3. int right=array.length-1;
    4. while (left
    5. int minIndex=left;
    6. int maxIndex=left;
    7. for (int i = left+1; i <=right; i++) {
    8. if (array[i] < array[minIndex]) {
    9. minIndex = i;
    10. }
    11. if (array[i] > array[maxIndex]) {
    12. maxIndex = i;
    13. }
    14. }
    15. Swap(array,minIndex,left);
    16. if (maxIndex==left){
    17. maxIndex=minIndex;
    18. }
    19. Swap(array,maxIndex,right);
    20. left++;
    21. right--;
    22. }
    23. }

    四、堆排序

    堆排序逻辑:

         创建一个大根堆,堆顶元素是最大的,让最大值的元素和最后一个元素进行互换,最大值的元素就被移到了最后,然后把其余元素再排成大根堆,将这次堆顶最大值元素和倒数第二个元素进行互换,以此类推,遍历整个大根堆。

    代码如下:

    1. //创建大根堆
    2. public static void createHeap(int[]array){
    3. for (int parent = (array.length-1-1)/2; parent >=0; parent--) {
    4. siftDown(array,parent,array.length);
    5. }
    6. }
    7. //向下调整
    8. private static void siftDown(int[]array, int parent, int length) {
    9. int child = 2 * parent + 1;
    10. while (child < length) {
    11. if (child + 1 < length && array[child] < array[child + 1]) {
    12. child = child + 1;
    13. }
    14. if (array[child] > array[parent]) {
    15. Swap(array, child, parent);
    16. parent = child;
    17. child = 2 * parent + 1;
    18. } else {
    19. break;
    20. }
    21. }
    22. }
    23. //堆排序
    24. public static void heapSort (int[] array){
    25. createHeap(array);
    26. int end = array.length - 1;
    27. while (end > 0) {
    28. Swap(array, 0, end);
    29. siftDown(array, 0, end);
    30. end--;
    31. }
    32. }

    五、冒泡排序

    冒泡排序的逻辑:

      遍历一组数据,从第一个值开始往后进行遍历,如果顺序错误就进行交换。

    代码如下:

    1. public static void bobbleSort(int[]array){
    2. for (int i = 0; i < array.length-1; i++) {
    3. boolean flag=false;
    4. for (int j = 0; j < array.length-i-1; j++) {
    5. if (array[j]>array[j+1]){
    6. Swap(array,j,j+1);
    7. flag=true;
    8. }
    9. }
    10. if (flag==false){
    11. break;
    12. }
    13. }
    14. }

    六、快速排序

    快速排序的逻辑:

      在数组中,以第一个值为基准,从后往前找到比基准小的值,然后从前往后找到比基准大的值,然后将这两个值进行交互,当从后往前找和从前往后找相遇时,将相遇的值和基准值进行交换,然后再对数组进行递归。

    代码如下:

    1. public static void quickSort(int[]array){
    2. quick(array,0,array.length-1);
    3. }
    4. //快速排序
    5. private static void quick(int[]array,int start,int end){
    6. if (start>=end){
    7. return;
    8. }
    9. int pivot=partitionHoare(array,start,end);
    10. quick(array,start,pivot-1);
    11. quick(array,pivot+1,end);
    12. }
    13. private static int partitionHoare(int[]array,int left,int right){
    14. int tmp=array[left];
    15. int i=left;
    16. while (left
    17. while (left=tmp){
    18. right--;
    19. }
    20. while (left
    21. left++;
    22. }
    23. Swap(array,left,right);
    24. }
    25. Swap(array,i,left);
    26. return left;
    27. }

    七、归并排序

    归并排序的逻辑:

      将数组进行不断拆分,拆分到只有一个元素时,然后对元素进行有序的组合。

    代码如下:

    1. public static void mergeSort(int[]array){
    2. mergeSortFun(array,0,array.length-1);
    3. }
    4. private static void mergeSortFun(int[] array, int start, int end) {
    5. if (start>=end){
    6. return;
    7. }
    8. int mid=(start+end)/2;
    9. mergeSortFun(array,start,mid);
    10. mergeSortFun(array,mid+1,end);
    11. merge(array,start,mid,end);
    12. }
    13. private static void merge(int[] array, int left, int mid, int right) {
    14. int s1=left;
    15. int e1=mid;
    16. int s2=mid+1;
    17. int e2=right;
    18. int[]tmpArr=new int[right-left+1];
    19. int k=0;
    20. while (s1<=e1&&s2<=e2){
    21. if (array[s1]<=array[s2]){
    22. tmpArr[k++]=array[s1++];
    23. }else {
    24. tmpArr[k++]=array[s2++];
    25. }
    26. }
    27. while (s1<=e1){
    28. tmpArr[k++]=array[s1++];
    29. }
    30. while (s2<=e2){
    31. tmpArr[k++]=array[s2++];
    32. }
    33. for (int i = 0; i < tmpArr.length; i++) {
    34. array[i+left]=tmpArr[i];
    35. }
    36. }

  • 相关阅读:
    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