排序
#下面讨论的排序算法时,使用的实例数据结构就是一个表,假定表中元素是下面定义的record类的对象
class record:
def __init__(self,key,datum):
self.key=key
self.datum=datum
a=record(1,'a')
b=record(2,'b')
c=record(3,'c')
d=record(4,'d')
e=record(5,'e')
f=record(6,'f')
lst=[f,e,d,c,b,a]
-
#插入排序
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
insert_sort(lst)
print([x.key for x in lst])
-
#选择排序
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]
lst=[f,e,d,c,b,a]
select_sort(lst)
print([x.key for x in lst])
-
#起泡排序
def bubble_sort(lst):
for i in range(len(lst)):
found=False #如果内层循环扫描检查遇到了逆序,就给found赋True值。
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: #在内层循环结束后检查found,其值为False表示未发现逆序,立刻结束循环。
break #这样做可以提高效率
lst=[f,e,d,c,b,a]
bubble_sort(lst)
print([x.key for x in lst])
-
#快速排序
def quick_sort(lst):
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) #递归处理右半区间
qsort_rec(lst,0,len(lst)-1)
lst=[f,e,d,c,b,a]
quick_sort(lst)
print([x.key for x in lst])
def quick_sort1(lst):
def qsort(lst,begin,end):
if begin>=end:return
pivot=lst[begin].key
i=begin
for j in range(begin+1,end+1):
if lst[j].key<pivot: #发现一个小元素
i+=1
lst[i],lst[j]=lst[j],lst[i] #小元素换位
lst[begin],lst[i]=lst[i],lst[begin] #枢轴元就位
qsort(lst,begin,i-1)
qsort(lst,i+1,end)
qsort(lst,0,len(lst)-1)
lst=[f,e,d,c,b,a]
quick_sort1(lst)
print([x.key for x in lst])
-
#归并排序
def merge(lfrom,lto,low,mid,high):
i,j,k=low,mid,low
while i<mid and j<high: #反复复制两分段首记录中较小的
if lfrom[i].key<=lfrom[j].key:
lto[k]=lfrom[i]
i+=1
else:
lto[k]=lfrom[j]
j+=1
k+=1
while i<mid: #复制第一段剩余记录
lto[k]=lfrom[i]
i+=1
k+=1
while j<high: #复制第二段剩余记录
lto[k]=lfrom[j]
j+=1
k+=1
def merge_pass(lfrom,lto,llen,slen):
i=0
while i+2*slen<llen: #归并长slen的两段
merge(lfrom,lto,i,i+slen,i+2*slen)
i+=2*slen
if i+slen<llen: #剩下两段,后段长度小于slen
merge(lfrom,lto,i,i+slen,llen)
else: #只剩下一段,复制到表lto
for j in range(i,llen):
lto[j]=lfrom[j]
def merge_sort(lst):
slen,llen=1,len(lst)
templst=[None]*llen
while slen<llen:
merge_pass(lst,templst,llen,slen)
slen*=2
merge_pass(templst,lst,llen,slen) #结果存回原位
slen*=2
lst=[f,e,d,c,b,a]
merge_sort(lst)
print([x.key for x in lst])
参考:
《数据结构与算法-python语言描述》,裘宗燕(北京大学),第9章 排序