zoukankan      html  css  js  c++  java
  • [数据结构与算法] 003—排序算法(Python)

    写在前面

    常见排序算法可以分为两大类:

    • 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序。

    • 线性时间非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。

    排序复杂度

    类别 名称 时间复杂度 稳定性
    插入排序 插入排序(insertion sort) O(n2) 稳定
    插入排序 希尔排序 (shell sort) O(nlogn) 不稳定
    选择排序 选择排序(selection sort) O(n2) 不稳定
    选择排序 堆排序 (heapsort) O(nlogn) 不稳定
    交换排序 冒泡排序(bubble sort) O(n2) 稳定
    交换排序 快速排序(quicksort) O(nlogn) 不稳定
    归并排序 归并排序 (merge sort) O(nlogn) 稳定
    基数排序 基数排序(radix sort) O(n+k) 稳定

    冒泡排序

    它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。

    def bubbleSort(nums):
        for i in range(len(nums) - 1):
            for j in range(len(nums) - i - 1):
                if nums[j] > nums[j + 1]:
                    nums[j], nums[j + 1] = nums[j + 1], nums[j]
        return nums
    
    nums = [2, 1, 34, 4, 6, 3, 6]
    result = bubbleSort(nums)
    print(result)
    
    [1, 2, 3, 4, 6, 6, 34]
    

    选择排序

    每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,

    然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。

    def selectSort(nums):
        for i in range(len(nums) - 1):
            index = i
            for j in range(i + 1, len(nums)):
                if nums[j] < nums[index]:
                    index = j
            if index != i:
                nums[i], nums[index] = nums[index], nums[i]
        return nums
    
    nums = [2, 1, 34, 4, 6, 3, 6]
    result = selectSort(nums)
    print(result)
    
    [1, 2, 3, 4, 6, 6, 34]
    

    插入排序

    每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

    时间复杂度:O(n^2).

    def insertSort1(nums):
        for i in range(1, len(nums)):
            index = nums[i]
            j = i - 1
            while j >= 0 and nums[j] > index:
                nums[j+1] = nums[j]
                j-=1
            nums[j+1] = index
        return nums
    
    nums = [2, 4, 1 ,0, 4, 3, 2, 5]
    result = insertSort1(nums)
    print(result)
    
    [0, 1, 2, 2, 3, 4, 4, 5]
    

    下面方法会遍历到nums[-1],如果nums[-1] > index则进行交换,但是循环结束,nums[0]仍会赋值为index

    def insertSort(nums):
        for i in range(1, len(nums)):
            index = nums[i]
            for j in range(i, -1, -1):
                if index < nums[j - 1]:     #该方法会遍历到nums[-1],如果nums[-1] > index则进行交换,但是循环结束,nums[0]仍会赋值为index
                    nums[j]= nums[j - 1]
                else:
                    break
            nums[j] = index
        return nums
    
    nums = [2, 4, 1 ,0, 4, 3, 2, 5]
    result = insertSort(nums)
    print(result)
    
    [0, 1, 2, 2, 3, 4, 4, 5]
    

    快速排序

    快速排序原理是首先要找到一个中枢,把小于中枢的值放到他前面,
    大于中枢的值放到他的右边,然后再以此方法对这两部分数据分别
    进行快速排序。先看一下代码

    时间复杂度:O(nlgn)

    def quickSort(nums,start,end):
        #判断low是否小于high,如果为false,直接返回
        if start < end:
            i,j = start,end
            #设置基准数
            base = nums[i]
    
            while i < j:
                #如果列表后边的数,比基准数大或相等,则前移一位直到有比基准数小的数出现
                while (i < j) and (nums[j] >= base):
                    j = j - 1
    
                #如找到,则把第j个元素赋值给第个元素i,此时表中i,j个元素相等
                nums[i] = nums[j]
    
                #同样的方式比较前半区
                while (i < j) and (nums[i] <= base):
                    i = i + 1
                nums[j] = nums[i]
            #做完第一轮比较之后,列表被分成了两个半区,并且i=j,需要将这个数设置回base
            nums[i] = base
    
            #递归前后半区
            quickSort(nums, start, i - 1)
            quickSort(nums, j + 1, end)
        return nums
    
    
    nums = [49,38,65,97,76,13,27,49]
    print("Quick Sort: ")
    quickSort(nums,0,len(nums)-1)
    print(nums)
    

    持续更新中..,

  • 相关阅读:
    MySQL数据库设计规范
    Docker安装redis
    Go-用本地时间解析时间字符串
    Docker安装mysql
    docker安装es
    Json官网文档
    leetcode题目和解答集合
    76. 最小覆盖子串
    165. 比较版本号
    958. 二叉树的完全性检验
  • 原文地址:https://www.cnblogs.com/xianeri/p/10186597.html
Copyright © 2011-2022 走看看