边界如此之复杂,思路如此之诡谲。

时间复杂度O(nlogn)空间复杂度O(1)

堆排序:
1.把数组中的元素插入到大根堆,大根堆只保证堆顶元素为最大值,但是整体不保证有序。
2.把堆顶元素与最后一个元素交换,同时堆长度heapsize减一
3.把交换过后的0到heapsize的元素大根堆化,再重复第二步,直到heapsize的元素为1

建立堆的时间复杂度O(n)

1.heapsert函数是用来建立插入元素同时保证大根堆结构,
当前值从最后一个位置开始,每次与父节点比较大小,如果当前值比父节点大,则交换父节点直到当前值小于等于父节点。父节点为(index-1)//2
2.heapify函数是用来把当前长度内的元素大根堆化
当前值从根开始,每次与左右孩子中的较大值做交换,当当前没有做交换时则停止。
左孩子为2index+1,右孩子为2index+2

def heapSort(arr):
    for i in range(len(arr)):
        heapInsert(arr, i) #先把所有值插入到大根堆中
    heapsize = len(arr)
    heapsize = heapsize -1
    swap(arr,0,heapsize) #把堆顶最大值换到数组末尾
    while heapsize > 0:
        heapify(arr, 0, heapsize) #再次整理为大根堆,方便下次插入
        heapsize = heapsize - 1
        swap(arr,0,heapsize) #把堆顶最大值换到数组末尾 
        
def heapify(arr,index,heapsize):
    lchild = 2*index+1
    largest = 0 
    while(lchild < heapsize):
        if  lchild + 1 < heapsize and  arr[lchild + 1] > arr[lchild] : 
            largest = lchild+1
        else:
            largest = lchild
        if(arr[largest] > arr[index]):
            largest = largest
        else:
            largest = index
        if(largest == index):
            break
        swap(arr,largest,index)
        index = largest
        lchild = 2*index + 1      
        
def heapInsert(arr,index):
    rootIdx = (index -1) >> 1
    while  arr[rootIdx] < arr[index]:
        swap(arr,rootIdx, index)
        if(rootIdx==0):
            break
        index = rootIdx
        rootIdx = (index -1) >> 1
        
        
def swap(arr, i , j):
    arr[i],arr[j]=arr[j],arr[i]       
lst=[6,5,4,3,5,2,8]
heapSort(lst)
print(lst)
_____________________________________________________________
output: [2, 3, 4, 5, 5, 6, 8]

排序中的稳定性是指,排序过后,在原始数组中相对次序不改变。
1.冒泡排序可以实现稳定性:遇到相同值时,则让下一个值进行移动。
2.插入排序也可以实现稳定性,方法与冒泡类似,遇到相同值时,让前面的一个值再往前找
3.选择排序做不到稳定性
4.归并排序可以实现稳定性,归并排序划分为左右两个区域,我们可以规定在归并的时候,遇到相同值时,让左边的先拷贝下来,再拷贝右边的值。
5.堆排序做不到稳定性
6.快速排序也做不到稳定性
现实世界的业务需要稳定性,保证原始信息不被抹去。
总结一下:
具有稳定性的排序:冒泡排序,插入排序,归并排序
不具有稳定性的排序:选择排序,堆排序,快速排序
工程中的综合排序:
如果是基础数据类型,则在工程中选择快排,基础类型的稳定性无意义,都是数字3,在前在后是一样的。
如果是自定义的数据额结构,则在工程中是快速排序,保证稳定性。
如果长度小于60,则用插入排序