堆排序
算法思想: 堆排序我们需要用到堆这个数据结构(大根堆,小根堆),大根堆与小根堆就是一颗完全二叉树,大根堆的根节点总是大于儿子节点,小根堆反之,根节点总是小于儿子节点。对于堆我们要实现插入,调整操作。对于数组我们先建立好堆,每次我们从堆顶拿出元素放入数组尾部,然后对堆的 size 进行减一操作,最后得到遍历好的数组。
删除: 对某个 index 进行插入元素,判断当前 index 是否大于(小于)根节点,向上调整直到满足大(小)堆的性质
调整: 根据堆的大小从顶调整整颗完全二叉树
手动模拟一次(大根堆):
代码实现:
void heapInsert(int arr[], int index ){
while( arr[index] > arr[(index - 1) / 2] ){
swap( arr[index], arr[(index - 1) / 2] );
index = (index - 1) / 2;
}
}
void heapIfy( int arr[], int index, int heapsize ){
int left = index * 2 + 1;
while( left < heapsize ){
int largest = left + 1 < heapsize && arr[left + 1] > arr[left] ? left + 1 : left;
largest = arr[largest] > arr[index] ? largest : index;
if( largest == index )
break;
swap( arr[largest], arr[index] );
index = largest;
left = index * 2 + 1;
}
}
void heapSort( int arr[], int n ){
if( n <= 1 ){
return ;
}
for( int idx = 0; idx < n; ++ idx ){
heapInsert( arr, idx );
}
int heapsize = n;
swap( arr[0], arr[-- heapsize] );
while( heapsize > 0 ){
heapIfy( arr, 0, heapsize );
swap( arr[0], arr[-- heapsize] );
}
}
最后排序算法末尾我们附上几种时间空间复杂度的表格: