https://www.icourse163.org/learn/PKU-1002534001?tid=1206727206#/learn/content
数据结构与算法
张铭 、赵海燕 、王腾蛟 、宋国杰 、邹磊 、黄骏
插入排序 shell排序
def ImprovedInsertSort(Array): # Array为待排序数组
for i in range(1, len(Array)): # 依次插入第i 个记录
TempRecord = Array[i] #从i 开始往前寻找记录i 的正确位置
j = i - 1
#将那些>记录i 的记录j后移
while ((j >= 0) and (TempRecord < Array[j])):
Array[j + 1] = Array[j]
j = j - 1
#此时 j 后面就是记录i 的正确位置,回填
Array[j + 1] = TempRecord
def ShellSort(Array): #Array[] 为待排序数组
n = len(Array)
delta = n // 2 # 增量delta每次除以2递减
while delta > 0:
for i in range(0, delta):
# 分别对delta个子序列进行插入排序
#“&”传 Array[i]的地址,数组总长度为n-i
ModInsSort(Array, n - i, delta)
delta = delta // 2
# 如果增量序列不能保证最后一个delta间距为1
# 可以安排下面这个扫尾性质的插入排序
# ModInsSort(Array, n, 1)
def ModInsSort(Array, n, delta):
# 对子序列中第i个记录,寻找合适的插入位置
for i in range(delta, n, delta):
# j以dealta为步长向前寻找逆置对进行调整
for j in range(i, delta - 1, -delta):
if Array[j] < Array[j - delta]: # 逆置对
Array[j], Array[j - delta] = Array[j - delta], Array[j]
else:
break
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
# ShellSort(Array)
ImprovedInsertSort(Array)
print(Array)
选择排序
def SelectSort(Array):
n = len(Array)
# 依次选出第i小的记录,即剩余记录中最小的那个
for i in range(0, n - 1):
# 首先假设记录i就是最小的
Smallest = i
# 开始向后扫描所有剩余记录
for j in range(i + 1, n):
# 如果发现更小的记录,记录它的位置
if Array[j] < Array[Smallest]:
Smallest = j
# 将第i小的记录放在数组中第i个位置
Array[i], Array[Smallest] = Array[Smallest], Array[i]
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
SelectSort(Array)
print(Array)
冒泡排序
def BubbleSort(Array):
n = len(Array)
for i in range(0, n - 1):
NoSwap = True # 初始标志为真
for j in range(n - 1, i, -1):
if Array[j] < Array[j - 1]: # 判断是否逆置
Array[j], Array[j - 1] = Array[j - 1], Array[j]
NoSwap = False # 发生了交换,标志变为假
if NoSwap: # 没发生交换,则已完成排好序
return
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
BubbleSort(Array)
print(Array)
快速排序
def Partition(Array, left, right):
# 分割函数,分割后轴值已到达正确位置
l = left # l 为左指针
r = right # r 为右指针
TempRecord = Array[r] # 保存轴值
while l != r: # l, r 不断向中间移动,直到相遇
# l 指针向右移动,直到找到一个记录>轴值 Array[l] > TempRecord
while (Array[l] <= TempRecord and r > l):
l += 1
if (l < r): # 未相遇,将逆置元素换到右边空位
Array[r] = Array[l]
r -= 1 # r 指针向左移动一步
# r 指针向左移动,直到找到一个记录<轴值 Array[l] < TempRecord
while (Array[r] >= TempRecord and r > l):
r -= 1
if (l < r): # 未相遇,将逆置元素换到左空位
Array[l] = Array[r]
l += 1 # l 指针向右移动一步
Array[l] = TempRecord # 把轴值回填到分界位置 l 上
return l
def QuickSort(Array, left, right):
# Array[]为待排序数组,left,right分别为数组两端
if (left >= right): # 只有0或1个记录,就不需排序
return
pivot = left + (right - left) // 2 # 选择轴值
Array[pivot], Array[right] = Array[right], Array[pivot] # 轴值放到数组末端
pivot = Partition(Array, left, right) # 分割后轴值正确
QuickSort(Array, left, pivot - 1) # 左子序列递归快排
QuickSort(Array, pivot + 1, right) # 右子序列递归快排
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
QuickSort(Array, 0, len(Array) - 1)
print(Array)
归并排序
# 将数组Array的局部Array[left,middle]和Array[middle+1,right]合并到TempArray,
# 并保证TempArray有序,然后再拷贝回Array[left,mid]
# 归并操作时间复杂度: O(right-middle+1),即O(n)
# 两个有序子序列都从左向右扫描,归并到新数组
def Merge(Array, TempArray, left, middle, right):
ptmp = 0 # 从左开始归并
index1 = left # 左边子序列的起始位置
index2 = middle + 1 # 右边子序列的起始位置
while index1 <= middle and index2 <= right:
if Array[index1] <= Array[index2]: # 取较小者插入合并数组中
TempArray[ptmp] = Array[index1]
ptmp += 1
index1 += 1
else:
TempArray[ptmp] = Array[index2]
ptmp += 1
index2 += 1
while index1 <= middle: # 只剩左序列,可以直接复制
TempArray[ptmp] = Array[index1]
ptmp += 1
index1 += 1
while index2 <= right:
TempArray[ptmp] = Array[index2]
ptmp += 1
index2 += 1
for i in range(0, right - left + 1): # 将数组暂存入临时数组
Array[left + i] = TempArray[i]
def MergeSort(Array, TempArray, left, right): # Array为待排序数组,left,right两端
if left < right:
middle = left + (right - left) // 2 # 从中间划为两个子序列
MergeSort(Array, TempArray, left, middle) # 左
MergeSort(Array, TempArray, middle + 1, right) # 右
Merge(Array, TempArray, left, middle, right) # 对相邻的有序序列进行归并
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
MergeSort(Array, [0] * len(Array), 0, len(Array) - 1)
print(Array)
def ModMerge(Array, TempArray, left, middle, right):
# 复制 Array[left:middle] 到 TempArray[left:middle]
for i in range(left, middle + 1):
TempArray[i] = Array[i]
# 颠倒复制 Array[middle+1:right] 到 TempArray[middle+1:right]
# Array[middle+1] 到 TempArray[right]
# Array[middle+2] 到 TempArray[right-1]
# Array[middle+j] 到 TempArray[right-j+1]
for j in range(1, right - middle + 1):
TempArray[right - j + 1] = Array[j + middle]
index1 = left # 两个子序列的起始位置
index2 = right
for k in range(left, right + 1):
if TempArray[index1] <= TempArray[index2]:
Array[k] = TempArray[index1]
index1 += 1
else:
Array[k] = TempArray[index2]
index2 -= 1
def ModMergeSort(Array, TempArray, left, right): # Array为待排序数组,left,right两端
if left < right:
middle = left + (right - left) // 2 # 从中间划为两个子序列
MergeSort(Array, TempArray, left, middle) # 左
MergeSort(Array, TempArray, middle + 1, right) # 右
ModMerge(Array, TempArray, left, middle, right) # 对相邻的有序序列进行归并
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
ModMergeSort(Array, [0] * len(Array), 0, len(Array) - 1)
print(Array)
桶排序
def BucketSort(Array):
n = len(Array)
max_num = max(Array) + 1
TempArray = [0] * n # 临时数组
for i in range(0, n): # 把序列复制到临时数组
TempArray[i] = Array[i]
count = [0] * max_num # 桶容量计数器
for i in range(0, n): # 统计每个取值出现的次数
count[Array[i]] += 1
for i in range(1, max_num): # 统计小于等于i的元素个数
count[i] = count[i - 1] + count[i] # c [i]记录i+1的起址
for i in range(n - 1, -1, -1): # 尾部开始,保证稳定性
count[TempArray[i]] -= 1
Array[count[TempArray[i]]] = TempArray[i]
Array = [13, 27, 19, 2, 8, 12, 2, 8, 30, 89]
BucketSort(Array)
print(Array)