数据结构-查找(归并排序、快速排序、插入排序、冒泡排序、选择排序、堆排序,Python实现)

实现归并排序、快速排序、插入排序、冒泡排序、选择排序、堆排序

目录

(1)归并排序

(2)快速排序

(3)插入排序

(4)冒泡排序

(5)选择排序

(6)堆排序

参考:


(1)归并排序

归并排序英文名为Merge Sort, 是建立在归并操作上的一种有效的排序算法,该算法是采用分治法。其思想是先递归的把数组划分为两个子数组,一直递归到数组中只有一个元素,然后再调用函数把两个子数组排好序。

归并排序严格遵循从左到右或从右到左的顺序合并子数据序列, 因此不会改变相同数据之间的相对顺序, 是一种稳定的排序算法。

  • 设置递归的出口;
  • 直接把数组平分成两个子数组;
  • 递归调用划分数组函数,最后划分到数组中只有一个元素,即数组是有序的了;
  • 然后调用排序函数,把两个有序的数组合并成一个有序的数组;
  • 排序函数的步骤,让两个数组的元素进行比较,把大的/小的元素存放到临时数组中,如果有一个数组的元素被取光了,那就直接把另一数组的元素放到临时数组中,然后把临时数组中的元素都复制到实际的数组中。

归并排序代码:

def merge_sort(array):
    if len(array) <= 1:#递归的出口
        return array
    mid = len(array)//2
    left = merge_sort(array[:mid])
    right = merge_sort(array[mid:])
    w = sort(left,right)
    return w

def sort(left, right):
    a = 0
    b = 0
    result = []
    while a < len(left) and b < len(right):
        if left[a] <= right[b]:
            result.append(left[a])
            a = a+1
        else:
            result.append(right[b])
            b = b + 1
    result += left[a:]
    result += right[b:]
    return result

上面的代码主要是两个函数,一个是划分数组函数,第二个是对两个有序数组合并的归并函数。

(2)快速排序

快速排序英文称为Quicksort,是采用分治策略来把一个序列分为两个子序列。然后分别对两个子序列进行递归的快速排序。

  • 从数列中挑出一个元素(一般是第一个元素)作为基准base
  • 从后往前找元素比基准小的排在基准元素前面,大的排在基准元素后面
  • 以基准元素为界,分别对其前后两个子序列进行快速排序

代码实现

def quick_sort(arr, start, end):
    if start >= end:#递归结束标志
        return
    low = start
    high = end
    base = arr[start]
    
    while low < high:
        while low < high and base < arr[high]:
            high -= 1
        arr[low] = arr[high]
        while low < high and base > arr[high]:
            low += 1
        arr[high] = arr[low]
        
    arr[low] = base
    quick_sort(arr, start, low - 1)
    quick_sort(arr, low+1, end)
    return arr

(3)插入排序

插入排序英文称为Insertion Sort,先将待排序序列的第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列;然后从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置,直到所有数据都完成排序;如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。

代码实现

#插入排序
def insert_sort(arr):
    for i in range(1, len(arr)):
        for j in range(i,0,-1):
            if arr[j] < arr[j - 1]:
                arr[j - 1], arr[j] = arr[j], arr[j - 1]
    return arr

(4)冒泡排序

冒泡排序英文称为 Bubble Sort,它遍历所有的数据,每次对相邻元素进行两两比较,如果顺序和预先规定的顺序不一致,则进行位置交换;重复同样的操作,直到所有的数据有序。

代码实现

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

(5)选择排序

选择排序英文称为 Selection Sort,它是先在数据中找出最大或最小的元素,放到序列的起始;然后再从余下的数据中继续寻找最大或最小的元素,依次放到排序序列中,直到所有数据样本排序完成。

#选择排序
def select_sort(arr):
    for i in range(len(arr)):
        min_index = i
        for j in range(i+1, len(arr)):
            if arr[j]< arr[min_index]:
                min_index = j
            if min_index != i:
                arr[i], arr[min_index] = arr[min_index],arr[i]
    return arr

(6)堆排序

堆排序,英文称 Heapsort,是用堆这种数据结构所设计的一种排序算法。堆排序是采用二叉堆的数据结构来实现的。

  1. 父节点的值总是大于或等于(小于或等于)任何一个子节点的值;

  2. 每个节点的左右子树都是一个二叉堆(都是最大堆或最小堆)

步骤:

  • 先将无序数据构建一个大顶堆(升序)或小顶堆(降序);
  • 将堆顶元素与末尾元素交换,将最大(小)元素沉到数组末尾
  • 重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,直至数组有序

代码实现:

def maxheap(arr):
    for i in range(len(arr)//2, -1, -1):
        heap(arr, i)
def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]
def heap(arr, i):#构建最大堆
    left_child = 2*i + 1
    right_child = 2*i + 2
    largest = i
    if left_child > arrLen:
        return
    if left_child < arrLen and arr[left_child] > arr[largest]:
        largest = left_child
    if right_child < arrLen and arr[right_child] > arr[largest]:
        largest = right_child
    if largest != i:
        swap(arr, i, largest)
        heap(arr, largest)
def heap_sort(arr):
    global arrLen
    arrLen = len(arr)
    maxheap(arr)
    for i in range(len(arr)-1, 0, -1):#将最大的元素沉到末尾
        swap(arr, i, 0)
        arrLen -= 1
        heap(arr, 0)#数据堆结构改变后再将其变为最大堆
    return arr

参考:

1. https://blog.csdn.net/qq_32799165/article/details/87878876

2. https://www.runoob.com/w3cnote/heap-sort.html

3. https://www.cnblogs.com/chengxiao/p/6129630.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值