七种常见排序算法-Python(冒泡、选择、插入、希尔、快速、归并、堆)

Note:参考

1.https://blog.csdn.net/wuzhiwei549/article/details/80654836 java排序

2.https://blog.csdn.net/liang_gu/article/details/80627548  java排序

3.https://blog.csdn.net/u014452812/article/details/82752984 python 冒泡 选择 插入

4.https://blog.csdn.net/qq_34840129/article/details/80638225 python 堆排序

1.冒泡  2.选择  3.插入  4.希尔 5.快速  6.归并  7.堆


冒泡排序(Bubble Sort)

冒泡排序算法的运作如下:

  1. 比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

A.

'''冒泡排序实现从小到大排序'''
a=[12,-57,23,85,56,-123,-456,250]       #测试案例
b=len(a)                                #队列长度
for i in range(b):
    for j in range(b-i-1):              #设置循环次数
        if a[j]>a[j+1]:                 #如果后者比前者小,则交换位置,总是把大的数放到后面
            a[j],a[j+1]=a[j+1],a[j]
print(a)

B.定义函数方法

arr = [7, 4, 3, 67, 34, 1, 8]

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


bubble_sort(arr)
print(arr)  # [1, 3, 4, 7, 8, 34, 67]


'''else'''

if __name__ == "__main__":
    li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    print(li)
    bubble_sort(li)
    print(li)


选择排序(Selection Sort)

选择排序也是一种简单直观的排序算法。它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
 

'''
选择排序
选择排序是每次找出最小的索引,
然后替换数据的位置
'''
 
def select_sort(aList):
    '''选择排序'''
    l = len(aList)
 
    for j in range(l - 1):
        min_index = j
        for i in range(min_index + 1, l - 1):
            if aList[min_index] > aList[i]:
                min_index = i
        # 循环一遍后找到最小的索引
        aList[j], aList[min_index] = aList[min_index], aList[j]
 
 
if __name__ == "__main__":
    li = [9 , 16, 17, 15, 11]
    print(li)
    select_sort(li)
    print(li)


插入排序(Insertion Sort)

具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序

  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描

  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置

  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

  5. 将新元素插入到该位置后

  6. 重复步骤2~5

'''插入排序'''
def insert_sort(aList):
    '''插入排序'''
    n = len(aList)
    for i in range(n):
        j = i
        # print('j= ', j)
        while j > 0:
            if aList[j] < aList[j - 1]:
                aList[j], aList[j - 1] = aList[j - 1], aList[j]
            # print(j)
            j -= 1
        # print(' ')
 
 
if __name__ == "__main__":
    li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
    print(li)
    insert_sort(li)
    print(li)

 


