您的位置:首页 > 其它

选择排序

2016-04-06 21:28 246 查看
选择排序:每一次从待排序元素中选择一个最大的或最小的元素,顺序放在已排好序的数列最后,直到整个数列全部有序。



选择排序优化:

同时选最大和最小值,每一趟遍历标记最大最小值的位置,然后分别交换到区间两端,再缩小区间重复此操作。



每次找到目标位置后用一个tmp保存最大值位置(或最小值位置)是为了防止在该位置的值被换走。比如:



//SelectSort
void SelectSort(int *array, size_t size)
{
assert(array);
int left = 0;
int right = size - 1;
while (left<right)
{
int min = left;
int max = left;
int tmp = 0;
for (size_t index = left + 1; index < right+1; ++index)
{
if (array[index] <= array[min])
{
min = index;
}
else if (array[index]>=array[max])
{
max = index;
}
}
tmp = array[max];
swap(array[left], array[min]);
if (array[max] != tmp)
{
swap(array[min], array[right]);
}
else
{
swap(array[max], array[right]);
}
++left;
--right;
}
}


堆排序:1、建堆;升序建大堆

2、堆头和最后一个叶子交换;

3、size–,重新向下调整

堆排序时间复杂度O(nlogn),即使有序也是O(nlogn)

所以堆排序不一定比选择排序优。

//HeapSort
void AdjustDown(int *array, size_t root, size_t size)
{
assert(array);
int child = 2 * root + 1;
while (child<size)
{
if (child + 1 < size && array[child + 1] > array[child])
{
child++;
}
if (array[child] > array[root])
{
swap(array[child], array[root]);
root = child;
child = 2*root + 1;
}
else
{
break;
}
}

}

void HeapSort(int *array, size_t size)
{
assert(array);
//1、从最后一个非叶子节点开始   建堆
int root = (size - 2) / 2;
while (root >= 0)
{
AdjustDown(array, root, size);
root--;
}
//2、堆头和最后一个元素交换,“剔除”最后一个(即size--),向下调整
for (size_t index = size - 1; index > 0; --index)
{
swap(array[0], array[index]);
AdjustDown(array, 0, index);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: