Python 排序

1、冒泡排序

交换过程图示(第一次):

 

我们一共需要进行n-1次冒泡过程

def bubble_sort(list):
    for i in range(len(list)-1,0,-1):
        for j in range(i):
            if(list[j]>list[j+1]):
                list[j+1],list[j]=list[j],list[j+1]

range() 函数可创建一个整数列表,一般用在 for 循环中。  range(start, stop[, step])

参数说明:

  • start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
  • stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
  • step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)

 2、选择排序

     它的工作原理如下:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

      选择排序的主要优点与数据移动有关。如果某个元素位于正确的最终位置上,则它不会被移动。选择排序每次交换一对元素,它们当中至少有一个将被移到其最终位置上,因此对n个元素的表进行排序总共进行至多n-1次交换

排序过程:

                             

def selection_sort(l):
    list = l.copy() #对于列表和字典,参数传递的方式是引用传递。对列表进行拷贝,这样不会改变参数l的值
    n=len(list)
    for i in range(n-1):
        maxidx=i
        for j in range(i+1,n):
            if list[j]>list[maxidx]:
                maxidx=j
        if maxidx!=i:
            list[i],list[maxidx]=list[maxidx],list[i]
    return list

3、插入排序

      插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前 扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

插入排序分析

 

def insert_sort(l):
    list = l.copy()
    # 从第二个位置,即下标为1的元素开始向前插入
    for i in range(1,len(list)):
        # 从第i个元素开始向前比较,如果小于前一个元素,交换位置
        for j in range(i,0,-1):#不包含0
            if list[j]<list[j-1]:
                list[j],list[j-1]=list[j-1],list[j]
    return list

希尔排序

     希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法

      希尔排序的基本思想是:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。

def shell_sort(l):
    list=l.copy()
    gap=len(list)//2
    while gap>0:
        for i in range(gap,len(list)):
            j=i;
            while j>=gap and list[j]<list[j-gap]:
                list[j - gap], list[j] = list[j], list[j - gap]
                j=j-gap
        gap=gap//2
    return list

5、快速排序

    快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。步骤为:

  • 挑选基准值:从数列中挑出一个元素,称为"基准"(pivot);
  • 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
  • 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。

   递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。选取基准值有数种具体方法,此选取方法对排序的时间性能有决定性影响。

def partition(arr,low,high): 
    i = low-1         # 最小元素索引,正确
    pivot = arr[high]       
    for j in range(low , high):   
        # 当前元素小于或等于 pivot 
        if  arr[j] <= pivot:          
            i = i+1 
            arr[i],arr[j] = arr[j],arr[i]   
    arr[i+1],arr[high] = arr[high],arr[i+1] 
    return ( i+1 ) 

# 快速排序函数
def quickSort(arr,low,high): 
    if low < high:  
        pi = partition(arr,low,high)   
        quickSort(arr, low, pi-1) 
        quickSort(arr, pi+1, high) 
  
arr = [10, 7, 8, 9, 1, 5] 
n = len(arr) 
quickSort(arr,0,n-1)

6、归并排序原理

归并排序采用分而治之的原理:

     一、将一个序列从中间位置分成两个序列;

     二、在将这两个子序列按照第一步继续二分下去;

     三、直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再两两合并成一个有序序列即可。

                            

 

def merge_sort( li ):
    #不断递归调用自己一直到拆分成成单个元素的时候就返回这个元素,不再拆分了
    if len(li) == 1:
        return li

    mid = len(li) // 2
    #对拆分过后的左右再拆分 一直到只有一个元素为止,最后一次递归时候ll和lr都会接到一个元素的列表
    ll = merge_sort( li[:mid] )
    rl =merge_sort( li[mid:] )

    # 对返回的两个拆分结果进行排序后合并再返回正确顺序的子列表
    return merge(ll , rl)


def merge( left , right ):#left,right列表本身就是有序的
    # 从两个有顺序的列表里边依次取数据比较后放入result,每次我们分别拿出两个列表中最小的数比较,把较小的放入result
    result = []
    while len(left)>0 and len(right)>0 :
#为了保持稳定性,当遇到相等的时候优先把左侧的数放进结果列表,因为left本来也是大数列中比较靠左的
        if left[0] <= right[0]:
            result.append( left.pop(0) )
        else:
            result.append( right.pop(0) )
    #while循环出来之后 说明其中一个数组没有数据了,我们把另一个数组添加到结果数组后面
    result += left
    result += right
    return result

if __name__ == '__main__':
    li = [5,4 ,3 ,2 ,1]
    li2 = merge_sort(li)
    print(li2)

 left.pop(index) 该方法返回从列表中移除的元素对象。

二分法查找

   二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表。折半查找方法适用于不经常变动而查找频繁的有序列表。

    首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。

                                              

def binary_select(list,item):
    first=0
    last=len(list1)-1

    while last>=first:
        mid = first + last // 2
        if list[mid]==item:
            return mid
        if list[mid]>item:
            last=mid-1
        if list[mid]<item:
            first = mid+1
    return False

from:https://www.cnblogs.com/fwl8888/p/9315730.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值