选择排序(直接选择排序~堆排序)+归并排序

一、选择排序

1、算法原理

每一趟从待排序的记录当中选出最小的元素,顺序放在已经排好序的序列的后面,直到全部记录排序完毕。

2、算法思想

首先找到所有数中最小值的下标;找到最小值的下标与第一个位置的数值交换位置,这样每一次找到的最小值固定在前面;循环操作直到遍历找到所有。

舞蹈之选择排序:http://v.youku.com/v_show/id_XMzMyODk5MDI0.html?from = s1.8-1-1.2

时间复杂度:O(n  ^ 2),由于选择排序每一轮只交换一次,所以其实际性能要优于冒泡排序。

代码演示:

 public static void selectSort(int[] arr){
        for(int i=0;i<arr.length;i++){
            int min=i;
            int j=i+1;
            for(;j<arr.length;j++){
                if(arr[min] > arr[j]){//找出最小值的下标
                  min=j;
                }
            }
            if(min>i) {//将最小值从头开始放
                int temp = arr[i];
                arr[i] = arr[min];
                arr[min] = temp;
            }
        }
    }

二、堆排序

堆排序是一种树形选择排序,是对直接选择排序的有效改进。

1、堆的概念

堆是一颗顺序存储的完全二叉树。完全二叉树中所有的非终端结点的值均不大于(均不小于)其左、右孩子结点的值。

小根堆:每个节点的值小于等于其左、右孩子结点的值。

大根堆:每个节点的值大于等于其左、右孩子结点的值。

2、算法思想

将待排序的序列构造成一个大根堆,此时,整个序列中的最大值就是堆顶的根节点,将其与末尾的元素进行交换,此时,末尾就是最大值,然后将剩余n-1个元素重新构造成一个堆,这样得到n个元素的次小值,如此反复进行执行,就能够得到一个有序的序列了。

时间复杂度:O(nlong2n)                                                           空间复杂度:O(1)

3、算法步骤

步骤一:构建初始堆。将给定的无序的序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)

此时,我们就将无序数组构造成了一个大顶堆。

步骤二:将堆顶元素和末尾的元素进行交换,使得末尾的元素最大,然后继续调整堆,再将堆顶元素和末尾的元素进行交换,得到第二大元素。如此反复进行交换、重建、交换。

  

代码演示:

public static void adjust(int[] arr, int start, int end) {
        int temp=arr[start];
        for(int i=2*start+1;i<=end;i=2*i+1){
            if(i+1<=end && arr[i]<arr[i+1]){
                i++;//i保存左右结点的较大值的下标
            }
            if(temp<arr[i]){
                arr[start]=arr[i];
                start=i;
            }else{
                break;
            }
        }
        arr[start]=temp;
    }
    public static void heapSort(int[] arr){
        int i=0;
        for(i=(arr.length-1-1)/2;i>=0;i--){//i代表要调整的根节点的下标
            adjust(arr,i,arr.length-1);//建立最大堆
        }
        int temp=0;
        for(i=0;i<arr.length;i++){
            temp=arr[0];//根保存最大值
            arr[0]=arr[arr.length-i-1];//arr[0]赋值为当前待排序的最后一个值
            arr[arr.length-1-i]=temp;
            adjust(arr,0,arr.length-1-i-1);
        }
    }

三、归并排序

1、算法原理

对于给定的一组记录,利用递归和分治技术将数据序列划分成为越来越小的半子表,再对半子表进行排序,最后再用递归的方法将排好序的半子表合并成为有序序列。

舞蹈之归并排序:http://v.youku.com/v_show/id_XMzMyODk5Njg4.html?from = s1.8-1-1.2

2、算法思想

将数据集合两分拆开;循环拆分至每组只剩一个为止;将拆分的数组进行排序组合;两两合并,直至合并成为一个数组。

具体的过程示意如下图:

代码演示:

      public static void mergeSort(int[] arr,int low,int mid,int high) {
          int i=low;
          int j=mid+1;

          int[] temp=new int[high-low+1];
          int k=0;

          while(i<=mid && j<=high){
              if(arr[i]<arr[j]){
                  temp[k++]=arr[i++];
              }else if(arr[i]>arr[j]){
                  temp[k++]=arr[j++];
              }
          }
          while(i<=mid){
              temp[k++]=arr[i++];
          }
          while(j<=high){
              temp[k++]=arr[j++];
          }
          for(int k2=0;k2<temp.length;k2++){
              arr[k2+low]=temp[k2];
          }
      }
      public static void merge(int[] arr,int low,int high){
          int mid=(low+high)/2;
          if(low<high){
              merge(arr,low,mid);
              merge(arr,mid+1,high);

              mergeSort(arr,low,mid,high);
          }
      }

猜你喜欢

转载自blog.csdn.net/qq_40303781/article/details/83309551