排序算法总结

排序主要用这六种:

O(n^2)的有:冒泡排序、插入排序、选择排序

O(nlogn)的有:快排、归并排序、堆排序

冒泡排序:原理是无序区两两比较,每趟得到一个最大的放在无序区最后;

  算法:外循环是趟数[0,n-1), 内循环是无序区个数[0, n-i-1);循环体是比较[j]和[j+1];

插入排序:是把数组分成有序区和无序区两部分,每次从无序区取出一位作为tar值,从后向前遍历有序区,大于tar则后移,最后放到目标位置;

  算法:外循环是无序区长度[1,n);定义a[i]为tar值;内循环j指向i,比较a[j-1]与tar,大于则往后顺移a[j-1];最后a[j]赋值;

选择排序:也是分为有序区和无序区,每次从无序区选择一位最小的放到有序区末尾;

  算法:外循环是趟数[0,n-1), 内循环是无序区个数[i+1,n);循环体是比较[i]和[j];

快排:每次排序确定一个数的位置,比该数小的移到左边,大的移到右边。一趟快排的算法是:

  • 设置两个首尾指针lo、hi;
  • 以第一个元素作为key值;
  • 从hi向前搜索,如果大于key则hi--,小于key则[lo]=[hi]把[hi]移到前面;
  • 从lo向后搜搜,如果小于key则lo++,大于key则[hi]=[lo]把[lo]移到后面;
  • 重复3、4步骤,直到lo=hi;返回lo位置。

上述过程就是partition函数;以partition函数返回的位置,对左右两边递归。

  算法:(如上)partition(a,lo,hi)函数:定义key,while循环(lo<hi),内部(lo<hi && a[hi]>=key);最后a[lo]赋值,返回lo; sort(a,lo,hi)函数:判断(lo<hi),index,递归;

归并排序:将数组分成若干个小数组,将已有序的数组两两归并得到完全有序数组。每趟归并的算法是:

  • 申请空间tmp[],大小是两个已排数组的和,[hi-lo+1];
  • 设定两个指针,分别指向两个已排数组的起始位置;
  • 比较两个指针元素的值,选择小的元素放到tmp[]里,并移动指针;
  • 重复步骤3,直到某一指针到数组尾;
  • 将另一序列剩下的所有元素复制到tmp[]里;
  • 将tmp[]数组覆盖原num[]数组;

  算法:merge(a,lo,mid,hi)方法:tmp[]数组,左右指针+临时指针,比较两数组小的保存,保存剩余数组,赋值数组;mergeSort(a,lo,hi) mid, if()判断:左右递归,merge();注意左右递归一定是左边(lo,mid),右边(mid+1, hi);因为mid偏左,不然会死循环。

堆排序:堆排序包括两个过程,首先是根据元素建堆,时间复杂度O(n),然后将堆的根节点取出(与最后一个节点交换),将前面N-1个节点进行堆调整。直至所有节点都取出。堆调整时间复杂是O(lgn),调用了n-1次,所以堆排序时间复杂度是O(nlgn);

  • 建堆:建堆是不断调整堆的过程;从len/2出开始调整(最后一个父节点)。最后一层父节点最多下调1次,倒数第二层最多下调2次,顶点最多下调H=logN次。而最后一层父节点共有2^(H-1)个,倒数第二层公有2^(H-2),顶点只有1(2^0)个,所以总共的时间复杂度为s = 1 * 2^(H-1) + 2 * 2^(H-2) + ... + (H-1) * 2^1 + H * 2^0。将H代入后s= 2N - 2 - log2(N),近似的时间复杂度就是O(N)。
  • 调整堆:思想是比较节点i和它的孩子节点left(i),right(i),若i不是最大则调换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值