zoukankan      html  css  js  c++  java
  • 算法-排序算法-1

    1. 选择排序 o n平方/o1

      在剩余的数组中选取最小值与数组第一位替换

      缺点是:无论是基本有序的数组还是乱序的数组,使用的时间是一致的

      

     1  public void selectSort(int[] a){
     2         for (int i = 0; i < a.length; i++) {
     3             int min = i;
     4             for (int j = i+1; j < a.length; j++) {
     5                 if (a[min]>a[j]){
     6                     swap(a,min,j);
     7                     min = j;
     8                 }
     9             }
    10         }
    11     }
    1  public void swap(int[] a,int i,int j){
    2         int temp = a[i];
    3         a[i] = a[j];
    4         a[j] = temp;
     
    }
    1 void swap(int[] arr,int i,int j){
    2     int[i] = int[i] ^ int[j];
    3     int[j] = int[i] ^ int[j];
    4     int[i] = int[i]  ^ int[j];  
    5 }

    2. 插入排序(稳定性排序) o n平方/o1

    每次都跟前面排好序的数组进行比较 后面小于前面就互换

    比较适合基本有序的数组 大概比选择排序快1.7倍

    1 public void insertion(int[] a){
    2     for(int i = 1;i<a.length;i++){
    3         for(int j = i;j>0&&a[j]<a[j-1];j--){
    4            swap(a,j,j-1);
    5         }
    6     }
    7 }

    3.希尔排序

    希尔排序是插入排序的进化版,有点像最优子问题一样,先达到大概有序 最后进行一次插入排序

     1 public void shell(int[] a){
     2   
     3   // 先确定一个步长h
     4   int h = a.length/2;
     5 
     6   // 等于1时就是进行一次插入排序 
     7   while(h>=1){
     8     for(int i = h;i<a.lenght;i++){
     9        for(int j = i;j >= h && a[j]<a[j-h];j-=h){
    10             swap(a,j,j-h);
    11         }
    12    }
    13     h/=2;
    14   }  
    15     
    16 }        

     4.冒泡排序(稳定排序) o n平方/o1

      每一轮都得出一个最大的数放最右边

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

     5. 归并排序(稳定排序) o n*logn/o n

      遍历分成两个数组,两个数组双指针合并

     1 public void process(int[] arr, int l, int r) {
     2         if (l == r) {
     3             return;
     4         }
     5         int mid = l + ((r - l) >> 1);
     6          process(arr,l,mid);
     7          process(arr,mid+1, r);
     8          merge(arr,l,mid,r);
     9     }
    10 
    11     public int merge(int[] arr, int l, int mid, int r) {
    12         int p1 = l;
    13         int p2 = mid + 1;
    14         int ret = 0;
    15         int i = 0;
    16         int[] help = new int[r - l + 1];
    17         while (p1 <= mid && p2 <= r) {
    18             // 这一步是计算经过几次调换
    19             ret += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
    20             // 小值移动到数组的左边
    21             help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
    22         }
    23         // 移动剩余值
    24         while (p1 <= mid) {
    25             help[i++] = arr[p1++];
    26         }
    27         while (p2 <= r) {
    28             help[i++] = arr[p2++];
    29         }
    30         // 用辅助内存替换原数组的值
    31         for (i = 0; i < help.length; i++) {
    32             arr[l + i] = help[i];
    33         }
    34         return ret;
    35     }

     6. 快速排序 o n*logn/o logn

      选取一个数,大于这个数的放右边 小于这个数的放左边 等于这个数的放中间 没进行一次确定一批相同值的位置

     1 public void sort(int[] arr, int l, int r) {
     2         if (l < r) {
     3             // 选出随机值
     4             AlUtils.swap(arr, (int) (l + Math.random() * (r - l + 1)), r);
     5             // 荷兰国旗一次
     6             int[] partition = partition(arr, l, r);
     7             // 左区间
     8             sort(arr, l, partition[0] - 1);
     9             // 右区间
    10             sort(arr, partition[1] + 1, r);
    11         }
    12     }
    13 
    14     public int[] partition(int[] arr, int l, int r) {
    15         int less = l - 1;
    16         int more = r;
    17         while (l < more) {
    18             if (arr[l] < arr[r]) {
    19                 // 目标值是r位置的值
    20                 // l位置的值小于目标值, l位置与less下一个值交换 l跳下一个
    21                 AlUtils.swap(arr, l++, ++less);
    22             } else if (arr[l] > arr[r]) {
    23                 // l位置的值大于目标值 l位置与more上一个值交换 l不变
    24                 AlUtils.swap(arr, l, --more);
    25             } else {
    26                 // l位置的值 与目标值一致不变 l跳下一个
    27                 l++;
    28             }
    29         }
    30         // 目标值r位置换到中间位置 r位置的值确定了位置
    31         AlUtils.swap(arr, more, r);
    32         int[] result = {less + 1, more};
    33         return result;
    34     }

     7. 堆排序 o n*logn/o1

      父 (i-1)/2

      左 2*i+1

      右 2*i +2

      

     1  public void heapInsert(int[] arr, int index) {
     2         while (arr[index] > arr[(index - 1) / 2]) {
     3             AlUtils.swap(arr, index, (index - 1) / 2);
     4             index = (index - 1) / 2;
     5         }
     6     }
     7 
     8     public void heapify(int[] arr, int index, int heapSize) {
     9         int left = index * 2 + 1;
    10         while (left < heapSize) {
    11             int largest = left + 1 < heapSize && arr[left] < arr[left + 1] ? left + 1 : left;
    12             largest = arr[index] < arr[largest] ? largest : index;
    13             if (largest == index) {
    14                 break;
    15             }
    16             AlUtils.swap(arr, largest, index);
    17             index = largest;
    18             left = index * 2 + 1;
    19         }
    20     }
    21 
    22     public void sort(int[] arr) {
    23         // 先建立大顶堆
    24         for (int i = 0; i < arr.length; i++) {
    25             heapInsert(arr, i);
    26         }
    27         // 第一个值与最后一个值替换 然后heapify
    28         int heapSize = arr.length;
    29         AlUtils.swap(arr, 0, --heapSize);
    30         // 再替换 知道heapsize小于0
    31         while (heapSize > 0) {
    32             heapify(arr, 0, heapSize);
    33             AlUtils.swap(arr, 0, --heapSize);
    34         }
    35     }
    36 
    37     public void disLessK(int[] arr,int k){
    38         PriorityQueue<Integer> heap = new PriorityQueue<>();
    39         int index = 0;
    40         for (;index<=Math.min(arr.length,k);index++){
    41             heap.add(arr[index]);
    42         }
    43         int i = 0;
    44         for (;index<arr.length;i++,index++){
    45             heap.add(arr[index]);
    46             arr[i] = heap.poll();
    47         }
    48         while (!heap.isEmpty()){
    49             arr[i++] = heap.poll();
    50         }
    51     }

     8. 桶排序(不基于比较的排序)

    统计排序: 创建相同长度的数组,每个数在对应的index+1 最后遍历有值的数组 放入数组

    基数排序: 以10进制为例,创建10个桶(队列),个位数放入对应的队列取出,按十位放入对应队列取出,按百位放入对应的队列取出 取出放入数组 有序

  • 相关阅读:
    普林斯顿《算法》笔记(二)
    集成学习之Boosting —— AdaBoost原理
    Bagging与方差
    js中的深复制与浅复制
    Javascript的异步与单线程
    实现Vue的双向绑定
    什么是mvvm设计模式
    什么是虚拟DOM
    vue源码实现的整体流程解析
    Java基础常见英语词汇
  • 原文地址:https://www.cnblogs.com/isnotnull/p/14845784.html
Copyright © 2011-2022 走看看