美文网首页
基础知识——排序算法python实现

基础知识——排序算法python实现

作者: 不分享的知识毫无意义 | 来源:发表于2019-12-30 22:24 被阅读0次

    本人非计算机专业出身,对于排序算法理解不深,这里先自己通过python实现一下各种排序算法,排名不分先后,难易不分先后,力争能用简单的语言让大家记住各个算法。

    1.归并排序

    采用分治的思路,就是二分法+递归,算法复杂度O(n*logn)。
    这个思路简单说,就是先把数据分左右两份,直到每一份只有两个数据,递归到最内层就是两个数字的比较,然后依次向上合并,每次都是排好序的左右数组的比较。这里需要写两个函数,一个用来排序,一个用来合并。
    最开始的时候,想用一个函数解决,但每次result更新为空,影响了排序结果,所以还是拆分两个函数比较好。

    def merge(left, right):
        result = []    
        i = j = 0
        while i < len(left) and j < len(right):
            if left[i] <= right[j]:
                result.append(left[i])
                i += 1
            else:
                result.append(right[j])
                j += 1
            print(result)
        if i <= len(left):
            result.extend(left[i:])
        if j <= len(right):
            result.extend(right[j:])
        return result
    def guibing(input):
        r = len(input)
        if r<2:
            return input
        mid = r //2
        left = input[0:mid]
        right = input[mid:]
        rleft = guibing(left)
        rright = guibing(right)
        return merge(rleft,rright)
    list1 = [3,5,6,5,3,2,1,5,4,7,8]
    guibing(list1)
    

    2.冒泡排序

    冒泡排序应该算是入门级别的算法了吧,特别好理解。就是来来回回比大小,用两个for循环控制,第一轮比完以后就知道最小(大)的数是哪个了,下次就可以少比较一个。所以有两种写法,一种是从头往后放,一种是从后往前放,算法复杂度是O(n2)。

    def buble(input):
        l = len(input)
        for i in range(l):
            for j in range(i+1,l):
                if input[i] > input [j]:
                    input[i],input[j] = input[j],input[i]
        return input
    

    3.快速排序

    快速排序就是说一个二分法加一个递归,效率会高一点。思路比较好理解吧,随便从列表里选一个数据,以它为基准,比他小就放左边,大就放右边,最后再递归划分,直到就剩一个数据。它的时间复杂度为O(n*logn)。
    2020-02-21补充,这个题我面试遇到了我竟然忘了,看了半天网上的解释,真的是理解不深啊,这里新更新一个解法,就是左右扫描的解法。具体来说就是选择基准后来回扫描发现最大值小于基准值,最小值大于基准值时候二者就交换位置,这样的目的是把基准值排到中间位置,不是数组中间位置而是值的中间位置,就是左边的值都比他小,右边的值都比他大,然后low和tmp交换位置,就实现了基本有序,然后再递归求解。真的是不如解法1方便。

    #解法1
    def quick(input):
        if len(input) < 1:
            return input
        mid = len(input) // 2
        left = []
        right = []
        base = input[mid]
        input.remove(base)
        for i in range(len(input)):
            if input[i] < base:
                left.append(input[i])
            else:
                right.append(input[i])
        return quick(left) + [base] + quick(right)
    #解法2
    def quicksort(x):
        if len(x) <= 1:
            return x
        m = len(x)
        tmp, low, high = 0, 0, m-1
        while low < high:
            while low < high and x[high] >= x[tmp]:
                high -= 1
                # print(1, high)
            while low < high and x[low] <= x[tmp]:
                low += 1
                # print(2, low)
            x[high], x[low] = x[low], x[high]
        x[low], x[tmp] = x[tmp], x[low]
        return quicksort(x[:low]) + [x[low]] + quicksort(x[low+1:])
    

    4.插入排序

    插入排序是根据位置,依次比较排好序,它也是一个双层循环,内层是排好序的数组,外层是整个数组,如果发现当前进数组的数比排好序数组的最后一个元素小,就把这个元素往后移动一位,以此类推。这里有个问题就是,因为是在原来的数组上操作,所以要把当前进排序的数给保存下来,以免排序数组位移的时候把当前数据给覆盖了。

    def insert(input):
        l = len(input)
        for i in range(1,l):
            value = input[i]
            j = i - 1
            while j >= 0:
                if input[j] > value:
                    input[j+1] = input[j]
                else:
                    break
                j -= 1
            input[j+1] = value
        return input
    

    5.选择排序

    选择排序和冒泡排序一样简单,思路就是先选定一个基准数据(从位置0开始),然后比较找到比他还小的最小数,然后交换位置。明显时间复杂度为O(n2)。

    def selectsort(x):
        if len(x) <= 1:
            return x
        for i in range(len(x) - 1):
            minidx = i
            for j in range(i+1, len(x)):
                if x[j] <= x[minidx]:
                    minidx = j
            x[i], x[minidx] = x[minidx], x[i]
        return x
    

    6.堆排序

    堆排序算是比较复杂的一种排序方式了,可以分两步进行,第一步就是构造一个堆,什么是堆呢,堆就是完全二叉树,根节点数据大于(小于)所有的叶子节点数据。构造堆,是一个遍历,自底向上的过程,分别找左右叶子节点的最大值,跟当前跟节点值的比较,比较完成后继续遍历如果大,就更新位置,然后把跟节点值放到相应位置去。然后对排序是从底向上的过程,第一个元素和最后一个元素互换位置,然后重排剔除最后一个元素的堆,使其成为最大堆。

    def max_heap(heap,heapsize,root):
        i, j = root, 2*root+1
        tmp = heap[i]
        while j < heapsize:
            if j + 1 < heapsize and heap[j] < heap[j+1]:
                j = j + 1
            if tmp > heap[j]:
                break
            heap[i] = heap[j]
            i, j = j, 2*j + 1
        heap[i] = tmp
    def build_max_heap(heap):
        heapsize = len(heap)
        for i in range(heapsize//2-1, -1, -1):
            max_heap(heap, heapsize, i)
        return heap
    def heap_sort(heap):
        heapsize = len(heap)
        heap = build_max_heap(heap)
        for i in range(heapsize-1, 0, -1):
            heap[i], heap[0] = heap[0], heap[i]
            max_heap(heap, i, 0)
        return heap
    

    相关文章

      网友评论

          本文标题:基础知识——排序算法python实现

          本文链接:https://www.haomeiwen.com/subject/caudoctx.html