Bootstrap

Leetcode刷题09-排序

排序

基础知识

1.简介

排序:将一组无序的记录序列按照某种逻辑顺序重新排序,调整为有序的记录序列的过程。

2.排序算法分类:

由于待排序的记录数量不同,使得排序过程中涉及的存储器不同,可将排序算法分为两大类:

  • 内部排序算法:当参加排序的数据量不大时,在排序过程中将全部记录存放在内存中处理
  • 外部排序算法:当参加排序的数据量较大时,以致于内存不足与一次存放全部记录,在排序过程中需要通过内存与外村之间的数据交换达到排序目的。

对于具有多个相同值的记录序列来说,如果采用的排序算法使得排序前后拥有相同值记录的相对位置是否有改变可分为:

  • 稳定性排序算法:对于值相同的两个元素,排序前后的的先后次序不变
  • 非稳定性排序算法:对于值相同的两个元素,排序前后的先后次序改变

根据记录在存储介质上的组织方式划分排序算法的分类可分为:

  • 顺序存储结构排序算法:记录之间的逻辑顺序通过物理地址的先后映射,在排序过程中需要移动记录的位置
  • 链式存储结构排序算法:文件中的一个记录对应着链表中的一个链节点,记录之间的逻辑顺序是通过指针来反应,因而排序过程中不必移动记录,只需修改相应指针的指向

3.常见排序算法

常见的排序算法主要有十种:冒泡排序算法、选择排序算法、插入排序算法、希尔排序算法、快速排序算法、堆排序算法、计数排序算法、桶排序算法、基数排序算法。

按照时间复杂度划分:

  • O(n^2):冒泡排序、选择排序、插入排序
  • O(n * logn):希尔排序、归并排序、快速排序、堆排序
  • O(n):计数排序、桶排序、基数排序

4.排序算法基本思路及实现

冒泡排序基本思想:通过相邻元素之间的比较与交换,使值较小的元素逐步从后面移到前面,值较大的元素从前面移到后面,就像水底的气泡一样向上冒,是稳定性排序算法

def bubbleSort(self, arr):
	for i in range(len(arr)):
        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 selectionSort(arr):
    for i in range(len(arr) - 1):
        min_pos = i
        for j in range(i + 1, len(arr)):
            if arr[min_pos] > min[j]:
                min_pos = j
        if i != min_pos:
            arr[i], arr[min_pos] = arr[min_pos], arr[i]
   	return arr

插入排序基本思想:每一趟排序中,将剩余未排序元素中第一个元素,插入到排序元素中的合适位置上,是稳定性排序算法

def insertionSort(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

希尔排序基本思想:将整个序列按照一定间隔取值划分为若干个子序列,每个子序列使用插入排序,直到最后一轮排序间隔未1,对整个序列进行插入排序,为非稳定性排序算法

def shellSort(arr):
    size = len(arr)
    gap = size // 2
    while gap > 0:
        for i in range(gap, size):
           	temp = arr[i]
            j = i
            while j >= gap and arr[j - gap] > temp:
				arr[j] = arr[j - gap]
                j -= gap
            arr[j] = temp
        gap = gap // 2
    return arr

归并排序基本思想:采用经典的分治策略,先递归将当前序列分为两半,然后将有序序列合并成一个有序序列,是稳定性排序算法

def merge(left_arr, right_arr):
    arr = []
    while left_arr and right_arr:
        if left_arr[0] <= right_arr[0]:
            arr.append(left_arr.pop(0))
        else:
            arr.append(right_arr.pop(0))
   	while left_arr:
        arr.apend(left_arr.pop(0))
        
    while right_arr:
        arr.apend(right_arr.pop(0))
        
   	return arr
    
    
def mergeSort(arr):
    size = len(arr)
    if size < 2:
        return arr
    mid = len(arr) // 2
    left_arr, right_arr = arr[0: mid], arr[mid:]
    return merge(mergeSort(left_arr), mergeSort(right_arr))

快速排序基本思想:通过一趟排序将无序序列分为独立的两个序列,第一个序列的值均比第二个序列的值小。然后递归两个子序列,以达到整个序列有序,非稳定性排序算法

def randomPartition(arr, low, high):
    i = random.randint(low, high)
    arr[i], arr[high] = arr[high], arr[i]
    return partition(arr
;