python算法之排序(二)

#堆排序
#基本思想:1.将初始待排序数字列表(R1,R2,...,Rn)构建成大顶堆,此堆为初始的无序列表
# 2.将堆顶元素R1与最后一个元素Rn交换,此时得到新的无序列表(R1,R2,...,Rn-1)和新的有序列表(Rn)
# 3.由于交换后新的堆顶R1可能违反堆的性质,因此需要对当前无序列表(R1,R2,...,Rn-1)调整为新堆,
# 然后再次将R1与无序列表最后一个元素交换,得到新的无序列表(R1,R2,...,Rn-2)和新的有序列表(Rn-1,Rn).
# 不断重复此过程直到有序列表的元素个数为n-1,则整个排序过程完成。

#sift_down通过从下而上比较每个节点与其子节点的大小(Ri<R2i,Ri<R2i+1),将最大的数放置到堆顶
def sift_down(numList, start, end):
root = start
while True:
child = 2 * root + 1
if child >end:
break
if child + 1 <=end and numList[child] < numList[child+1]:
child += 1
if numList[root] < numList[child]:
numList[root], numList[child] = numList[child], numList[root]
root = child
else:
break

def heap_sort(numList):
#将初始列表组成大顶堆
first = len(numList) // 2 - 1
for start in reversed(range(0, first+1)):
sift_down(numList, start, len(numList)-1)
print(numList)
#将最大的数放置到最后,对前n-1个元素进行堆调整
for end in range(len(numList)-1, 0, -1):
numList[0], numList[end] = numList[end], numList[0]
sift_down(numList, 0, end-1)
print(numList)
return numList
print(heap_sort([16, 7, 3,20,17,8,99,76]))
# [99, 76, 16, 20, 17, 8, 3, 7]
# [76, 20, 16, 7, 17, 8, 3, 99]
# [20, 17, 16, 7, 3, 8, 76, 99]
# [17, 8, 16, 7, 3, 20, 76, 99]
# [16, 8, 3, 7, 17, 20, 76, 99]
# [8, 7, 3, 16, 17, 20, 76, 99]
# [7, 3, 8, 16, 17, 20, 76, 99]
# [3, 7, 8, 16, 17, 20, 76, 99]


# 归并排序:
# 基本思想:首先归并排序使用了二分法,归根到底的思想还是分而治之。拿到一个长数组,将其不停的分为左边和右边两份,
# 然后以此递归分下去。然后再将她们按照两个有序数组的样子合并起来。
# 举例[4,7,8,3,5,9]
# 第一步:分:[4,8,7] [3,9,5] ->[4,8] [7] [3,9] [5] -> [4] [8] [7] [3] [9] [5]
# 第二步:并:[4,8] [7] [3,9] [5] ->[4,7,8] [3,5,9] -> [3,4,5,7,8,9]

def merge(a,b):#此时a和b都为已经排序好的列表
c = []
h = j = 0
while j<len(a) and h<len(b):#依次比较直到a或b的元素被全部排完
if a[j]<b[h]:
c.append(a[j])
j+=1
else:
c.append(b[h])
h+=1
if j==len(a):
#当a里的元素全部排完了,将b里剩下的元素依次排入c
for i in b[h:]:
c.append(i)
else:
#当b里的元素全部排完了,将a里剩下的元素依次排入c
for i in a[j:]:
c.append(i)
return c

#递归法
def mergesort(numList):
print(numList)
if len(numList) <= 1:
return numList
middle = len(numList) / 2
left = mergesort(numList[:middle])
right = mergesort(numList[middle:])
return merge(left, right)
print(mergesort([1,2,-1,8,6,7,-2]))
# [1, 2, -1, 8, 6, 7, -2]
# [1, 2, -1]
# [1]
# [2, -1]
# [2]
# [-1]
# [8, 6, 7, -2]
# [8, 6]
# [8]
# [6]
# [7, -2]
# [7]
# [-2]

#遍历法
def mergesort1(numList):
lenList = len(numList)
while lenList>1:
newList = []
if lenList % 2 == 0:
for i in range(lenList/2):
a = [numList[2*i]] if type(numList[2*i]) == int else numList[2*i]
b = [numList[2*i+1]] if type(numList[2*i+1]) == int else numList[2*i+1]
newList.append(merge(a, b))
numList = newList
lenList = len(numList)
else:
for i in range(lenList/2):
a = [numList[2 * i]] if type(numList[2*i]) == int else numList[2 * i]
b = [numList[2 * i + 1]] if type(numList[2*i+1]) == int else numList[2 * i + 1]
newList.append(merge(a, b))
last = [numList[-1]] if type(numList[-1]) == int else numList[-1]
newList.append(last)
numList = newList
lenList = len(numList)
print(newList)
print(lenList)
return numList[0]
#print(mergesort1([1,2,-1,8,7,6,-2]))
print(mergesort1([1,2,-1,8,6,7,-2,-13,58,30,-15,18]))
# [[1, 2], [-1, 8], [6, 7], [-2]]
# 4
# [[-1, 1, 2, 8], [-2, 6, 7]]
# 2
# [[-2, -1, 1, 2, 6, 7, 8]]
# 1
# [-2, -1, 1, 2, 6, 7, 8]

#希尔排序(在直接插入排序的基础上加上间隔)
#基本思想:1.定义步长序列t为[k,...,1]
# 2.按照步长序列个数k,对排序队列进行k趟排序
# 3.每趟排序,根据对应的步长ti,将待排序列分割成ti个子序列,分别对
# 各个子序列进行直接插入排序。

def insertsort(numList):
leng = len(numList)
gap = leng
while(gap>1):
gap = gap // 2
print(gap)
for i in range(gap,leng):
if numList[i] < numList[i-gap]:
midnum = numList[i]
j=i-gap
while numList[j] >midnum and j >= 0:
numList[j+gap] = numList[j]
j -=gap
numList[j + gap] = midnum
print(numList)
return numList
print(insertsort([1,2,-1,8,6,7,-2,-13]))
[1,2,-1,8,6,7,-2,-13]
# 间隔为4
# [1, 2, -1, 8, 6, 7, -2, -13]
# [1, 2, -1, 8, 6, 7, -2, -13]
# [1, 2, -2, 8, 6, 7, -1, -13]
# [1, 2, -2, -13, 6, 7, -1, 8]
# 间隔为2
# [-2, 2, 1, -13, 6, 7, -1, 8]
# [-2, -13, 1, 2, 6, 7, -1, 8]
# [-2, -13, 1, 2, 6, 7, -1, 8]
# [-2, -13, 1, 2, 6, 7, -1, 8]
# [-2, -13, -1, 2, 1, 7, 6, 8]
# [-2, -13, -1, 2, 1, 7, 6, 8]
# 间隔为1
# [-13, -2, -1, 2, 1, 7, 6, 8]
# [-13, -2, -1, 2, 1, 7, 6, 8]
# [-13, -2, -1, 2, 1, 7, 6, 8]
# [-13, -2, -1, 1, 2, 7, 6, 8]
# [-13, -2, -1, 1, 2, 7, 6, 8]
# [-13, -2, -1, 1, 2, 6, 7, 8]
# [-13, -2, -1, 1, 2, 6, 7, 8]

猜你喜欢

转载自www.cnblogs.com/xhw19950606/p/12301081.html