排序算法(读书笔记)待续。。。

7月28日

今天看了几个以前学过的排序,这里老生常谈了。


 

插入排序

基本思想:取一个数,插入到已排好序的数组中,从末尾比较,把比这个数大的数都往后移一位,比到前面的数比它小为止,把它放进被腾出的这个空位。这样反复插,知道没有数为止,就排好序了。

 


 

希尔排序

基本思想:先确定一个步长,比如数据总长度的一半,这样数组就被分成了2份,把前一半和后一半比(a[0]和a[middle]比,a[1]和a[middle+1]比……a[middle-1]和a[n]比),前面有比后面大的就交换,没有就拉倒;然后减小步长,比如变为上一次步长的1/2,这样数组就被分成了4份,把每组中4个数拿来比(a[0],a[middle/2],a[middle],a[middle+middle/2]比,a[1],a[middle/2+1],a[middle+1],a[middle+middle/2+1]比……a[middle/2-1],a[middle-1],a[middle+middle/2-1],a[n]比),比大小,前后交换,同上;……一直到步长为 1 为止,这时候就相当于插入排序了,但是由于之前的排序,数字之间的跨度只是相邻的大小交换,这样就排好序了。

 


 

冒泡排序

基本思想:这个谭浩强那个老垃圾的书里都有,是学生初学比较上手的一个排序,不过,由于它在执行时间和交换次数上确实没什么好用的,所以,这里只是复习一下吧。这里冒的泡是数组中的最大值,就是从数组开头开始比较,比较相邻的两个数,前面的数要是比后面的大,就换位,再跟后面的比较,把一个最大的数排到数组最后;再从数组开头开始比较,比较相邻的两个数,前面的数要是比后面的大,就换位,再跟后面的比较,把第二大的数排到倒数第二的位置……一直到数组的第一个数,即每次从0到排好序的最后一个数,这最后一个数的位置当然是从数组的n to 1,这样就排好序了。

 


 

选择排序  

基本思想:虽然一个叫冒泡排序,一个叫选择排序,但主要的区别是前者找最大值,排到数组末尾,后者找最小值,选到数组开头,就是说选择排序,每次从没排好序的第一个数到数组的最后一个数,找出最小值,放在没排好序的第一个数的位置,这没排好序的第一个数的位置当然是从数组的1 to n,这样就排好序了。

 


 

快速排序

基本思想:即一般把中间元素作为基准,从左向右查找,把比基准元素小的放在左边,大的放在基准元素的右边。实现时,可以通过两个游标定位,A和B,A对元素进行遍历,B将小元素放在自己的左边,A和B之间为比基准元素大的元素,A之后的元素为尚未判断的元素。

 


 

归并排序

基本思想:可以说与希尔排序有些相似,并且使用分治的思想。希尔排序是改变步长,(1/2)N、(1/4)N……这样比较,是从长到短;归并排序是先把数组分成2、4……份,最后分成两个两个的,这样每2个数比较合并成一个排好序的组,再4个数的两组比较合并成一个排好序的组,再合并,直到整个数组变成两个数组的合并,再进行最后一次比较,合并成一个数组,就排好序了。与希尔排序的区别是,归并排序先切成单个数,再两两、四四、八八合并,希尔排序是先比较成大小两个数组,各自数组再分成大小两个比较,前者,先自上而下,再自下而上,后者,直接自上而下。

 


 

鸡尾酒排序

基本思想:鸡尾酒排序是冒泡排序的一个变形,它与冒泡排序的区别在于,冒泡排序是从左到右依次找出最大的数字。而鸡尾酒排序是从左向右找一次最大的数,在从右向左找一次最小的数,这样来回排序。

 


 

 

堆排序

基本思想:在对最大堆进行根部删除时,把最大堆最后一个元素与根部元素替换,然后将根部元素删除掉。利用这个原理,当删除根部元素后,此元素被放在数组(堆表示最理想的数据结构之一)的最后位置;进行调整后剩余元素还是一个最大堆,再删除根部元素,放在数组倒数第二个位置;依次删除,直到堆中无元素。可以看出,堆排序是在位的,即不需要额外的存储空间。

e.g: 9 6 8 2 5 7 ->  7 6 8 2 5 | 9  ->  8 6 7 2 5 | 9 ->  5 6 7 2 | 8 9 ->  7 6 5 2 | 8 9 ->  2 6 5 | 7 8 9 ->  6 2 5 | 7 8 9 ->  5 2 | 6 7 8 9 ->  2 | 5 6 7 8 9 ->  | 2 5 6 7 8 9

 


 

计数排序

  1. 找出待排序的数组中最大和最小的元素
  2. 统计数组中每个值为i的元素出现的次数,存入数组C的第i
  3. 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
  4. 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
#include <stdlib.h>
void counting_sort(int array[], int size)
{
  int i, min, max;
 
  min = max = array[0];
  for(i = 1; i < size; i++) {
    if (array[i] < min)
      min = array[i];
    else if (array[i] > max)
      max = array[i];
  }
 
  int range = max - min + 1;
  int *count = (int*)malloc(range * sizeof(int));
 
  for(i = 0; i < range; i++)
    count[i] = 0;
 
  for(i = 0; i < size; i++)
    count[ array[i] - min ]++;
 
  int j, z = 0;
  for(i = min; i <= max; i++)
    for(j = 0; j < count[ i - min ]; j++)
      array[z++] = i;
 
  free(count);
}


  


 

二叉查找树排序

基本思想:就是先对一个无序序列构造一个二叉查找树,然后进行其中序优先遍历。

 


 

桶排序

  1. 设置一个定量的阵列当作空桶子。
  2. 寻访序列,并且把项目一个一个放到对应的桶子去。
  3. 对每个不是空的桶子进行排序。
  4. 从不是空的桶子里把项目再放回原来的序列中。

 

拓扑排序

基本思想:方法1、首先需要知道所有节点的入度,将入度为零的点放入结果集;然后将与已处理的节点所指向的节点的入度减一,处理后,如果有入度为零的点,继续上述处理,   直到节点全部放入结果集,或没有入度为0的点。

                    方法2、对入度为0的点,添加一个公共父节点,然后对此树状结构进行深度优先遍历,记录下退出的节点序列,并压入栈中,弹出的栈序列即拓扑有序。

 


 

鸽巢排序

 


 

基数排序

基本思想:类似扑克牌的排序,先排花色再排数字;又比如对0~10000的数进行排序,是先排万位,再排千位……最后排个位,当然也可以反过来,即先排个位……最后排万位。实现方式,可以使用多个桶,按位把数字放入桶中,重新排序,直到各位均已排完序。和桶排序类似。

 


 

Bogo排序

珠排序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值