排序算法汇总

排序算法汇总

  • 一、冒泡排序
    • 1.算法思想
    • 2. 算法复杂度
    • 3.算法实现
  • 二、选择排序
    • 1.算法思想
    • 2.算法复杂度及优点
    • 3.算法实现
  • 三、插入排序
    • 1.算法思想
    • 2.算法复杂度及优缺点
    • 3.算法实现
  • 四、快速排序
    • 1.算法思想
    • 2.算法复杂度
    • 3.算法实现
  • 参考

一、冒泡排序

1.算法思想

  • 通过相邻元素之间的比较与交换,使值较小的元素逐步从后面移到前面,值较大的元素从前面移到后面。
  • 每一次都会将最大/最小的元素移动到最后。

2. 算法复杂度

  • 理想情况:数组元素的排列符合要求。这样我们只需要遍历比较一次相邻元素之间的大小,因此复杂度为 O ( n ) O(n) O(n)
  • 最坏情况:数组元素的顺序刚好与要求的相反,这样需要逐次遍历,使其符合要求。假设n个元素,第1次遍历,使最大/小的元素放到最后,比较n-1次;第2次遍历,使次大/小的元素到n-1位置。算法复杂度为 O ( n 2 ) O(n^{2}) O(n2)

时间复杂度较高,因此适用于数据量少,特别是数据基本有序的情况下。

3.算法实现

核心代码实现

class Solution:
    def bubbleSort(self, arr):
        for i in range(len(arr)): # 第 i 趟排序
            # 从序列中前 n - i + 1 个元素的第 1 个元素开始,相邻两个元素进行比较
            for j in range(len(arr) - i - 1):
                # 相邻两个元素进行比较,如果前者大于后者,则交换位置
                if arr[j] > arr[j + 1]:
                    arr[j], arr[j + 1] = arr[j + 1], arr[j]
        return arr

    def sortArray(self, nums: List[int]) -> List[int]:
        return self.bubbleSort(nums)

二、选择排序

1.算法思想

  • 将包含n个数的序列,分为已排序部分未排序部分。假设现在已经遍历到第 i i i个元素,已排序部分个数为i-1,未排序部分为n-i+1
  • 每次都是将未排序部分中最大/最小的元素与未排序部分的第一个元素交换位置。
  • 直到未排序部分的元素个数为0即终止。
    排序算法汇总_第1张图片

2.算法复杂度及优点

与数据初始排序无关,总是 O ( n 2 ) O(n^{2}) O(n2)

优点:可以原地操作,不占用其他空间,因此空间复杂度低。
缺点:时间复杂度总是 O ( n 2 ) O(n^{2}) O(n2),适用于数据量少的情况

3.算法实现

class Solution:
    def selectionSort(self, arr):
        for i in range(len(arr) - 1):
            # 记录未排序部分中最小值的位置
            min_i = i
            for j in range(i + 1, len(arr)):
                if arr[j] < arr[min_i]:
                    min_i = j
            # 如果找到最小值的位置,将 i 位置上元素与最小值位置上的元素进行交换
            if i != min_i:
                arr[i], arr[min_i] = arr[min_i], arr[i]
        return arr

    def sortArray(self, nums: List[int]) -> List[int]:
        return self.selectionSort(nums)

三、插入排序

1.算法思想

将整个序列分为两部分:前面i个元素为有序序列,后面 n - i 个元素为无序序列。每一次排序,将无序序列的第 1 个元素,在有序序列中找到相应的位置并插入。

2.算法复杂度及优缺点

算法复杂度为 O ( n 2 ) O(n^{2}) O(n2)

3.算法实现

class Solution:
    def insertionSort(self, arr):
        for i in range(1, len(arr)): # 遍历无序序列。第一个序列为有序的,从第二个元素开始
            temp = arr[i]
            j = i
            # 从右至左遍历有序序列
            while j > 0 and arr[j - 1] > temp:
                arr[j] = arr[j - 1] # 将有序序列中插入位置右侧的元素依次右移一位
                j -= 1
            arr[j] = temp # 将该元素插入到适当位置
        return arr

    def sortArray(self, nums: List[int]) -> List[int]:
        return self.insertionSort(nums)

四、快速排序

参考快速排序(详细讲解)

1.算法思想

假设按照升序排序:
其思想是,

  • 使用一个基准将序列分为两部分,基准的左侧的数据都比基准小,右侧都比基准大。
  • 分别对两个子序列,继续选择基准,将子序列分为小于基准和大于基准两部分。
  • 递归排序各个子序列,使其达到要求

2.算法复杂度

快速排序是一个既高效又不浪费空间的一种排序算法

3.算法实现

class Solution_QuickSort(): # 快速排序
    def __init__(self,nums):
        self.nums = nums
    def quickSort(self,start:int,end:int):
        if start > end:
            return
        i = start  # 左指针
        j = end    # 右指针

        base = self.nums[start]
        while i < j:
            # 先检查右边
            while i<j and self.nums[j]>=base:  # 从右边起,找到小于基准的第一个元素
                j -= 1
            while i<j and self.nums[i]<=base:  # 左边起,找到第一个大于基准的元素
                i += 1
            if i<j:
                self.swap(self.nums,i,j)

        self.swap(self.nums,start,i)  # 找到基准的位置


        self.quickSort(start,j-1) # 对基准左侧序列进行排序
        self.quickSort(j+1,end)  # 对基准右侧序列进行排序


    def swap(self,nums,left,right): # 交换
        nums[left], nums[right] = nums[right], nums[left]


if __name__ == '__main__':

    nums= [11,24,5,32,50,34,54,76]
    print('快速排序前:',nums)
    Sort = Solution_QuickSort(nums)
    Sort.quickSort( 0, len(nums) - 1)
    print('快速排序后:',Sort.nums)

参考

  1. https://algo.itcharge.cn/01.Array/02.Array-Sort/01.Array-Bubble-Sort/
  2. 快速排序(详细讲解)

你可能感兴趣的:(数据结构与算法,排序算法,算法,数据结构)