【初探】排序算法

来源:互联网 发布:图论及其算法 编辑:程序博客网 时间:2024/05/17 08:54

  • 日期:20160626
  • 作者:i.sshe
  • https://github.com/isshe

【初探】排序算法

1. 基础问题

  • 1.1 各个常见排序算法的思想及关键代码?

2. 基础问题解答

2.1 各个排序算法的思想及关键代码?

代码链接:https://github.com/isshe/Blog/tree/master/7_sort20160624

选择排序的思想:

  • A. 从数据中选择一个最小/最大数据, 和第i个位置数据交换位置.
  • B. 重复A操作,直到所有所有数据都被选择了一次.
  • 关键代码:
    for (i = 0; i < num; i++)    {         smallest = i;         for (j = i; j < num; j++)         {             if (temp_array[j] < temp_array[smallest])             {                 //找最小 or 最大                 smallest = j;             }         }         //交换         tempvalue = temp_array[smallest];         temp_array[smallest] = temp_array[i];         temp_array[i] = tempvalue;    }

插入排序的思想:

  • A. 比较要插入数据value和目标数组array(已经排好序)的元素,从后往前比较,如果比value小/大(看升序降序), 把数组的数据往后移动一格.一直比较直到找到value的合适位置.
  • B.把value插入到数组array中.
  • C.重复AB即可插入多个数据.
  • 关键代码:
     for (i = 0; i < num; i++)     {          position = i;          for(j = i-1; j >= 0; j--)          {              if (data->array[i] < array[j])              {                   position = j;                   array[j+1] = array[j];              }          }          array[position] = data->array[i];     }

归并排序的思想: 分治思想

相关博文:归并排序-自顶向下/自底向上

  • A.分解:把一份数据分为两份。像二分查找那样,mid=(front+rear)/2, 向下取整.(此时分为了[front, mid]和[mid+1, rear]两部分)
  • B.解决:对两部分分别进行递归排序.
  • C.合并:这里是递归合并,从最小的两部分开始一个一个取小的/大的(升序降序),放到目标数组中.
  • 缺点:归并排序不是原地的, 需要拷贝整个数组.
  • 模式:分治法.(将原问题分解为类似的子问题, 递归求解后再合并得到原问题的解)
  • 代码:(归并排序个人个人觉得最精华的地方在于合并)

    void merge(int *array, int front, int rear, int *dst_array){int a = front;   //第一个部分的头int b = (front + rear) / 2; //第一部分的尾int x = b + 1;   //第二部分的头int y = rear;    //第二部分的尾int i = front;   while(a <= b || x <= y){     //这一句是最关键的!是精华!     //合并是:a指向第一部分最小的数据,x指向第二部分最小的;     //比较两个最小,看哪个更小,更小的放到目标数组。     //x>y是为了应付第二部分已经空的情况。(空了就不用比较了,直接把第一部分放目标数组)     if (x > y || (a <= b && array[a] < array[x]))           {         dst_array[i++] = array[a++];     }     else     {          dst_array[i++] = array[x++];     }}//把排序好的放回到原数组for (i = front; i <= rear; i++){     array[i] = dst_array[i];}}

快速排序:分治思想。

  • 相关博文: 【初探】快速排序学习总结
  • 相关博文: 快速排序及三向切分快速排序
  • A. 在数据区域中选择一个基准点k;
  • B. 大于k的放一边A,小于k的放另一边B.
  • C. 再分别在A,B中以相同的策略划分。
    (注:每一次都能排序好一个数据,就是基准点那个)
  • 关键代码:

     while(1) {     while(array[j] >= key && i < j)  //从后往前找比基准小的     {         j--;     }     while(array[i] <= key && i < j)  //从前往后找比基准大的      {          i++;      }       if (i < j)                     //交换      {           temp = array[i];           array[i] = array[j];           array[j] = temp;      }      else      {           break;      }}//这次的交换能排序好一个数据,即基准。 temp = array[j];  array[j] = array[begin]; array[begin] = temp; //分两部分,继续递归 quick_sort(array, begin, j-1); quick_sort(array, j+1, end);

冒泡排序:

  • A. 比较相邻数据;
  • B. 交换数据;(上浮或下沉)
  • C. 以此反复。每次都能排序好一个数据
  • 代码:

    void bubble_sort(int *array, int num){ int    i = 0; int    j = 0; int    temp = 0; for(i = 0; i < num; i++) {     for(j = num-1; j > i; j--) //这里是从下往上。     {          if (array[j] < array[j-1])          {              temp = array[j];              array[j] = array[j-1];              array[j-1] = temp;          }     } }}

堆排序:关键在于最大最小堆的调整,排序只是循环输出第一个数据。【和二叉树/优先队列相关一起写】

3. 参考资料

  • 《算法基础-打开算法之门》
  • 《啊哈!算法》
  • 《算法(第四版)》

    注:处于学习阶段,有理解错误的地方还望告知。感谢!

0 0