希尔排序(Shell Sort)(插入排序的更高效改进

算法的基本思想是:先将待排记录序列分割成为若干子序列分别进行插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行一次直接插入排序。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:

  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
  • 但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
 

'''设定步长n/2    …递归直到步长为1'''
a = [56,52,-96,-53,23,-789,520]            #测试案例
b = len(a)                                 #列表长度
gap = b // 2                               #初始步长设置为总长度的一半
while gap >= 1:
    for i in range (b):
        j = i
        while j>=gap and a[j-gap] > a[j]:   #在每一组里面进行直接插入排序
            a[j],a[j-gap] = a[j-gap],a[j]
            j-= gap
    gap=gap//2                              #更新步长
print(a)


快速排序(Quick Sort)

快速排序使用分治策略(Divide and Conquer)来把一个序列分为两个子序列。步骤为:

  1. 从序列中挑出一个元素,作为”基准”(pivot).
  2. 把所有比基准值小的元素放在基准前面,所有比基准值大的元素放在基准的后面(相同的数可以到任一边),这个称为分区(partition)操作。
  3. 对每个分区递归地进行步骤1~2,递归的结束条件是序列的大小是0或1,这时整体已经被排好序了。

A.

def quicksort(a, left, right):
    if left>right:
        return -1
    temp=a[left]
    i=left
    j=right
    while i!=j:
        while a[j]>=temp and i<j:
            j-=1
        while a[i]<=temp and i<j:
            i+=1
        if i<j:
            a[i],a[j]=a[j],a[i]
    a[left]=a[i]
    a[i]=temp    
    quicksort(a,left,i-1)
    quicksort(a,i+1,right)


a=[4, 2, 7,8, 0, 1, 5,23]
quicksort(a,0,len(a)-1)
print(a)

B.

#!/usr/bin/python
 
def quicksort(array):
    if len(array) < 2:
        return array
    else:
        pivot = array[0]
        less = [i for i in array[1:] if i <= pivot]
        print(less)
        greater = [i for i in array[1:] if i > pivot]
        print(greater)
 
    return quicksort(less) + [pivot] + quicksort(greater)
 
  
 
if __name__ == '__main__':
    print(quicksort([10,5,3,2,6]))
    

输出:
 
 
[5, 3, 2, 6]# 第一次less
[]#第一次grester
[3, 2]
[6]
[2]
[]
[2, 3, 5, 6, 10] #最终结果 

假定现在要对数字序列 [4, 2, 7,8, 0,1, 5,23] 进行快速排序。
我们假设最左边的编号为i,最左边的编号为j,不失一般性,假定以4作为基准进行排序(每一次总总是让j先出发,向左移动,再让i出发,向右移动)。

  • (一)第一轮排序

j向左出发寻找第一个小于4的数,遇到1的时候停下来;i向右出发寻找第一个大于4的数,遇到7的时候停下来,交换两者的位置,数字序列变为
[4,2,1,8,0,7,5,23]
接下继续让j向左移动,寻找第二个小于4的数,遇到0的时候停下来;让i向右移动,寻找第二个大于4的数,遇到8的时候停下来,交换两者的位置,数字序列变为
[4,2,1,0,8,7,5,23]
此时发现i与j相遇了,第一轮排序结束,调换4和0的位置,数字序列变为
[0,2,1,4,8,7,5,23],
所有小于4的数字都在4的左边,所有大于4的数字都在4的右边。

  • (二)第二轮排序

分别对4左边和4右边的数字序列进行排序处理,首先对4左边的数字序列[0,2,1]排序。
以第一个数字0为基准,j向左出发寻找第一个小于0的数,i向右出发寻找第一个大于0的数,遇到0的时候停下来,如果找到就交换两者的位置,否则不变。数字序列变为[0,2,1],所有小于0的数字都在0的左边,所有大于0的数字都在0的右边。
再对4右边的数字序列[8, 7,5,23]排序。
以第一个数字8为基准,j向左出发寻找第一个小于8的数,遇到5的时候停下来;i向右出发寻找第一个大于8的数,如果找到就交换两者的位置,同时保证i小于j,那么数字序列变为[5,7,8,23]。所有小于8的数字都在8的左边,所有大于8的数字都在8的右边。
总体数字序列变为[0,2,1,4,5,7,8,23]。

  • (三)第三轮排序

好了动手算一算,类似第一和第二轮的排序方法,对0右边的数字序列进行排序,得到[0,1,2];对8左边的数字序列进行排序,得到[5,7,8,23]。第三轮排序结束。
得到最终的排序结果为
[0,1,2,4,5,7,8,23]。
快排过程结束。


归并排序(Merge Sort)

思想:先递归分解数组,再合并数组

原理:将数组分解最小之后,然后合并两个有序数组,基本思想是比较两个数组的最前面的数,谁小就取谁,取完后,将相应的指针后移以为。然后再比较,直到一个数组为空,最后把另一个数组的剩余部分复制过来即可。

'''归并排序'''
 
 
def merge_sort(alist):
    if len(alist) <= 1:
        return alist
    # 二分分解
    num = len(alist) / 2
    left = merge_sort(alist[:num])
    right = merge_sort(alist[num:])
    # 合并
    return merge(left, right)
 
 
def merge(left, right):
    '''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组'''
    # left与right的下标指针
    l, r = 0, 0
    result = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result
 
 
alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]
sorted_alist = merge_sort(alist)
print(sorted_alist)

首先是一个例子

在这里插入图片描述

原序先通过一半一半的拆分,然后:

在这里插入图片描述


堆排序(Heap Sort)

https://blog.csdn.net/qq_34840129/article/details/80638225

堆排序思想:堆顶(小顶堆)的元素是整个堆中最小的元素,将堆顶元素与最后一个元素交换,然后用一次‘向下筛选’将新的堆顶元素移动到堆中正确的位置:即比较堆顶元素与其两个左右子结点的大小,如果堆顶元素最小,则将其保留在堆顶位置,停止;如果左子结点或右子结点最小,则交换堆顶元素与左子结点或右子结点的值,然后再沿着当前路径不断地比较下去,直至最初的堆顶元素在某一次比较中是最小值或者到达叶结点位置。

此外,如果是小顶堆,得到的是降序序列如果是大顶堆,得到的是升序序列

