'''
堆排序:
堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
1)最大堆(最小堆)调整:将堆的末端子节点作调整,使得子节点永远小于(大于)父节点
2)创建最大堆(小堆):将堆中的所有数据重新排序
3)堆排序:移除位在第一个数据的根节点,并做最大堆(小堆)调整的递归运算
问题1:当堆顶元素改变时,如何重建堆?
首先将完全二叉树根结点中的记录移出,该记录称为待调整记录。此时根结点相当于空结点。从空结点的左、右子中选出一个关键字较小的记录,如果该记录的关键字小于待调整记录的关键字,则将该记录上移至空结点中。此时,原来那个关键字较小的子结点相当于空结点。重复上述移动过程,直到空结点左、右子的关键字均不小于待调整记录的关键字。此时,将待调整记录放入空结点即可。上述调整方法相当于把待调整记录逐步向下“筛”的过程,所以一般称为“筛选”法。
问题2:如何由一个任意序列建初堆?
一个任意序列看成是对应的完全二叉树,由于叶结点可以视为单元素的堆,因而可以反复利用“筛选”法,自底向上逐层把所有子树调整为堆,直到将整个完全二叉树调整为堆。
问题3:如何利用堆进行排序(进行堆排序的步骤)?
1)将待排序记录按照堆的定义建初堆(算法9.10),并输出堆顶元素;
2)调整剩余的记录序列,利用筛选法将前n-i个元素重新筛选建成为一个新堆,再输出堆顶元素;
3)重复执行步骤②n-1次进行筛选, 新筛选成的堆会越来越小,而新堆后面的有序关键字会越来越多,最后使待排序记录序列成为一个有序的序列,这个过程称之为堆排序。
时间复杂度:O(nlog2n)
稳定性:不稳定排序算法
'''
def createHeap(mylist,index,heap_size):
largest = index
left_child = 2 * index + 1
right_child = 2* index + 2
if left_child < heap_size and mylist[left_child] > mylist[largest]:
largest = left_child
if right_child < heap_size and mylist[right_child] > mylist[largest]:
largest = right_child
if largest != index:
mylist[largest],mylist[index] = mylist[index],mylist[largest]
createHeap(mylist,largest,heap_size)
def heapSort(mylist):
for i in range(len(mylist)//2 - 1,-1,-1):
createHeap(mylist,i,len(mylist))
for j in range(len(mylist) - 1,0,-1):
mylist[0],mylist[j] = mylist[j],mylist[0]
createHeap(mylist,0,j)
return mylist
if __name__ == '__main__':
mylist = [5,7,2,4,2,36,8,1,2,89,27,12,11]
print(heapSort(mylist))
'''
归并排序(速度仅次于快排):
建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
1)将一组无序的数组使用二分思想进行分割,直至分到每一个子序列只剩一个元素,或者子序列有序时,然后开始合并,分为子序列时可以使用递归。
2)通过不断的分割之后,所有的子序列都已经内部有序,之后进行合并,也就是二路归并,通过比较,将两个有序的序列合并为一个有序的序列,之后重复合并,直至所有的序列都合并完成,需要排序的数组就排序完成了。
时间复杂度:O(nlog2n)
稳定性:稳定排序算法
'''
def mergesort(newlist1,newlist2):
nums = []
x, y = 0, 0
while x < len(newlist1) and y < len(newlist2):
if newlist1[x] < newlist2[y]:
nums.append(newlist1[x])
x += 1
else:
nums.append(newlist2[y])
y += 1
if x == len(newlist1):
for i in newlist2[y:]:
nums.append(i)
else:
for i in newlist1[x:]:
nums.append(i)
return nums
def merge(mylist):
if len(mylist) < 2:
return mylist
else:
_index = len(mylist) // 2
left_index = merge(mylist[:_index])
right_index = merge(mylist[_index:])
return mergesort(left_index,right_index)
if __name__ == '__main__':
mylist = [2,3,4,2,1,7,8,5,99,0,1,-1,-6,45]
print(merge(mylist))