排序算法python实现集锦

1. 直接插入排序——升序

#直接插入排序   升序排序
def insert_sort(a):
    length = len(a)
    for i in range(1, length):
        if a[i] < a[i - 1]:
            j= i -1
            temp = a[i]
            while j >= 0 and temp < a[j]:
                a[j + 1] = a[j]
                j -= 1
            a[j + 1] = temp
    return a

print(insert_sort([2, 5, 2, 7, 1, 6]))

是稳定的,时间复杂度o(n^{2}),最好o(n),最差o(n^{2}),空间复杂度o(1)

2. 折半插入排序——升序

#折半插入排序   升序排序
def bi_insert_sort(a):
    length = len(a)
    for i in range(1, length):
        low = 0
        high = i - 1
        temp = a[i]
        while low <= high:
            mid = (low + high) // 2
            if a[mid] <= temp:
                low = mid + 1
            else:
                high = mid - 1
        for j in range(i, low, -1):
            a[j] = a[j - 1]
        a[low] = temp
    return a

print(bi_insert_sort([2, 5, 2, 7, 1, 6]))

折半插入排序算法相比较于直接插入排序算法,只是减少了关键字间的比较次数,而记录的移动次数没有进行优化,所以该算法的时间复杂度仍是o(n^{2})

3. 希尔排序

#希尔排序   升序排序
def shell_sort(a):
    length = len(a)
    interval = length // 2
    while interval > 0:
        for i in range(interval, length):
            j = i - interval
            if a[i] < a[j]:
                temp = a[i]
                while j > -1:
                    if a[j] > temp:
                        a[j + interval] = a[j]
                        j -= interval
                    else:
                        break
                a[j + interval] = temp

        interval = interval // 2
    return a

print(shell_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))

不稳定;

一般的初次取序列的一半为增量,以后每次减半,直到增量为1;

对于关键字的值较小的记录,其前移的过程不是一步一步的,而是跳跃性的前移,并且在最后一次对整表进行插入排序时减少了比较和排序的次数。时间复杂度o(n^{2}),近似为O(N^1.25)

4. 冒泡排序

#冒泡排序   升序排序
def swap(index1, index2, a):
    temp = a[index1]
    a[index1] = a[index2]
    a[index2] = temp
    return a


def soap_sort(a):
    length = len(a)
    for i in range(length):
        for j in range(1, length - i):
            if a[j - 1] > a[j]:
                a = swap(j, j - 1, a)
    return a

print(soap_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))

若表中记录本身为正序存放,则整个排序过程只需进行 n-1(n 为表中记录的个数)次比较,且不需要移动记录;若表中记录为逆序存放(最坏的情况),则需要 n-1趟排序,进行 n(n-1)/2 次比较和数据的移动。所以该算法的时间复杂度为o(n^{2})

5. 快速排序

#快速排序   升序排序
def q_sort(a, low, high):
    temp = a[low]
    start = low
    end = high
    while low < high:
        while low < high and a[high] >= temp:
            high -= 1
        a[low] = a[high]
        while low < high and a[low] <= temp:
            low += 1
        a[high] = a[low]
    a[low] = temp
    if start < low - 1:
        a = q_sort(a, start, low - 1)
    if low + 1 < end:
        a = q_sort(a, low + 1, end)
    return a


def quick_sort(a):
    length = len(a)
    a = q_sort(a, 0, length - 1)
    return a

print(quick_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))

快速排序算法的平均时间复杂度为O(nlogn),是所有时间复杂度相同的排序方法中性能最好的排序算法,不稳定。

最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候,运行时间为o(n^{2})

最好情况是每次划分过程产生的区间大小都为n/2,时间复杂度为O(nlogn)

6. 选择排序

#选择排序   升序排序
def swap(a, index1, index2):
    temp = a[index1]
    a[index1] = a[index2]
    a[index2] = temp
    return a


def select_sort(a):
    length = len(a)
    for i in range(length):
        temp = a[i]
        index = i
        for j in range(i, length):
            if a[j] < temp:
                index = j
                temp = a[j]
        a = swap(a, i, index)
    return a

print(select_sort([49, 38, 64, 97, 76, 13, 27, 49, 55, 4]))

运行时间为o(n^{2}),比较次数没有好坏之分,移动有,稳定。

7. 堆排序

class Solution:
    def __init__(self):
        self.minNums=[]
        self.maxNums=[]
  
    def maxHeapInsert(self,num):
        self.maxNums.append(num)
        lens = len(self.maxNums)
        i = lens - 1
        while i > 0:
            if self.maxNums[i] > self.maxNums[(i - 1) / 2]:
                t = self.maxNums[(i - 1) / 2]
                self.maxNums[(i - 1) / 2] = self.maxNums[i]
                self.maxNums[i] = t
                i = (i - 1) / 2
            else:
                break
  
    def maxHeapPop(self):
        t = self.maxNums[0]
        self.maxNums[0] = self.maxNums[-1]
        self.maxNums.pop()
        lens = len(self.maxNums)
        i = 0
        while 2 * i + 1 < lens:
            nexti = 2 * i + 1
            if (nexti + 1 < lens) and self.maxNums[nexti + 1] > self.maxNums[nexti]:
                nexti += 1
            if self.maxNums[nexti] > self.maxNums[i]:
                tmp = self.maxNums[i]
                self.maxNums[i] = self.maxNums[nexti]
                self.maxNums[nexti] = tmp
                i = nexti
            else:
                break
        return  t
  
    def minHeapInsert(self,num):
        self.minNums.append(num)
        lens = len(self.minNums)
        i = lens - 1
        while i > 0:
            if self.minNums[i] < self.minNums[(i - 1) / 2]:
                t = self.minNums[(i - 1) / 2]
                self.minNums[(i - 1) / 2] = self.minNums[i]
                self.minNums[i] = t
                i = (i - 1) / 2
            else:
                break
  
    def minHeapPop(self):
        t = self.minNums[0]
        self.minNums[0] = self.minNums[-1]
        self.minNums.pop()
        lens = len(self.minNums)
        i = 0
        while 2 * i + 1 < lens:
            nexti = 2 * i + 1
            if (nexti + 1 < lens) and self.minNums[nexti + 1] < self.minNums[nexti]:
                nexti += 1
            if self.minNums[nexti] < self.minNums[i]:
                tmp = self.minNums[i]
                self.minNums[i] = self.minNums[nexti]
                self.minNums[nexti] = tmp
                i = nexti
            else:
                break
        return t

时间复杂度o(nlog\left ( n \right )),空间复杂度o(1),胜在后期每插入一个数字,排好只需要o(log(n))),比较和移动次数没有好坏之分,不稳定。

8. 归并排序

def merge(a, b):
    c = []
    h = j = 0
    while j < len(a) and h < len(b):
        if a[j] < b[h]:
            c.append(a[j])
            j += 1
        else:
            c.append(b[h])
            h += 1

    if j == len(a):
        for i in b[h:]:
            c.append(i)
    else:
        for i in a[j:]:
            c.append(i)

    return c

def merge_sort(lists):
    if len(lists) <= 1:
        return lists
    middle = len(lists)/2
    left = merge_sort(lists[:middle])
    right = merge_sort(lists[middle:])
    return merge(left, right)

print merge_sort([4, 7, 8, 3, 5, 9])

归并排序算法的时间复杂度为O(nlogn),空间复杂度O(n),比较和移动次数没有好坏之分,稳定。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值