数据结构与算法之排序

排序评价维度

  • 时间复杂度
  • 是否为原地排序(空间复杂度)
  • 是否稳定排序(是否破坏等值元素的原有先后顺序)
  • 总览
    算法复杂度总览表

冒泡排序思路

  • 原则:大数沉底
  • 具体:
    • 从第一个位置往后,相邻元素对比,大数交换
    • 一轮下来保证最后一个元素为本次排序最大数
    • 重复以上操作,依次得到本次排序次大数、第三大数…
    • 以上实现升序排列

插入排序思路

  • 原则:依次插入
  • 具体:
    • 默认第一个元素为已排序列表
    • 从第二个元素开始,遍历已排序列表获取插入位置,插入已排序列表
    • 补充:遍历方向从尾部向前,发现比待插入元素更小元素,则插入位置为该元素之后,并退出当前遍历

选择排序思路

快排思路

  • 递推公式:
quick_sort(p...r) = quick_sort(p...q-1) + quick_sort(q+1...r)
quick_sort终止条件:p >= r
  • 假代码
quick_sort($array, $size) {
	quick_sort_c($array, 0, $size-1);
}
quick_sort_c(&$array, $p, $r) {
	if ($p >= $r) return;
	$q = partition($array, $p, $r); //获取分区点(匹配分区点到正确顺序位置,并返回)
	quick_sort($array, $p, $q-1);
	quick_sort($array, $q+1, $r);
}

归并排序思路

  • 递推公式:
merge_sort(p...r) = merge( merge_sort(p..q) + merge_sort(q+1...r) )
merge_sort终止条件:p >= r
  • 假代码
merge_sort($array, $size) {
	return merge_sort_c($array, 0, $size-1);
}
merge_sort_c($array, $p, $r) {
	if ($p >= $r) return [];
	$q = intval(($p+$r)/2);
	$left = merge_sort_c($array, $p, $q);
	$right = merge_sort_c($array, $q+1, $r);
	return merge($left, $right); //合并两个有序数组
}

桶排序思路

  • 过程:
    • 设定每个桶是一个排序范围
    • 扫描全部元素,把元素归置到不同的桶中(范围内)
    • 每个桶内部自行排序
    • 最后把各桶元素依次串联得到最终结果
  • 适用场景: 数据量大,无法在内存中实现排序,例如:全省高考总分排序等

计数排序思路

  • 评价:计数排序是桶排序特殊情况,一个桶从一个范围变成了一个数,详情举例说明
  • 适用场景:数据范围不大,非负数情况
  • 举例:给8个考生成绩排序,成绩分数范围是0~10
$source = [3,9,0,4,5,2,7,1];
function count_sort($source, $size) {
	if ($size <= 1) return $source;
	//查找最大值
	$max = $source[0];
	for ($i=1; $i<$size; ++$i) {
		if ($max < $source[$i]) $max = $source[$i];
	}
	//建立值范围数组,并计算每个元素个数
	$range = [];
	for ($i=0; $i<=$max; ++$i) {
		$range[$i] = 0;
	}
	for ($i=0; $i<$size; ++$i) {
		++$range[$source[$i]];
	}
	//依次累加
	for ($i=1; $i<=$max; ++$i) {
		$range[$i] += $range[$i-1];
	}
	//排序
	$rs = $source;
	for ($i=0; $i<$size; ++$i) {
		$elem = $source[$i];
		$rs[$range[$elem]-1] = $elem;
		$range[$elem]--;
	}
	return $rs;

基数排序思路

  • 适用场景:手机号排序、词典排序
  • 思路:
    • 针对位依次排序,以手机号排序举例
    • 所有手机号先按照倒数第一个数字排序,使用桶排序或计数排序(数字范围是0~9),复杂度O(n)
    • 在保证稳定排序前提下(数值相同手机号原有先后顺序不变动),所有手机号继续按照倒数第二个数字排序…
    • 重复以上操作11次完成排序,排序结果类似如下:
13781234567
13781311111
13800000000
....

其他

  • 以上是常见的排序算法介绍,排序是算法入门的基础
  • 对运用层来说,编程语言已提供性能高效稳定的排序接口,开发者可直接调用
  • 稳定高效的工业级排序算法不止使用一种排序方法,逻辑更复杂考虑更全面,有需要可以自行阅读源码
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值