快排求逆序数&快排与归并时间复杂度比较

本文参考其他用快排求逆序数的方法。

在用快排求解逆序数前,我先考虑了这个问题,1:归并和快排的时间复杂度都是nlog(n),为什么不用归并?

我认为应该是由于快排在每次合并时都有用到临时数组,然后每次还需要把临时数组重新copy到原数组中 ,增加了时间复杂度;快排虽然也存在最坏的情况,即n^2,但是由于其随机性,所以期望的时间复杂度仍然是nlog(n),因此如果能用快排求逆序数的话,也是不错的。

本文用快排求逆序数思想:

a[10]={7,1,9,5,6,3,11,2,10,8}

7

1

9

5

6

3

11

2

10

9

s1:

1

5

3

2

s2:





7

9

11

10

9

以上比较过程中记录逆序数,时间复杂度nlog(n)。

求得逆序数:2500572073


涉及到的 文件,百度网盘 :http://pan.baidu.com/s/1dFxB64T

#!/usr/bin/env python
# coding:utf8

__author__ = 'yangrui'


fp = open('./Q8.txt', 'r')
lines = fp.readlines()
fp.close()
arr = []
for line in lines:
    line = line.strip('\n')
    arr.append(int(line))

#arr = [7,1,9,5,6,3,11,2,10,8]
count = 0

def SortAndCount(tmp, left, right):
    global count
    if left == right or right == -1:
        return
    if right-left == 1:
        if tmp[right] < tmp[left]:
            count += 1
        return
    s1 = [];s2 = []
    mid = tmp[(right-left)/2]
    flag = 0
    for i in range((right-left)/2):
        if tmp[i] > mid:
            count += 1
            flag += 1
            s2.append(tmp[i])
        elif tmp[i] < mid:
            count += flag
            s1.append(tmp[i])
    for i in range((right-left)/2+1, right+1):
        if tmp[i] > mid:
            s2.append(tmp[i])
            flag += 1
        elif tmp[i] < mid:
            s1.append(tmp[i])
            count += 1+flag
    SortAndCount(s1, 0, len(s1)-1)
    SortAndCount(s2, 0, len(s2)-1)


if __name__ == '__main__':
    SortAndCount(arr, 0, len(arr)-1)
    print(count)





你可能感兴趣的:(算法设计与分析)