Insert_sort and heap_sort and merge_sort

一、插入排序

"""
---------------插入排序--------------
一、介绍
    插入排序(Insettion Sort)是一种简单直观的排序算法。
    
二、步骤
    通过构建有序序列,对于未排序数据,在已排序序列中从后面向前扫描,
    找到相应位置并插入。
    插入排序在实现上,在从后面扫描的过程中,需要反复把已排序的元素逐步向后移位,为最新元素提供插入空间。
 """
def insert_sort(nums):
    for i in range(1, len(nums)):
        for j in range(i, 0, -1):
            if nums[j] < nums[j-1]:
                nums[j], nums[j-1] = nums[j-1], nums[j]
                
                
                
if __name__ == '__main__':
    nums = [54, 25, 52, 64, 77, 62, 20]
    insert_sort(nums)
    print(nums)

二、堆排序

"""
------------------------------- Heap Sort --------------------------------------

一、介绍
    堆排序(Heap Sort)是一种树形选择排序,是对直接选择排序的有效改进。
二、思想:
    起初要把排序的数的序列看成是一棵顺序存储的二叉树,调整它们的存储序,让其成为一个堆,这时堆的根节点的数最大
    而后将根节点与堆的最后一个节点交换,然后对前面(n-1)个数从新调整让其重新调整为一个堆,以此类推,知道只有两
    个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程。一、建立堆;
    二、堆顶和堆的最后一个节点交换位置。所以排序要有两个函数来构成。(1)建立堆的渗透函数,(2)反复调用渗透函数
    实现排序的函数。
三、堆的知识点:
    堆的定义:具有n个元素的序列(h1, h2, h3,..., hn),当且仅当满足(hi >= h2i, hi >= h2i+1 )或(hi <= h2i, hi <=h2i+1) 
    (i=1,2,..,n/2)在这里只讨论满足前者条件的堆。有堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全
    二叉树可以很直观的表示堆的结构。堆顶为根,其他为左右子树。
    
"""

#   调整堆,把最大的值调整到堆顶
def adjust_heap(nums, i, size):
    lchild = 2 * i + 1
    rchild = 2 * i + 2
    max = i
    if i < size / 2:
        if lchild < size and nums[lchild] > nums[max]:
            max = lchild
        if rchild < size and nums[rchild] > nums[max]:
            max = rchild
        if max != i:
            nums[max], nums[i] = nums[i], nums[max]
            adjust_heap(nums, max, size)

#   创建堆
def build_heap(lists, size):
    for i in range(0, (size >> 1))[::-1]:
        adjust_heap(lists, i, size)

#堆排序
def heap_sort(lists):
    size = len(lists)
    build_heap(lists,size)
    for i in range(0, size)[::-1]:
        lists[0], lists[i] = lists[i], lists[0]
        adjust_heap(lists, 0, i)
    return lists
   

if __name__ == '__main__':
    nums = [54, 25, 52, 64, 77, 62, 20]
    result = heap_sort(nums)
    print(result)

三、归并排序

"""
------------------------merge sort------------------------------
一、介绍
    基本思想
    将数组array[0, 1, ... , n-1]中的元素分成两个子数组:array1[0, 1, ... , n/2]和array2[n/2 + 1, ... , n-1].
    分别对这两个数组单独排序,然后将已排序的两个子数组归并成一个含有n个元素的有序数组
二、步骤
    递归实现
三、时间复杂度:O(N*logN)
四、归并排序的两点改进
    1.在数组长度比较短的情况下,不进行递归,而是选择其他排序方案,如插入排序
    2.归并的过程中,可以用记录数组下表的方式代替申请新内存空间;从而避免array和辅助数组剪得频繁数据移动

"""

#合并连个有序数组
def merge(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

def merge_sort(nums):
    if len(nums) <= 1:
        return nums
    num = len(nums) >> 1
    left = merge_sort(nums[:num])
    right = merge_sort(nums[num:])
    return merge(left,right)


# ------------------- 按第二个改进方案修改----------------------------

temp = [0] * 100


def Merge(nums, low, mid, high):
    i = low
    j = mid + 1
    size = 0
    while i <= mid and j <= high:
        if nums[i] < nums[j]:
            temp[size] = nums[i]
            i += 1
        else:
            temp[size] = nums[j]
            j += 1
        size += 1
    while i <= mid:
        temp[size] = nums[i]
        size += 1
        i += 1
    while j <= high:
        temp[size] = nums[j]
        size += 1
        j += 1
    for i in range(size):
        nums[low + i] = temp[i]


def Merge_sort(nums, low, high):
    if low >= high:
        return
    mid = (low + high) >> 1
    Merge_sort(nums, low, mid)
    Merge_sort(nums, mid + 1, high)
    Merge(nums, low, mid, high)


if __name__ == '__main__':
    nums = [54, 25, 52, 64, 77, 62, 20]
    Merge_sort(nums, 0, len(nums) - 1)
    print(nums)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值