在出现较多重复元素时,对于归并排序性能并不会受到影响,但是对于快速排序时间复杂度会由线性对数级别到达平方级别。
出现这一性能下降的原因是对于传统快速排序,每一次切分会将数组分为两部分,这两部分长度越接近效率越高,而在最糟情况,即所有元素值相等,快速排序切分的一部分长度将只有1,导致需要切分N此才能完成,另外每一次分区又要遍历数组,总时间复杂度为for(int i = 0; i < N; i++) {i} (不知道连加符号电脑上怎么打,且拿for循环表示)
三向切分的快速排序:
解决大量重复键的一个方法是把所有和本轮选择的基准值相等元素放在一个区域,即把原数组分为大于基准值,等于基准值,小于基准值三个分区,在之后的排序中只继续分区大于基准值和小于基准值两部分,以防大量重复键分散在不同的递归分区环节降低效率
实现方法:
在原来分区的i指针和gt指针中在加一个lt指针,lt初始指向0索引(基准值),i初始指向1索引
当i位置元素小于基准值时将lt处元素和该元素互换,i右移
i位置元素等于基准值时i右移lt不动
i位置元素大于基准值,gt位置元素小于基准值时,i和gt处元素交换
结束条件:i和gt相遇,此时lt为等于基准值这一分区左端点,gt为右端点
总结:i和gt与普通快速排序移动方式相同,lt在每一次遇到小于基准值的元素时