排序小结1

 

1.常用各种排序(限于比较排序)

(1) Insertion:平均时间 O(n^2);最坏时间 O(n^2);空间 O(1);稳定

每次将一个待排的记录插入到前面的已经排好的队列中的适当位置。

$ Insertion-Sort(A)
for j=2 to length[A] do
    key <- A[j]
    i <- j-1
    while i>0 && A[i]>key  do
        A[i+1] <- A[i]
        i--
    A[i+1] <- key

(2) Merge:平均时间 O(nlgn);最坏时间 O(nlgn);空间 O(n);稳定

$ Merge(A,p,q,r)
for i=1 to q-p+1 do L[i] <- A[p+i-1]
for j=1 to r-q do R[j] <- A[q+j]
L[q-p+2] <- R[r-q+1] <- infty
i <- j <- 1
for k=p to r do
    L[i]<=R[j]?A[k]<-L[i++]:A[k]<-R[j++]
$ Merge-Sort(A,p,r)
if p<r  then
    q <- (p+r)/2
    Merge-Sort(A,p,q)
    Merge-Sort(A,q+1,r)
    Merge(A,p,q,r)

(3)Heap:平均时间 O(nlgn);最坏时间 O(nlgn);空间 O(1);不稳定

$ Max-Heapify(A,i)
if Left[i]<=heap-size[A] && A[Left[i]]>A[i]
    then largest <- Left[i]
    else largest <- i
if Right[i]<=heap-size[A] && A[Right[i]]>A[largest]
    then largest <- Right[i]
if largest 不等于 i  then
    exchange A[i] <-> A[largest]
    Max-Heapify(A,largest)
$ Build-Max-Heap(A)
heap-size[A] <- length[A]
for i=length[A]/2 to 1
    Max-Heapify(A,i)
$ Heap-Sort(A)
Build-Max-Heap(A)
for i=length[A] to 2
    exchange A[1] <-> A[i]
    heap-size[A]--
    Max-Heapify(A,1)

衍生的优先级队列算法,下面只介绍最大优先级队列

Insert(S,x):把元素x插入集合S.这一操作可写为S<—SU{x}

$ Heap-Max-Insert(A,key)
heap-size[A] <- heap-size[A]+1
A[heap-size[A]] <- -infinity
Heap-Increase-Key(A,heap-size[A],key)

Maximum(S):返回S中具有最大关键字的元素

$ Heap-Maximum(A)
return A[1]

Extract-Max(S):去掉并返回S中的具有最大关键字的元素

$ Heap-Extract-Max(A)
if heap-size[A]<1 then
        error "heap underflow"
max <- A[1]
A[1] <- A[heap-size[A]]
heap-size[A] <- heap-size[A]-1
Max-Heapify(A,1)
return max

Increase-Key(S,x,k):将元素x的关键字的值增加到k,这里k值不能小于x的原关键字的值

$ Heap-Increase-Key(A,i,key)
if key<A[i]  then error
A[i] <- key
while i>1 && A[Parent(i)]<A[i]  do
        exchange A[i] <-> A[Parent(i)]
        i <- Parent(i)

(4)Quick:平均时间 O(nlgn);最坏时间 O(n^2);空间 O(lgn);不稳定

通过一趟排序将待排的记录分割成独立的两部分,其中一部分记录的关键字均比另一个部分的关键字小,然后再分别对这两个部分记录继续进行排序,以达到整个序列有效。

快排有随机版本,也就是说在partition的时候是随机选取分点值的,这样的话平均效果会好一点,但操作相对复杂而且没有质的飞跃。

clrs的Ex7.2-2表明它对排序对象有多个相同值时候的效果是比较差的,有一种快排的三路变体可以解决这中边界数据。

$ Partition(A,p,r)
x <- A[r]
i <- p-1
for j=p to r-1  do
    if A[j]<=x then
        i++
        exchange A[i] <-> A[j]
exchange A[i+1] <-> A[r]
return i+1
$ Quick-Sort(A,p,r)
if p<r then
    q <- Partition(A,p,r)
    Quick-Sort(A,p,q-1)
    Quick-Sort(A,q+1,r)

快排的三路变体

PARTITION(A,p,r,int& q1, int& q2)  //用指针或者引用返回两个参数
1 x = A[r]	
2 i = p-1
3 for j = p to r - 1
4 	if A[j] <= x
5 		i = i + 1
6 		exchange A[i] with A[j]
7 exchange A[i + 1] with A[r]
8 k= i+1
9 for j = p to i 
10 	if A[j] = x
11		k = k - 1
12 		exchange A[j] with A[k]
13 q1 = k,q2=i+1

2.总结

n比较小的时候,适合插入排序和选择排序

基本有序的时候,适合直接插入排序和冒泡排序

n很大但是关键字的位数较少时,适合 链式基数排序

n很大的时候,适合 快速排序堆排序归并排序

无序的时候,适合 快速排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值