def heap_sort(elems):
    def siftdown(elems, e, begin, end): #向下筛选
        i, j = begin, begin*2+1 #j为i的左子结点
        while j < end:
            if j+1 < end and elems[j] > elems[j+1]: #如果左子结点大于右子结点
                j += 1                              #则将j指向右子结点
            if e < elems[j]: #j已经指向两个子结点中较小的位置,
                break        #如果插入元素e小于j位置的值,则为3者中最小的
            elems[i] = elems[j] #能执行到这一步的话,说明j位置元素是三者中最小的,则将其上移到父结点位置
            i, j = j, j*2+1 #更新i为被上移为父结点的原来的j的位置,更新j为更新后i位置的左子结点
        elems[i] = e #如果e已经是某个子树3者中最小的元素,则将其赋给这个子树的父结点
                     #或者位置i已经更新到叶结点位置,则将e赋给这个叶结点。
        
    end = len(elems)
    for i in range(end//2-1, -1, -1): #构造堆序。
        siftdown(elems, elems[i], i, end)
    for i in range ((end-1), 0,-1): #进行堆排序.i最后一个值为1,不需要到0
        print(elems)
        e = elems[i] #将末尾元素赋给e
        elems[i] = elems[0] #交换堆顶与最后一个元素
        siftdown(elems, e, 0, i)
        
    return(elems)
 
if __name__=="__main__":
    print(heap_sort([5,6,8,1,2,4,9]))

下面用图来解释堆排序的具体过程:

假设最初的无序的列表为[5,6,8,1,2,4,9],经过堆的初始化操作后得到的对堆结构如下:

                   

然后开始进行堆排序,每次都交换堆顶和末尾元素,然后对堆顶元素进行一次向下筛选,带颜色区域为已经排好序的位置,过程如下:

 

 


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
好的,下面是使用Python实现7种排序算法对1000以内的270个随机数进行排序的代码: ```python import random # 生成270个1000以内的随机数 nums = [random.randint(0, 1000) for _ in range(270)] # 冒泡排序 def bubble_sort(nums): n = len(nums) for i in range(n): for j in range(n - i - 1): if nums[j] > nums[j + 1]: nums[j], nums[j + 1] = nums[j + 1], nums[j] return nums # 选择排序 def selection_sort(nums): n = len(nums) for i in range(n): min_index = i for j in range(i + 1, n): if nums[j] < nums[min_index]: min_index = j nums[i], nums[min_index] = nums[min_index], nums[i] return nums # 插入排序 def insertion_sort(nums): n = len(nums) for i in range(1, n): j = i while j > 0 and nums[j] < nums[j - 1]: nums[j], nums[j - 1] = nums[j - 1], nums[j] j -= 1 return nums # 希尔排序 def shell_sort(nums): n = len(nums) gap = n // 2 while gap > 0: for i in range(gap, n): temp = nums[i] j = i while j >= gap and nums[j - gap] > temp: nums[j] = nums[j - gap] j -= gap nums[j] = temp gap //= 2 return nums # 归并排序 def merge_sort(nums): if len(nums) <= 1: return nums mid = len(nums) // 2 left = merge_sort(nums[:mid]) right = merge_sort(nums[mid:]) return merge(left, right) 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 result += left[i:] result += right[j:] return result # 快速排序 def quick_sort(nums): if len(nums) <= 1: return nums pivot = nums[0] left = [x for x in nums[1:] if x < pivot] right = [x for x in nums[1:] if x >= pivot] return quick_sort(left) + [pivot] + quick_sort(right) # 堆排序 def heap_sort(nums): def sift_down(nums, start, end): root = start while True: child = 2 * root + 1 if child > end: break if child + 1 <= end and nums[child] < nums[child + 1]: child += 1 if nums[root] < nums[child]: nums[root], nums[child] = nums[child], nums[root] root = child else: break n = len(nums) for i in range(n // 2 - 1, -1, -1): sift_down(nums, i, n - 1) for i in range(n - 1, 0, -1): nums[0], nums[i] = nums[i], nums[0] sift_down(nums, 0, i - 1) return nums # 输出排序结果 print("冒泡排序结果:", bubble_sort(nums)) print("选择排序结果:", selection_sort(nums)) print("插入排序结果:", insertion_sort(nums)) print("希尔排序结果:", shell_sort(nums)) print("归并排序结果:", merge_sort(nums)) print("快速排序结果:", quick_sort(nums)) print("堆排序结果:", heap_sort(nums)) ``` 注意:以上代码实现了7种排序算法,但是对于乱序数组的排序效率并不相同,具体哪种排序算法更适合哪种排序情况需要根据实际情况具体分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值