算法参考于菜鸟教程https://www.runoob.com/w3cnote/ten-sorting-algorithm.html
'''
1、冒泡排序
'''
def bubbleSort(arr):
for i in range(1, len(arr)):
for j in range(0, len(arr)-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
'''
2、选择排序--每次选择最小值
'''
def selectionSort(arr):
for i in range(len(arr)-1):
# 记录最小数的索引
minIndex = i
for j in range(i+1, len(arr)):
if arr[j] < arr[minIndex]:
minIndex = j
# i 不是最小数时,将i和最小数进行交换
if i != minIndex:
arr[i], arr[minIndex] = arr[minIndex], arr[i]
return arr
'''
3、选择排序--向有序序列中,从后向前插入元素
'''
def insertSort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i] # 记录要插入的元素
while preIndex >= 0 and arr[preIndex] > current: # 从后向前遍历
arr[preIndex+1] = arr[preIndex]
preIndex -= 1
arr[preIndex+1] = current
return arr
'''
4、希尔排序--先将序列划分成n份,每一份进行插入排序;最后进行整体插入排序
arr = [2,5,7,12,4,1,13,6,8,11,15,9]
res = shellSort(arr)
gap = 4
数据被分成4组--[2,4,8]、[5,1,11]、[7,13,15]、[12,6,9]、
'''
def shellSort(arr):
import math
gap = 1
while(gap < len(arr)/3):
gap = gap*3+1
# print(gap)
while gap > 0:
for i in range(gap, len(arr)):
temp = arr[i]
j = i - gap
while j >= 0 and arr[j] > temp:
arr[j+gap] = arr[j]
j -= gap
arr[j+gap] = temp
gap = math.floor(gap/3)
return arr
'''
5、快速排序--关键点在于partition函数找到pivot
(1)主元选择固定
(2)随机选取主元的快速排序
'''
class QuickSort1(object):
def quickSort(self, arr, left, right):
if left < right:
index = self.partition2(arr, left, right)
self.quickSort(arr, left, index-1)
self.quickSort(arr, index+1, right)
def partition(self, arr, left, right):
pivot = left
index = pivot + 1
i = index
while i <= right:
if arr[i] < arr[pivot]: # 把小于arr[pivot]的值放到左边,大于arr[pivot]的值放到右边
self.swap(arr, i, index)
index += 1
i += 1
self.swap(arr, pivot, index-1)
return index-1
def partition2(self, arr, left, right):
pivot = arr[left]
i, j = left, right
while i < j:
while i < j and arr[j] >= pivot: # 从后往前找,找到一个比pivot小的数
j -= 1
arr[i] = arr[j]
while i < j and arr[i] <= pivot: # 从前往后找,找到一个比pivot大的数
i += 1
arr[j] = arr[i]
arr[i] = pivot # i = j
return i
def swap(self, arr, i, j):
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
class QuickSort2(object):
def quickSort(self, arr, left, right):
if left < right:
index = self.partition2(arr, left, right)
self.quickSort(arr, left, index-1)
self.quickSort(arr, index+1, right)
def partition(self, arr, left, right):
pivot = left
index = pivot + 1
i = index
while i <= right:
if arr[i] < arr[pivot]: # 把小于arr[pivot]的值放到左边,大于arr[pivot]的值放到右边
self.swap(arr, i, index)
index += 1
i += 1
self.swap(arr, pivot, index-1)
return index-1
def partition2(self, arr, left, right):
pivot = arr[left]
i, j = left, right
while i < j:
while i < j and arr[j] >= pivot: # 从后往前找,找到一个比pivot小的数
j -= 1
arr[i] = arr[j]
while i < j and arr[i] <= pivot: # 从前往后找,找到一个比pivot大的数
i += 1
arr[j] = arr[i]
arr[i] = pivot # i = j
return i
def swap(self, arr, i, j):
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
'''
6、堆排序--给定一个数组,建立最小堆
'''
class Heap(object):
def heapSort(self, arr):
heapSize = len(arr)
# 建立最小堆
self.buildMaxHeap(arr, heapSize)
# 排序
for i in range(heapSize-1, 0, -1):
self.swap(arr, 0, i)
self.heapify(arr, 0, i)
# heapSize -= 1
# self.heapify(arr, 0, heapSize)
return arr
def buildMaxHeap(self, arr, heapSize):
for i in range(heapSize//2, -1, -1):
self.heapify(arr, i, heapSize)
def heapify(self, arr, i, heapSize):
left = 2 * i + 1
right = 2 * i + 2
maxIndex = i
if left < heapSize and arr[left] < arr[maxIndex]:
maxIndex = left
if right < heapSize and arr[right] < arr[maxIndex]:
maxIndex = right
if maxIndex != i:
self.swap(arr, i, maxIndex)
self.heapify(arr, maxIndex, heapSize)
def swap(self, arr, i , j):
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
# 从头建立一个最小堆,并完成push和pop操作
class Heap2(object):
def __init__(self):
self.heap = []
def _shift_up(self, index):
while index > 0:
parent = (index-1) // 2 # 很关键,因为索引是从0开始的,因此需要-1
if self.heap[parent] < self.heap[index]:
break
self.heap[parent], self.heap[index] = self.heap[index], self.heap[parent]
index = parent
def _shift_down(self, index):
while index * 2 + 1 < len(self.heap): # 还存在左子树
left = 2 * index + 1
right = 2 * index + 2
parent = index
smallest = parent
if self.heap[left] < self.heap[smallest]:
smallest = left
if right < len(self.heap) and self.heap[right] < self.heap[smallest]: # important
smallest = right
if smallest == parent:
break
self.heap[parent], self.heap[smallest] = self.heap[smallest], self.heap[parent]
index = smallest
def push(self, data):
self.heap.append(data)
self._shift_up(len(self.heap) - 1) # 对最后一个元素操作
def pop(self): # 堆顶元素和最后一个元素交换, 然后重新建堆
last = len(self.heap)-1
self.heap[0], self.heap[last] = self.heap[last], self.heap[0]
peek = self.heap.pop() # pop最后一个元素,即将原来的栈顶元素pop出来
self._shift_down(0) # 从0开始调整堆
return peek
'''
7、归并排序--采用分治法
'''
def mergeSort(arr):
import math
if (len(arr)<2):
return arr
middle = math.floor(len(arr)//2)
left, right = arr[0:middle], arr[middle:]
return merge(mergeSort(left), mergeSort(right))
def merge(left, right):
result = []
while left and right:
if left[0] <= right[0]: # 保证了归并排序的稳定性
result.append(left.pop(0))
else:
result.append(right.pop(0))
while left:
result.append(left.pop(0))
while right:
result.append(right.pop(0))
return result
'''
8、基数排序--其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较
'''
arr = [2,5,7,12,4,1,13,6,8,11,15,9]
sol = Heap2()
sol.push(5)
sol.push(2)
sol.push(3)
print(sol.heap)
res = sol.pop()
print(sol.heap)
print(res)