Python之排序算法

排序算法

对一序列对象根据某个关键字进行排序。
在这里插入图片描述

常用术语:

  1. 稳定与不稳定
    稳定:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;
    不稳定:如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面;
  2. 内排序与外排序
    内排序:所有排序操作都在内存中完成;
    外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行。

排序算法的性能三大影响因素:

  1. 时间性能(时间复杂度): 一个算法执行所耗费的时间。
  2. 辅助空间 (空间复杂度):运行完一个程序所需内存的大小。
  3. 算法的复杂性 : 算法本身的复杂度,而不是指算法的时间复杂度

在这里插入图片描述

交换排序(冒泡排序,快速排序)

冒泡排序:冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。
在这里插入图片描述

'''
冒泡排序算法的运作如下:
	1. 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
	2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
	这步做完后,最后的元素会是最大的数。
	3. 针对所有的元素重复以上的步骤,除了最后一个。
	4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
'''
def bubbleSort(arr):                                     
    n = len(arr)                                         
                                                         
    # 遍历所有数组元素                                           
    for i in range(n):                                   
                                                         
        # Last i elements are already in place           
        for j in range(0, n-i-1):                        
                                                         
            if arr[j] > arr[j+1] :                       
                arr[j], arr[j+1] = arr[j+1], arr[j]      
                                                         
arr = [64, 34, 25, 12, 22, 11, 90]                       
                                                         
bubbleSort(arr)                                          
                                                         
print ("排序后的数组:")                                        
for i in arr:                                            
    print ("%d" %(i),end=',')                            
---------------------------------------------------
排序后的数组:
11,12,22,25,34,64,90,

快速排序:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。

将‘4’作为第一趟排序的关键字:
在这里插入图片描述

arr=[10,5,2,3]

def Quick_sort(arr):
    if len(arr)<2:
        return arr#基线条件:为空或只包含一个元素的数组是有序的
    else:
        pivot=arr[0]#递归条件
        less=[i for i in arr[1:] if i <= pivot]#由所有小于基准值的元素组成子数组
        greater=[i for i in arr[1:] if i> pivot]#由所有大于基准值的元素组成子数组
        return Quick_sort(less) + [pivot] +Quick_sort(greater)
print(Quick_sort(arr))
-----------------------------------------------------------------------
[2, 3, 5, 10]

插入排序(直接插入,希尔排序)

直接插入(Straight Insertion Sort):将一个记录插入到已经排
好序的有序表中,从而得到一个新的、记录数增 1 的有序表。

'''
步骤:
第一步,a[0]为有序区,待排序区为a[1..n-1]。令i=1。
第二步,将a[1]与a[0]中元素比较,将小的元素放在第一个位置。
第三步,以此类推,直到待排序中全部元素插入完成为止。
'''
import random
def insert_sort(nums):
    """
      # 插入排序
    :param nums:
    :return:
    """
    count = len(nums)
    for i in range(1, count):
        key = nums[i]
        j = i - 1
        while j >= 0:
            if nums[j] > key:
                nums[j + 1] = nums[j]
                nums[j] = key
            j -= 1
    return nums

if __name__ == '__main__':
    nums = [random.randint(1, 200) for i in range(10)]
    sort_nums = insert_sort(nums)
    print(sort_nums)
-------------------------------------------------------------
[6, 8, 34, 46, 50, 53, 75, 114, 160, 177]

希尔排序(Shell Sort):希尔排序是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序通过将全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

一般在记录的数量多的情况下,希尔排序的排序效率较直接插入排序高。
在这里插入图片描述
复杂度
ShellSort的复杂度分析非常复杂,不同gap序列的设计对应不同的复杂度。

最坏时间复杂度:根据步长序列的不同而不同。已知最好的: O(n (logn) ^2)
最优时间复杂度: O(n)
平均时间复杂度:根据步长序列的不同而不同。

选择排序(简单选择排序,堆排序)

简单选择排序:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换;接着对不包括第一个记录以外的其他记录进行第二轮比较,得到最小的记录并与第二个记录进行位置交换;重复该过程,直到进行比较的记录只有一个时为止。

"""
实现过程为: 
(1)将整个记录序列划分为有序区和无序区,初始时,有序区为空,无序区含有待排序的所有记录。 
(2)在无序区中选取关键码最小的记录,将它与无序区中的第一个记录交换,使得有序区扩展了一个记录,同时无序区减少了一个记录。 
(3)不断重复(2),直到无序区只剩下一个记录为止。此时所有的记录已经按关键码从小到大的顺序排列。
"""
def findSmallest(arr):
    smallest = arr[0]#储存最小的值
    smallest_index = 0#存储最小元素的索引
    for i in range(1, len(arr)):
        if arr[i] < smallest:
            smallest = arr[i]
            smallest_index = i
    return smallest_index

def selectionSort(arr):#对数组进行排序
    newArr=[]
    for i in range(len(arr)):
        smallest=findSmallest(arr)#找出数组中最小的元素并将其加入到新数组中
        newArr.append(arr.pop(smallest))
    return newArr

print(selectionSort([5,3,6,2,10]))
-------------------------------------------------------------------------
[2, 3, 5, 6, 10]

堆排序: 堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值。最大的值一定在堆顶。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值