一、插入排序
"""
---------------插入排序--------------
一、介绍
插入排序(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)