• 排序算法小结


            排序算法一直以来是我的心病,这次为了搞定这块内容,进行了一次系统的学习,结合大神的讲解以及个人的总结,梳理了以下的解决方案,顺便给出相关的迁移问题以及解决方案。

    概况:

    排序一般分为选择排序和插入排序这两大类,其余排序都是在这两块上的优化和深入。

    这里不得不提到时间复杂度,虽然为O(n*2),可是在特定的场合下,插入排序还是比较快的,尤其是在近乎有序的情况下,一般在数据量比较小而接近的

    情况下使用比较好。

    插入排序衍生出冒泡排序和希尔排序

    高级排序(O(nlogn)):

    归并排序、快速排序、双路/三路快速排序、堆排序

    下面给出相关的代码实例(python格式):

    选择排序:

    def selectSort(arr):
        """
            选择排序
        """
        for i in range(0,len(arr)):
            # 在[i,n)中选择最小的索引
            min_index = i
            for j in range(i+1,len(arr)):
                if arr[j] < arr[min_index]:
                    min_index = j
            # 交换i与min_index的位置
            # swap(arr[i], arr[min_index]) python中不需要使用这个,内存空间中局部变量无效
            arr[i], arr[min_index] = arr[min_index], arr[i]

    插入排序:

    def insertSort(arr):
        """
            插入排序
        """
        for i in range(1, len(arr)):
            # 选择arr[i]的位置
            a = arr[i]
            j = i
            for j in range(1, i+1)[::-1]:
                # if arr[j-1] > arr[j]:
                #     arr[j-1], arr[j] = arr[j], arr[j-1]
                if arr[j-1] > a:
                    arr[j] = arr[j-1]
                else:
                    break
            arr[j] = a
    

     快速排序:

    def _parition(arr, s, e):
        """
            找拆分位置
            arr[s...index -1]<arr[index] arr[index+1....e]> arr[index]
        """
        #初始第一个
        base = arr[s]
        j = s
        #使得 arr[i+1....j-1]< base and arr[j+1....e]>base
        for i in range(s+1, e+1):
            if arr[i] < base:
                arr[j+1], arr[i] = arr[i], arr[j+1]
                j += 1
        arr[s], arr[j] = arr[j], arr[s]
        return j
    
    
    
    def _quickSort(arr, l, r, n):
        """
            进行快排
        """
        if r < l:
            return
        index = _parition(arr, l, r)
        if index == n:
            return index
    
        _quickSort(arr, l, index-1, n)
        _quickSort(arr, index+1, r, n)
    
    
    def quickSort(arr, n):
        """
            快速排序
        """
        return _quickSort(arr, 0, len(arr)-1, n)
    

      归并排序:

    def __merge_sort(arr, s, mid, e):
        """
            归并arr[s...mid] arr[mid+1....e]
        """
        #初始化归并空间
        merge_arr = [0] * (e-s+1)
        #赋值
        for i in range(s, e+1):
            merge_arr[i-s] = arr[i]
    
        i = s
        j = mid+1
        #归并
        for k in range(s, e+1):
            if i > mid:
                arr[k] = merge_arr[j-s]
                j += 1
            elif j > e:
                arr[k] = merge_arr[i-s]
                i += 1
            elif merge_arr[i-s] <merge_arr[j-s]:
                arr[k] = merge_arr[i-s]
                i += 1
            else:
                arr[k] = merge_arr[j-s]
                j += 1
    
    
    
    def _mergeSort(arr, s, e):
    
        if s >= e:
            return
        #改进数据量小的时候,用插入排序
        if e-s <20:
            insertSort(arr)
            return
        #中间位置
        mid = s + (e-s)//2
        _mergeSort(arr, s, mid)
        _mergeSort(arr, mid+1, e)
        if arr[mid] < arr[mid+1]:
            __merge_sort(arr, s, mid, e)
    
    
    def mergeSort(arr):
        """
            归并排序
        """
        _mergeSort(arr, 0, len(arr)-1)  

    堆排序:

    def MAX_Heapify(heap, HeapSize, root):
        left = 2*root + 1
        right = left + 1
        larger = root
        if left < HeapSize and heap[larger] < heap[left]:
            larger = left
        if right < HeapSize and heap[larger] < heap[right]:
            larger = right
        if larger != root:#如果做了堆调整则larger的值等于左节点或者右节点的,这个时候做对调值操作
            heap[larger],heap[root] = heap[root],heap[larger]
            MAX_Heapify(heap, HeapSize, larger)
    
    
    def Build_MAX_Heap(heap):
        HeapSize = len(heap)#将堆的长度当独拿出来方便
        for i in range((HeapSize -2)//2,-1,-1):#从后往前出数
            MAX_Heapify(heap,HeapSize,i)
    
    
    def heapSort(arr):
        Build_MAX_Heap(arr)
        for i in range(len(arr)-1,-1,-1):
            arr[0],arr[i] = arr[i],arr[0]
            MAX_Heapify(arr, i, 0)
        return arr

    以下是随机生成测试数据和计算排序时长的方式:

    def generArr(l, r, n):
    
        arr = [0] * n
        for i in range(0, n):
            arr[i] = random.randint(l,n)
        return arr
    
    
    def countTime(arr, func = None):
        """
            计算时长
        """
        start = time.time()
        func(arr)
        end = time.time()
        print(func.__name__, '时长{}s'.format(round((end-start), 5)))
    

      计算结果如下:

    def main():
        """
            主函数
        """
        arr = generArr(0, 100, 10000)
        arrs = generArr(0, 100, 10000)
        countTime(arr, mergeSort)
        countTime(arrs, insertSort)
    if __name__ == '__main__':
        main()
    
    
    D:anacondpython.exe E:/cources_python/data_structure/algorithm/sort_demo.py
    mergeSort 时长15.77121s
    insertSort 时长7.39828s
    
    Process finished with exit code 0
    

      

  • 相关阅读:
    使用 C# 2008 Express Edition 编写的猜数字游戏
    话说三层
    在asp.net 1.1 中使用Ajax
    vs2005 调试时出现“无法附加。绑定句柄无效”的解决办法
    解决“你可能没有权限使用网络资源”的问题
    html&js 在firefox与IE中呈现存在差异的解决方法总结
    sql 事务 全攻略
    mssql的TSQL教程(从建登陆到建库、表和约束)(1)
    数据库练习题
    用批处理附加数据库
  • 原文地址:https://www.cnblogs.com/zx-bob-123/p/8610345.html
Copyright © 2020-2023  润新知