七大经典排序算法-python实现总结

算法参考于菜鸟教程https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

'''
1、冒泡排序
'''
def bubbleSort(arr):
    for i in range(1, len(arr)):
        for j in range(0, len(arr)-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

'''
2、选择排序--每次选择最小值
'''
def selectionSort(arr):
    for i in range(len(arr)-1):
        # 记录最小数的索引
        minIndex = i
        for j in range(i+1, len(arr)):
            if arr[j] < arr[minIndex]:
                minIndex = j
        # i 不是最小数时,将i和最小数进行交换
        if i != minIndex:
            arr[i], arr[minIndex] = arr[minIndex], arr[i]
    return arr
'''
3、选择排序--向有序序列中,从后向前插入元素
'''
def insertSort(arr):
    for i in range(len(arr)):
        preIndex = i-1
        current = arr[i]    # 记录要插入的元素
        while preIndex >= 0 and arr[preIndex] > current:        # 从后向前遍历
            arr[preIndex+1] = arr[preIndex]
            preIndex -= 1
        arr[preIndex+1] = current
    return arr

'''
4、希尔排序--先将序列划分成n份,每一份进行插入排序;最后进行整体插入排序
arr = [2,5,7,12,4,1,13,6,8,11,15,9]
res = shellSort(arr)
gap = 4
数据被分成4组--[2,4,8]、[5,1,11]、[7,13,15]、[12,6,9]、
'''
def shellSort(arr):
    import math
    gap = 1
    while(gap < len(arr)/3):
        gap = gap*3+1
    # print(gap)
    while gap > 0:
        for i in range(gap, len(arr)):
            temp = arr[i]
            j = i - gap
            while j >= 0 and arr[j] > temp:
                arr[j+gap] = arr[j]
                j -= gap
            arr[j+gap] = temp
        gap = math.floor(gap/3)

    return arr

'''
5、快速排序--关键点在于partition函数找到pivot
(1)主元选择固定
(2)随机选取主元的快速排序
'''
class QuickSort1(object):
    def quickSort(self, arr, left, right):
        if left < right:
            index = self.partition2(arr, left, right)
            self.quickSort(arr, left, index-1)
            self.quickSort(arr, index+1, right)

    def partition(self, arr, left, right):
        pivot = left
        index = pivot + 1
        i = index
        while i <= right:
            if arr[i] < arr[pivot]:         # 把小于arr[pivot]的值放到左边,大于arr[pivot]的值放到右边
                self.swap(arr, i, index)
                index += 1
            i += 1
        self.swap(arr, pivot, index-1)
        return index-1

    def partition2(self, arr, left, right):
        pivot = arr[left]
        i, j = left, right
        while i < j:
            while i < j and arr[j] >= pivot:     # 从后往前找,找到一个比pivot小的数
                j -= 1
            arr[i] = arr[j]
            while i < j and arr[i] <= pivot:      # 从前往后找,找到一个比pivot大的数
                i += 1
            arr[j] = arr[i]
        arr[i] = pivot                          # i = j
        return i

    def swap(self, arr, i, j):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

class QuickSort2(object):
    def quickSort(self, arr, left, right):
        if left < right:
            index = self.partition2(arr, left, right)
            self.quickSort(arr, left, index-1)
            self.quickSort(arr, index+1, right)

    def partition(self, arr, left, right):
        pivot = left
        index = pivot + 1
        i = index
        while i <= right:
            if arr[i] < arr[pivot]:         # 把小于arr[pivot]的值放到左边,大于arr[pivot]的值放到右边
                self.swap(arr, i, index)
                index += 1
            i += 1
        self.swap(arr, pivot, index-1)
        return index-1

    def partition2(self, arr, left, right):
        pivot = arr[left]
        i, j = left, right
        while i < j:
            while i < j and arr[j] >= pivot:     # 从后往前找,找到一个比pivot小的数
                j -= 1
            arr[i] = arr[j]
            while i < j and arr[i] <= pivot:      # 从前往后找,找到一个比pivot大的数
                i += 1
            arr[j] = arr[i]
        arr[i] = pivot                          # i = j
        return i


    def swap(self, arr, i, j):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

'''
6、堆排序--给定一个数组,建立最小堆
'''
class Heap(object):
    def heapSort(self, arr):
        heapSize = len(arr)
        # 建立最小堆
        self.buildMaxHeap(arr, heapSize)
        # 排序
        for i in range(heapSize-1, 0, -1):
            self.swap(arr, 0, i)
            self.heapify(arr, 0, i)
            # heapSize -= 1
            # self.heapify(arr, 0, heapSize)
        return arr

    def buildMaxHeap(self, arr, heapSize):
        for i in range(heapSize//2, -1, -1):
            self.heapify(arr, i, heapSize)

    def heapify(self, arr, i, heapSize):
        left = 2 * i + 1
        right = 2 * i + 2
        maxIndex = i
        if left < heapSize and arr[left] < arr[maxIndex]:
            maxIndex = left

        if right < heapSize and arr[right] < arr[maxIndex]:
            maxIndex = right

        if maxIndex != i:
            self.swap(arr, i, maxIndex)
            self.heapify(arr, maxIndex, heapSize)

    def swap(self, arr, i , j):
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

# 从头建立一个最小堆,并完成push和pop操作
class Heap2(object):
    def __init__(self):
        self.heap = []

    def _shift_up(self, index):

        while index > 0:
            parent = (index-1) // 2             # 很关键,因为索引是从0开始的,因此需要-1
            if self.heap[parent] < self.heap[index]:
                break
            self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent]
            index = parent

    def _shift_down(self, index):
        while index * 2 + 1 < len(self.heap):   # 还存在左子树
            left = 2 * index + 1
            right = 2 * index + 2
            parent = index
            smallest = parent
            if self.heap[left] < self.heap[smallest]:
                smallest = left
            if right < len(self.heap) and self.heap[right] < self.heap[smallest]:   # important
                smallest = right

            if smallest == parent:
                break

            self.heap[parent], self.heap[smallest] = self.heap[smallest], self.heap[parent]
            index = smallest

    def push(self, data):
        self.heap.append(data)
        self._shift_up(len(self.heap) - 1)  # 对最后一个元素操作

    def pop(self):                          # 堆顶元素和最后一个元素交换, 然后重新建堆
        last = len(self.heap)-1
        self.heap[0], self.heap[last] = self.heap[last], self.heap[0]
        peek = self.heap.pop()              # pop最后一个元素,即将原来的栈顶元素pop出来
        self._shift_down(0)                 # 从0开始调整堆

        return peek


'''
7、归并排序--采用分治法
'''
def mergeSort(arr):
    import math
    if (len(arr)<2):
        return arr
    middle = math.floor(len(arr)//2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))

def merge(left, right):
    result = []
    while left and right:
        if left[0] <= right[0]:         #  保证了归并排序的稳定性
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    return result


'''
8、基数排序--其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较
'''

arr = [2,5,7,12,4,1,13,6,8,11,15,9]
sol = Heap2()
sol.push(5)
sol.push(2)
sol.push(3)
print(sol.heap)
res = sol.pop()
print(sol.heap)
print(res)



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值