第9章 排序
9.1 问题和性质
9.1.1 问题定义
集合上的序
(读者:这里没有看的很明白)
定义
9.1.2 排序算法
基于比较的排序
基本操作、性质和评价
稳定性:
适应性:
排序算法的分类
基于排序的基本操作方法或特点分类:
- 插入排序
- 选择排序
- 交换排序
- 分配排序
- 归并排序
- 外部排序
记录结构
(读者:抄代码)
class record:
def __init__(self, key, datum):
self.key = key
self.datum = datum
9.2 简单排序算法
9.2.1 插入排序
算法的考虑和实现
(读者:抄代码)
def insert_sort(lst):
for i in range(1, len(lst)): # 开始时片段[0:1]已排序
x = lst[i]
j = i
while j > 0 and lst[j-1].key > x.key:
lst[j] = lst[j-1] # 反序逐个后移元素,确定插入位置
j -= 1
lst[j] = x
算法分析
(读者:没看)
插入排序算法的变形
采用二分法检索插入位置。但不可能从根本上改变算法的性质。
相关问题
(读者:看书上的记号)
9.2.2 选择排序
简单选择排序
直接选择排序算法
(读者:抄代码)
def select_sort(lst):
for i in range(len(lst)-1): # 只需要循环len(lst)-1次
k = i
for j in range(i, len(lst)): # k是已知最小元素的位置
if lst[j].key < lst[k].key:
k = j
if i != k: # lst[k]是确定的最小元素,检查是否需要交换
lst[i], lst[k] = lst[k], lst[i]
由于在方方面面都不如插入排序,直接选择排序很少被实际使用。
提高选择的效率
(读者:记得回头去补补堆排序。)
9.2.3 交换排序
起泡排序(读者:应该是冒泡排序)
(读者:抄代码)
def bubble_sort(lst):
for i in range(len(lst)):
for j in range(1, len(lst)-i):
if lst[j-1].key > lst [j].key:
lst[j-1], lst[j] = lst[j], lst[j-1]
算法的改进
(读者:抄代码)
def bubble_sort(lst):
for i in range(len(lst)):
found = False
for j in range(1, len(lst)-i):
if lst[j-1].key > lst[j].key:
lst[j-1], lst[j] = lst[j], lst[j-1]
found = True
if not found:
break
情况分析
9.3 快速排序
9.3.1 快速排序的表实现
(一次)划分的实现
(读者:没看明白。。)
9.3.2 程序实现
(读者:抄代码)
下面定义一个非递归的函数,其中调用一个递归定义的函数(可以作为局部定义),给定划分范围初值:
def quick_sort(lst):
qsort_rec(lst, 0, len(lst)-1)
递归过程的框架:
def qsort_rec(lst, l, r):
if l >= r: return # 分段无记录或只有一个记录
i = l;
j = r
pivot = lst[i] # lst[i]为初始值
while i < j: # 找pivot的最终位置
... ... # 用j向左扫描找小于pivot的记录并移到左边
... ... # 用i向右扫描找大于pivot的记录并移到右边
lst[i] = pivot # 将pivot存入为其确定的最终位置
qsort_rec(lst, l, i-1) # 递归处理左半区间
qsort_rec(lst, i+1, r) # 递归处理右半区间
递归的快速排序函数定义如下:
def qsort_rec(lst, l, r):
if l >= r:
return # 分段无记录或只有一个记录
i = l
j = r
pivot = lst[i] # lst[i]是初始空位
while i < j: # 找pivot的最后位置
while i < j and lst[j].key >= pivot.key:
j -= 1 # 用j向左扫描找小于pivot的记录
if i < j:
lst[i] = lst[j]
i += 1 # 小记录移到左边
while i < j and lst[i].key <= pivot.key:
i += 1 # 用i向右扫描找大于pivot的记录
if i < j:
lst[j] = lst[i]
j -= 1 # 大记录移到右边
lst[i] = pivot # 将pivot存入其最终位置
qsort_rec(lst, l, i-1) # 递归处理左半区间
qsort_rec(lst, i+1, r) # 递归处理右半区间
9.3.3 复杂度
(读者:没看)
9.3.4 另一种简单实现
(读者:没耐心看完,直接抄代码 吧)
def quick_sort1(lst):
def qsort(lst, begin, end):
if begin >= end:
return
pivot = lst[begin].key
i = begin
for j in rang[begin + 1, end + 1]:
if lst[j].key < pivot: # 发现一个元素
i += 1
9.4 归并排序
(读者:完全没看)
9.4.1 顺序表的归并排序
9.4.2 归并算法的设计问题
9.4.3 归并排序的函数定义
9.4.4 算法分析
9.5 其他排序方法
(读者:也几乎没看,因为提到了桶排序。。)
9.5.1 分配排序和基数排序
9.5.2 一些与排序有关的问题
9.5.3 Python系统的list排序
本章总结
练习
参考文献:
1.《数据结构与算法-Python语言描述》。