排序和简单地搜索
排序算法的稳定性
稳定性:稳定排序算法会让原本有相等键值的纪录维持相对次序。
假设以下的数对将要以他们的第一个数字来排序。
(4, 1) (3, 1) (3, 7)(5, 6)
在这个状况下,有可能产生两种不同的结果,一个是让相等键值的纪录维持相对的次序,而另外一个则没有:
(3, 1) (3, 7) (4, 1) (5, 6) (维持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改变)
那么低一个就是稳定的,第二个就是不稳定的
冒泡排序
def bubble_sort(alist):
for j in range(len(alist)-1,0,-1):
# j表示每次遍历需要比较的次数
for i in range(j):
if alist[i]>alist[i+1]:
alist[i],alist[i+1]=alist[i+1],alist[i]
li = [54,26,93,17,77,31,44,55,20]
bubble_sort(li)
print(li)
输出
[17, 20, 26, 31, 44, 54, 55, 77, 93]
选择排序
def selection_sort(alist):
n=len(alist)
for i in range(n-1):
#i代表将要选择第i个位置的元素
min_index=i
for j in range(i+1,n):
#j代表本次选择从第j个开始
if alist[min_index]>alist[j]:
min_index=j
if min_index!=i:
alist[min_index],alist[i]=alist[i],alist[min_index]
alist = [54,226,93,17,77,31,44,55,20]
selection_sort(alist)
print(alist)
输出结果:
[17, 20, 31, 44, 54, 55, 77, 93, 226]
插入排序
def insert_sort(alist):
for i in range(1,len(alist)):
#i是指每次插入需要比较的次数
for j in range(i-1,0,-1):
#j是指从第j个向前比较,一直比较到第0个
if alist[j]<alist[j-1]:
alist[j],alist[j-1]=alist[j-1],alist[j]
alist = [54,26,93,17,77,31,44,55,20]
insert_sort(alist)
print(alist)
输出
[17, 26, 31, 44, 54, 55, 77, 93, 20]
希尔排序
希尔排序是一种高级的快速排序,每次排序的元素是列表中以某个数为间隔的子列表
def shell_sort(arr):
n=len(arr)
gap=n//2
##从一个比较大的gap开始,然后缩小gap
while gap>0:
#以gap为间隙进行插入排序,arr[0...gap-1]已经在即将被插入的序列中
#每次添加一个元素进行以此gap的插入排序,直到最后一个元素
for i in range(gap,n):
temp=arr[i]
#临时保存arr[i],将arr[i]添加到合适的位置
j=i
while j-gap>=0 and arr[j-gap]>temp:
arr[j]=arr[j-gap]
j-=gap
#一直将比temp大的元素移动到arr[j+gap]上
arr[j]=temp
gap=gap//2
alist = [6,10,1,3,5,11,2,14]
shell_sort(alist)
print(alist)
[1, 2, 3, 5, 6, 10, 11, 14]
快速排序
def quick_sort(arr,start,end):
if start>=end:
return
#退出循环的条件
mid=arr[start]
low=start
high=end
while low<high:
# 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动
while low<high and arr[high]>mid:
high-=1
# 将high指向的元素放到low的位置上
arr[low]=arr[high]
# 如果low与high未重合,low指向的元素比基准元素小,则low向右移动
while low<high and arr[low]<mid:
low+=1
# 将low指向的元素放到high的位置上
arr[high]=arr[low]
# 退出循环后,low与high重合,此时所指位置为基准元素的正确位置
# 将基准元素放到该位置
arr[low]=mid
quick_sort(arr,start,low-1)
quick_sort(arr,low+1,end)
alist = [54,26,93,17,77,31,44,55,20]
quick_sort(alist,0,len(alist)-1)
print(alist)
[17, 20, 26, 31, 44, 54, 55, 77, 93]
归并排序
def merge(a,b):
c=[]
i=j=0
while i<len(a) and j<len(b):
if a[i]<b[j]:
c.append(a[i])
i+=1
else:
c.append(b[j])
j+=1
if i<len(a):
for k in a[i:]:
c.append(k)
if j<len(b):
for l in b[j:]:
c.append(l)
return c
def merge_sort(arr):
if len(arr)<=1:
return arr
mid=len(arr)//2
l=merge_sort(arr[:mid])
r=merge_sort(arr[mid:])
return merge(l,r)
a = [4, 7, 8, 3, 5, 9]
print(merge_sort(a))
[3, 4, 5, 7, 8, 9]
常见排序算法比较
二分查找法的递归与非递归
递归方式
def binary_search(arr,item):
if len(arr)==0:
return
else:
mid=len(arr)//2
if arr[mid]==item:
return True
else:
if item<arr[mid]:
binary_search(arr[:mid],item)
else:
binary_search(arr[mid+1:],item)
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
None
True
非递归方式:
def binary_search(arr,item):
l=0
r=len(arr)-1
while l<=r:
mid=(l+r)//2
if arr[mid]==item:
return True
elif item<arr[mid]:
r=mid-1
else:
l=mid+1
return False
testlist = [0, 1, 2, 8, 13, 17, 19, 32, 42,]
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
False
True