选择排序与堆排序
一,直接选择排序
思路比较简单:即依次从剩余记录中选取最小的
二,堆排序
利用堆的思想,建立一个最大堆,把堆顶的元素(最大值)拿掉,再重新建堆,依次递归
代码
void heapSort(int data[], int len)
{
heapify(data, len);
int end = len - 1;
while(end > 0)
{
//将根节点放到最后,因为根节点总是最大的
int tmp = data[end];
data[end] = data[0];
data[0] = tmp;
//由于根节点的值被修改了,需要对以该节点为根的树进行siftDown操作,该操作执行完后,能够保证其仍然是最大堆
siftDown(data, 0, end - 1);
end--;
}
}
void heapify(int data[], int len)
{
int start = (len - 2) /2; //指向最后一个父亲节点
while(start >= 0)//从下往上建立最大堆
{
siftDown(data, start, len - 1);
start--;
}
}
//该方法只是确保以start为根节点的树是一个最大堆,但是不会保证start + 1为根节点的树
void siftDown(int data[], int start, int end)
{
int root = start;
while(root * 2 + 1 <= end) //若具有儿子节点
{
int child = root * 2 + 1;
//判断是否具有右儿子节点,并指向最大的儿子节点
if(child < end && data[child] < data[child + 1])
{
child = child + 1;
}
//将较大的作为父亲节点
if(data[child] > data[root])
{
int tmp = data[root];
data[root] = data[child];
data[child] = tmp;
//循环下去,确保被更新的儿子节点是其子树的最大值
root = child;
}
else
{
break;
}
}
}