基本排序方法如下
(1)冒泡排序
冒泡排序基本的思路就是2层循环,每次比较相邻2个数,每次把大的数往后移,一层循环下来就能确定一个,这里做了一点优化,内存循环的范围不用一直到底,只要到上一次循环之前就行
def bubblesort(l):
for x in range(len(l)):
for y in range(len(l)-x-1):
if l[y]>l[y+1]:
k=l[y]
l[y]=l[y+1]
l[y+1]=k
(2)选择排序
把一个序列分成2部分,左边视为有序,每次从右边选出一个最小的,放到左边,每次可以确认一个最小的
def selectsort(l):
for x in range(len(l)):
min=x
for y in range(x,len(l)):
if l[y]<l[min]:
min=y
if min!=x:
k=l[x]
l[x]=l[min]
l[min]=k
(3)插入排序
插入排序同样是把序列分成左右2部分,每次把右边序列的第一个拿去和左边序列从尾到头进行比较,
def insertsort(l):
for x in range(1,len(l)):
k=l[x]
y=x-1
while y>=0 and l[y]>k:
l[y+1]=l[y]
y=y-1
l[y+1]=k
(4)堆排序
首先要建立一个大根堆,堆的性质是父节点的值大于左右孩子的值,左右孩子之间没有限制,建立完大根堆后,每次把堆顶元素也就是最大的元素取出来放在数组后面,然后维护这个堆,之后再重复操作,堆取完数组也就出来了
堆排序比较复杂,我们分几个步骤来实现
首先是维护堆,这个方法需要比较父节点和左右孩子节点,找出最大的,如果不是父节点,则要把最大值赋给父节点,并往下继续维护(之一这里比父节点小的节点我们不用去往下维护,这个涉及到我们在建堆时的处理顺序,我们维护的是从由下至上的第一个非叶子节点开始的)
def heapify(l,i,size):
lchild=2*i+1
rchild=2*i+2
max=i
if lchild < size-1 and l[max]<l[lchild]:
max=lchild
if rchild < size-1 and l[max]<l[rchild]:
max=rchild
if max!=i:
k=l[max]
l[max]=l[i]
l[i]=k
heapify(l,max,size)
然后是建堆,叶子结点无法维护,所以我们按倒叙来从第1个非叶子结点来建堆
def buildheap(l):
for x in reversed(range(0,len(l)/2)):
heapify(l,x,len(l))
准备工作完成了就可以实现堆排序了,在排序内部我们要不断取堆顶并维护新的堆
def heapsort(l):
heapsize=len(l)
buildheap(l)
while heapsize>1:
heapsize=heapsize-1
k=l[0]
l[0]=l[heapsize]
l[heapsize]=k
heapify(l,0,heapsize)
下面是完整代码
def heapify(l,i,size):
lchild=2*i+1
rchild=2*i+2
max=i
if lchild<size and l[max]<l[lchild]:
max=lchild
if rchild<size and l[max]<l[rchild]:
max=rchild
if max!=i:
k=l[max]
l[max]=l[i]
l[i]=k
heapify(l,max,szie)
def buildheap(l,n):
heapsize=n
for x in reversed(range(0,n/2-1)):
heapify(l,x,heapify)
return heapsize
def heapsort(l):
n=len(l)
heapsize=buildheap(l,n)
while heapsize>1:
heapsize=heapsize-1
k=l[0]
l[0]=l[heapsize]
l[heapsize]=k
heapify(l,0,heapsize)
(5)归并排序
也叫二分排序,简单来说就是把一个序列分成2部分,再继续递归下去直到每个序列只有1个数,然后开始两两合并
def merge(l, left, right,mid):
res = []
x = left
y = mid + 1
while x <= mid and y <= right:
if l[x] <= l[y]:
res.append(l[x])
x = x + 1
else:
res.append(l[y])
y = y + 1
while x <= mid:
res.append(l[x])
x = x + 1
while y <= right:
res.qppend(l[y])
y = y + 1
for i in range(0, len(res)):
l[left + i] = res[i]
def mergesort(l, left, right):
if left==right:
return
mid = (left + right) / 2
mergesort(l, left, mid)
mergesort(l, mid + 1, right)
merge(l, left, right,mid)
(6)快速排序
快排的思路和二分有点像,不过快排是每次把序列份左右2部分,选一个基准元素,比它大的放右边,小的放左边,这个靠两边递进的循环来实现
def part(l,left,right):
pivo=l[left]
while left<right:
while left<right and l[right]>=pivo:
right=right-1
k=l[right]
l[right]=l[left]
l[left]=k
while left<right and l[left]<=pivo:
left=left+1
k=l[right]
l[right]=l[left]
l[left]=k
return left
def quicksort(l,left,right):
if left<right:
pivo=part(l,left,right)
quicksort(l,left,pivo-1)
quicksort(l,pivo+1,right)