• 算法:排序



    复杂度表:

    冒泡排序、插入排序、选择排序

    快排、归并排序、堆排序

    希尔排序、桶排序、

    (不稳定:选择排序、快排、堆排序)


    463.Sort Integer  整数排序:http://www.lintcode.com/en/problem/sort-integers/

    1.冒泡排序

    两两比较,每趟把最大的数移到最后;

    (外循环,趟数:n-1趟 [0,n-1);

    内循环,有序区趟数,n-1-i;

    比较:[j]>[j+1]则swap;)

     1     public void sortIntegers(int[] a) {
     2         int n = a.length;
     3         for (int i = 0; i < n - 1; i++) {
     4             for (int j = 0; j < n - i - 1; j++) {
     5                 if (a[j] > a[j + 1]) {
     6                     int tmp = a[j];
     7                     a[j] = a[j + 1];
     8                     a[j + 1] = tmp;
     9                 }
    10             }
    11         }
    12     }
    View Code

    参考:为什么冒泡排序最优是O(n)


    2.插入排序

     取出无序区的第一位作为tar,在有序区里从后向前遍历,大于tar则后移;最后把tar值放到最终位置;

    (由于需要j定位;所以:1.j需要定义在外部;2.判断条件在for循环括号内部而不是if语句;)

    (定义j;外循环:无序区的长度/趟数,[1,n)

    定义tar;内循环:[i,0)后序遍历,条件j>0且tar<[j-1];

    后移:[j]=[j-1];定位:a[j] = tar;)

     1 public class Solution {
     2     public void sortIntegers(int[] a) {
     3         int n = a.length;
     4         int j;
     5         for (int i = 1; i < n; i++) {
     6             int tar = a[i];
     7             for (j = i; j > 0 && tar < a[j - 1]; j--) {
     8                 a[j] = a[j - 1];
     9             }
    10             a[j] = tar;
    11         }
    12     }
    13 }
    View Code

    3.选择排序

     每趟从无序区选择最小的值放入有序区的末尾;

    (外循环:n-1趟,[0,n-1); 其中i指向有序区的后一位;

    内循环:扫描无序区 [i+1,n);

    判断:[i]>[j]则swap)

     1 public class Solution {
     2     //选择排序
     3     public void sortIntegers(int[] a) {
     4         int n = a.length;
     5         for (int i = 0; i < n - 1; i++) {
     6             for (int j = i + 1; j < n; j++) {
     7                 if (a[i] > a[j]) {
     8                     int tmp = a[i];
     9                     a[i] = a[j];
    10                     a[j] = tmp;
    11                 }
    12             }
    13         }
    14     }
    15 }
    View Code

    4.快速排序

    每次排序确定一个数的位置。比该数小的移到左边,大的移到右边。

    (例:6-3-7-4-1;lo,hi;pivot为6;注意pivot是值,不是位置;

    首先判断hi<6,那么把1移到lo,即1(lo)-3-7-4-1(hi);

    判断lo<6,lo++,即1-3-7(lo)-4-1(hi);

    此时lo>6,跳出left-while循环,把7移到hi,此时1-3-7(lo)-4-7(hi);可以看到,每次移动都会把上一个移动过的重复的数字覆盖掉。

    继续大while循环: hi>6,hi--,1-3-7(lo)-4(hi)-7;hi<6,把4移动到lo,1-3-4(lo)-4(hi)-7,right-while循环后,lo和hi重合,跳出while循环;

    最后再把pivot放到该位置上[lo]=pivot;并且return 该位置lo;

    这样就完成一轮排序;此时6的位置确定,左右分别为小数和大数)

    (1.主程序:sort(a, 0, len-1);

    2.sort函数:sort(A[], lo, hi),首先判断lo>=hi则return;partition函数;递归;

    3.partition函数:记录pivot;while(<)循环;right-while:判断右侧(&&>),大于则--;否则移动到lo; left-while(&<),小于则++;否则移动到hi;

    4.pivot放到最终位置;返回index-lo;)

    (注意partition内部的while循环一定要加上=key!!否则错误!)

     1 public class Solution {
     2     public void sortIntegers(int[] a) {
     3         sort(a, 0, a.length - 1);
     4     }
     5     public int partition (int[] a, int lo, int hi) {
     6         int key = a[lo];
     7         while (lo < hi) {
     8             while (lo < hi && a[hi] >= key) hi--;
     9             a[lo] = a[hi];
    10             while (lo < hi && a[lo] <= key) lo++;
    11             a[hi] = a[lo];
    12         }
    13         a[lo] = key;
    14         return lo;
    15     }
    16     public void sort(int[] a, int lo, int hi) {
    17         if (lo >= hi) return;
    18         int index = partition(a, lo, hi);
    19         sort(a, lo, index - 1);
    20         sort(a, index + 1, hi);
    21     }
    22 }
    View Code

    5.堆排序


    6.归并排序

    将若干个有序数组合并成一个有序数组称为归并。

    过程:先将数组分成若干小数组并排序,再两两归并成有序数组

    (1.主程序-调用mergeSort(a,low,high);

    2.helper1:mergeSort-当low<high时左右递归,将数组拆成单个元素;归并merge(a, low, mid, high);

    3.helper2:merge-a.tmp数组, 左右指针和k指针; b.当left<=mid和right<=high时,将left和right中小的数保存的tmp中;

    4.while()保存剩余的数;

    5.for(0,tmp.length)覆盖a[i+low]数组)

     1 public class Solution {
     2     /**
     3      * @param A an integer array
     4      * @return void
     5      */
     6     public void sortIntegers(int[] a) {
     7         // Write your code here
     8         mergeSort(a, 0, a.length - 1);
     9     }
    10     public void merge(int[] a, int low, int mid, int high) {
    11         int[] temp = new int[high - low + 1];
    12         int left = low;// 左指针
    13         int right = mid + 1;// 右指针
    14         int k = 0;
    15         // 把较小的数先移到新数组中
    16         while (left <= mid && right <= high) {
    17             if (a[left] < a[right]) {
    18                 temp[k++] = a[left++];
    19             } else {
    20                 temp[k++] = a[right++];
    21             }
    22         }
    23         // 把左边剩余的数移入数组
    24         while (left <= mid) {
    25             temp[k++] = a[left++];
    26         }
    27         // 把右边边剩余的数移入数组
    28         while (right <= high) {
    29             temp[k++] = a[right++];
    30         }
    31         // 把新数组中的数覆盖nums数组
    32         for (int i = 0; i < temp.length; i++) {
    33             a[i + low] = temp[i];
    34         }
    35     }
    36 
    37     public void mergeSort(int[] a, int low, int high) {
    38         int mid = (low + high) / 2;
    39         if (low < high) {
    40             // 左边
    41             mergeSort(a, low, mid);
    42             // 右边
    43             mergeSort(a, mid + 1, high);
    44             // 左右归并
    45             merge(a, low, mid, high);
    46         }
    47 
    48     }
    49 }
    View Code

     参考:归并排序


  • 相关阅读:
    zoj 2110
    zoj 2376 Ants
    zoj 2256 Mincost
    企业版app在iOS8上无法安装的几个问题解决
    源码推荐(8.05):一行代码实现多风格的推送小红点,效果很好的跑马灯
    iOS在支持arc的工程中,导入不支持arc的第三方的插件
    一个异步加载图片的公用类: EGOImageLoading
    一款轻量级的 iOS 图像缓存
    UIGestureRecognizer学习笔记
    IOS两个App应用之间的跳转
  • 原文地址:https://www.cnblogs.com/buwenyuwu/p/6485666.html
Copyright © 2020-2023  润新知