排序

68 阅读1分钟

3.排序:

1.冒泡排序:

  • 相邻的元素做比较交换

  • 第一次就将最大的元素放到最后(正序)

    for(int i=1;i< arr.length;i++){
        for(int j=0;j< arr.length-i;j++){
            if(arr[j]>arr[j+1]){
                int temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    

2.选择排序:

  • 从第一个元素开始和数组中最小的元素交换

  • 先选出最小的元素下标

    for(int i=0;i< arr.length-1;i++){
        int min=i;
        for(int j=i;j< arr.length;j++){
            if(arr[min]>arr[j]){
                min=j;
            }
        }
        int temp=arr[i];
        arr[i]=arr[min];
        arr[min]=temp;
    }
    

3.插入排序:

  • 将无序中的元素插入有序中,第二层循环逆序实现最小到最前

    for(int i=1;i< arr.length;i++){
        for(int j=i;j>0;j--){
            if(arr[j]<arr[j-1]){
                int temp=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=temp;
            }
        }
    }
    

4.希尔排序(分组的插入排序):

  • 选定一个增长量h,按照增长量h作为数据分组依据,对数据进行分组

  • 对分好组的每一组数据完成插入排序

  • 减少增长量,最小减为1,重复第二步操作

    //希尔排序=分组+插入排序
    for(int index= arr.length/2;index>0;index--){
        for(int i=index;i< arr.length;i++){
            for(int j=i;j>0;j--){
                if(j-index>-1&&arr[j]<arr[j-index]){  //j-index容易越界
                    int temp=arr[j];
                    arr[j]=arr[j-index];
                    arr[j-index]=temp;
                }
            }
        }
    }
    

5.归并排序:

  • 递归

    • 先执行后递归,正序输出
    • 先递归后执行,逆序输出
  • 归并排序

    • 分解:利用先递归后执行,将数组分解成无数小数组(当开始下标等于结束下标时停止)

    • 归并:将小数组作比较,将最小的放入额外数组,将额外数组元素赋予原数组

      public static void sort(int[] arr,int start,int end){
          if(start>=end){
              return;
          }
          int mid=(start+end)/2;
          sort(arr,start,mid);
          sort(arr,mid+1,end);
          Merge(arr,start,mid,end);
      }
      public static void Merge(int[] arr,int left,int mid,int right){
          int[] temp=new int[right-left+1];
          int i=left;int j=mid+1;  //指定两个比较数组开始坐标
          int k=0;
          while(i<=mid&&j<=right){  //比较
              if(arr[i]<arr[j]){
                  temp[k++]=arr[i++];
              }else{
                  temp[k++]=arr[j++];
              }
          }
          //剩余一个数
          while(i<=mid){
              temp[k++]=arr[i++];
          }
          while(j<=right){
              temp[k++]=arr[j++];
          }
          //交换元素给原数组
          for(int t=0;t< temp.length;t++){
              arr[left++]=temp[t];
          }
      }
      

6.快速排序:

image.png

```
public class h快速排序双向扫描 {
    public static void QuickSort2(int[] arr,int start,int end){
        if(start>=end){
            return;
        }
        int index=getIndex2(arr,start,end);  //主元
        QuickSort2(arr,start,index);
        QuickSort2(arr,index+1,end);
    }
    public static int getIndex2(int[] arr,int left,int right){
        int mid=arr[left];  //基准值
        int i=left+1;int j=right;
        while(i<=j){
            while(i<=j&&arr[j]>=mid){   // i<=j是必须
                j--;
            }
            while(i<=j&&arr[i]<=mid){
                i++;
            }
            if(i<j){   //前面运算会出现i>j的情况
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
            }
        }
        //更新主元,交换后数组中arr[j]左边的小,右边的大
        int temp=arr[left];
        arr[left]=arr[j];
        arr[j]=temp;
        return j;
    }
}
```

7.排序的稳定性:

  • 稳定性的定义

    • 数组中A元素和B元素相等,并且A元素在B元素前面;如果使用某排序算法多次排序后,能保证A元素依赖在B元素前面,可以说这个算法是稳定的