zoukankan      html  css  js  c++  java
  • 排序算法总结

    1、选择排序

      选择排序的算法步骤是,从头到尾遍历数组找出最小的值,然后将其与前方未经过排序的第一个数进行交换。重复执行上述步骤直至结束

      该算法需要两次循环,时间复杂度是 O(n2

      代码如下:

    def selection_sort(arr):
        arr_length=len(arr)
        if arr_length<2:
            return arr
        for i in range(arr_length-1):
            min_index=i
            for  j in range(i+1,arr_length):
                if arr[j]<arr[min_index]:
                    min_index=j
            if i!=min_index:
                arr[i],arr[min_index]=arr[min_index],arr[i]
        return arr

    2、冒泡排序

      该算法步骤是,循环比较当前数与下一个数的大小,将大的数放到后面小的数放到前面,这样依次交换,一直到未排序的最后一个数字。经此步骤最大的数字就会 “冒泡” 到最后面。重复持续上述步骤

      该算法时间复杂度为O(n2

      代码如下:

    def bubble_sort(arr):
        arr_length=len(arr)
        if arr_length<2:
            return arr
        for i in range(arr_length-1):
            for j in range(i+1,arr_length):
                if arr[i]>arr[j]:
                    arr[i],arr[j]=arr[j],arr[i]
        return arr

    3、插入排序

      该算法步骤是,循环数组未排序部分,将未排序部分与排序部分比较,找到排序数组中小于等于当前数的位置,将当前数插入其中。

      该算法时间复杂度是 O(n2)

      代码如下:

    def insertion_sort(arr):
        arr_length=len(arr)
        if arr_length<2:
            return arr
        for i in range (arr_length-1):
            pre_index=i-1
            cur_index=i
            while  pre_index>=0 and arr[cur_index]<pre_index:
                arr[pre_index],arr[cur_index]= arr[cur_index],arr[pre_index]
                cur_index=pre_index
                pre_index=cur_index-1
        return arr

    4、希尔排序

      希尔排序可以认为是改进的插入排序,首先设置一个间隔值 gap (gap=3x+1 and gap<arr_length//3).通过间隔将数组分为指定的 m 个数组,依次对该 m 个数组进行插入排序,然后后递减 gap的值(gap=gap//3 ) 重复上述步骤直到gap 为0.

      时间复杂度为 O(nLogn)

      代码如下:

      

    def shell_sort(arr):
        gap=1
        arr_length=len(arr)
        if arr_length<2:
            return arr
        while gap<arr_length//3:
            gap=gap*3+1
        while gap>0:
            for i in range(gap,arr_length):
                pre_index=i-gap
                cur_val=arr[i]
                while pre_index>=0 and arr[pre_index] >cur_val:
                    arr[pre_index+gap]=arr[pre_index]
                    pre_index-=gap
                arr[pre_index+gap]=cur_val
            gap=gap//3
        return arr

    5、归并排序

      归并排序采用分治法,将大列表分为左右两个子列表,依次分下去,直到只剩下一个元素,然后将左右子列表合并。

      时间复杂度 O(nLogn) 空间复杂度 O(n)

      递归法

      

    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
    
    def merge_sort(arr):
        arr_length=len(arr)
        if arr_length<2:
            return arr
        mid=arr_length//2
        left=arr[:mid]
        right=arr[mid:]
        return merge(merge_sort(left),merge_sort(right))

      分治法:

    def merge_sort_iteration(arr):
        arr_length=len(arr)
        i=1
        while i<arr_length:
            left_start=left_end=right_start=right_end=0
            while left_start<=arr_length-i:
                merged=[]
                right_start=left_end=left_start+i
                right_end=left_end+i
                if right_end>arr_length:
                    right_end=arr_length
                left=arr[left_start:left_end]
                right=arr[right_start:right_end]
                while left and right:
                    if left[0]<=right[0]:
                        merged.append(left.pop(0))
                    else:
                        merged.append(right.pop(0))
                
                merged.extend(left if  left else right)
                arr[left_start:right_end]=merged
                left_start+=i*2
            i*=2
        return arr

    6、快速排序

      快速排序也是采用分治法,先选取一个数,默认选取第一个数,将小于该数的数字放入其左边,将大于该数的数字放入右边。在一次对左边和右边重复上述操作。

      时间复杂度 O(nLogn)  空间复杂度 O(Logn)

      代码如下:

      

    def partion(arr,low,high):
        povit_num=arr[low]
        index=low+1
        i=index
        while low<high:
            while low <high and arr[high]>=povit_num :
                high-=1
            arr[low]=arr[high]
            while low<high and  arr[low]<=povit_num:
                low+=1
            arr[high]=arr[low]
        arr[low]=povit_num
        return low
    
    def quick_sort(arr,low=0,high=None):
        if   high is None:
            high=len(arr)-1
        if(low<high):
            pivot=partion(arr,low,high)
            quick_sort(arr,low,pivot-1)
            quick_sort(arr,pivot+1,high)
        return arr

    7、堆排序

      对于 一个序列 {a1,a2,...an} 如果  a[i] >=a[2i+1] a[i]>=a[2i+2] 则为大根堆,即完全二叉树中,非叶子节点的值均大于孩子节点的值,就叫大根堆.

      根据定义可以知道,只要知道了大根堆,就可以直接获取根节点然后在动态调整。重复此步骤即可

      堆排序时间复杂度O(nLogn) 空间复杂度O(1)

    def heap_adjust(arr,start,end):
        firt_num=arr[start]
        index=start*2+1
        while index<=end:
            if index<end  and arr[index]<arr[index+1]:
                index+=1
            if index<=end and  arr[index]<=firt_num:
                break
            arr[start]=arr[index]
            start=index
            index=2*index+1
        arr[start]=firt_num
    
    
    def build_max_heap(arr):
        arr_length=len(arr)
        index=arr_length//2-1
        while index>=0:
            heap_adjust(arr,index,arr_length-1)
            index-=1
    
    
    def heap_sort(arr):
        arr_length=len(arr)
        build_max_heap(arr)
        for i in range(arr_length-1,0,-1):
            arr[i],arr[0]=arr[0],arr[i]
            heap_adjust(arr,0,i-1)
        return arr

    8、计数排序

      计数排序适合数字处于较小区间内,建立一个整数数组作为计数,然后后循环该整数数组,依次将数字放回原始数组中

      计数排序的时间复杂都为:O(n+k),空间复杂度为:O(k)

    def counting_sort(arr,maxVal):
        bucketLen=maxVal+1
        bucket=[0]*bucketLen
        arr_length=len(arr)
        for i in range(arr_length):
            bucket[arr[i]]+=1
        index=0
        for i in range(bucketLen):
            while bucket[i]>0:
                arr[index]=bucket[i]
                index+=1
                bucket[i]-=1
        return   arr
        

    9、桶排序

      桶排序是一种优化的计数排序,需要设计一种函数关系,将给定的数据映射到一定范围内。需要做到尽可能增大桶的数量,并且保证均匀分布

      桶排序的时间复杂度是O(n+k),空间复杂度是 O(n+k)

      代码如下:

    def bucket_sort_2(arr):
        arr_length=len(arr)
        if(arr_length<2):
            return arr
        min_num=min(arr)
        max_num=max(arr)
        bucket_range=(max_num-min_num)/arr_length
        if bucket_range==0:
            return arr
        buckets=[[] for _ in range(arr_length+1)]
        for item in arr:
            buckets[int((item-min_num)//bucket_range)].append(item)
        arr.clear()
        for bucket in buckets:
            arr.extend(sorted(bucket))
        return arr

    10、基数排序

       基数排序实际上和桶排序类似,只不过利用了每位数字作为桶。

      基数排序的时间复杂度为:O(n*K)  空间复杂度为O(n+k)

      代码如下:

      

    def radix_sort(arr):
        radix=0
        arr_len=len(arr)
        if arr_len<2:
            return arr
        max_num=max(arr)
        max_radix=len(str(max_num))
        while radix<max_radix:
            buckets=[[] for _ in range(10)]
            for item in arr:
                buckets[(item//10**max_radix)%10].append(item)
            arr.clear()
            for bucket in buckets:
                if bucket:
                    arr.extend(sorted(bucket))
            max_radix+=1
        return arr

      

  • 相关阅读:
    wordpress通过$wpdb获取一个分类下所有的文章
    WordPress的摘要显示方式
    WordPress简洁的SEO标题、关键词和描述
    WordPress获取特色图像的链接地址
    WordPress的Bootstrap面包屑导航
    destoon 6.0 手机站支持在所有浏览器访问
    dede织梦5.7的安全防护设置
    WordPress主题制作:基础样式文件
    LInux常用到的命令(面试)
    1030 完美数列 (25分) PAT-B
  • 原文地址:https://www.cnblogs.com/Assist/p/15208293.html
Copyright © 2011-2022 走看看