简单选择排序
基本思想:
在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。
void selectsort(int *a, int n)
{
for (int i = 0; i < n; ++i)
{
int min = i;
for (int j = i + 1; j < n; j++)
{
if (a[j] < a[min])
min = j;
}
int t = a[i];
a[i] = a[min];
a[min] = t;
}
}
二元选择排序
基本思想:
就是在简单选择排序的基础上一趟确定最大值和最小值。由于需要确定两个值,所有实现时要特别注意边界情况的检查,以免出现两个元素被交换两次(等于没交换)的情况。
void biselectsort(int *a, int n)
{
for (int i = 0; i < n / 2; ++i)
{
int min = i, max = n- i - 1;
for (int j = i; j <= n - i - 1; ++j)
{
if (a[j] > a[max])
max = j;
if (a[j] < a[min])
min = j;
}
// 交换数据,需要特别处理max=i,min=n-i-1的特殊情况
int t1 = a[i], t2 = a[n - i - 1], vmin = a[min], vmax = a[max];
a[i] = vmin;
a[n - i - 1] = vmax;
if (max == i && min == n - i - 1)
{
;
}
else if (max == i)
{
a[min] = t2;
}
else if (min == n - i - 1)
{
a[max] = t1;
}
else
{
a[min] = t1;
a[max] = t2;
}
}
}
堆排序
堆排序是一种O(nlogn)的排序算法,其思想是建立大顶堆(递增排序时)、小顶堆(递减排序时),然后将堆顶元素与末尾元素交换,经过n-1次之后,则形成有序的序列。
http://blog.csdn.net/morewindows/article/details/6709644/
上面这篇博客对堆排序的讲解已经非常详细了,虽然代码实现上有一些瑕疵,这里就不赘述了。
我的大顶堆(递增排序)的代码实现如下:
// 堆排序,下标从0开始,i节点的父节点为(i-1)/2, 子节点为i*2+1和i*2+2
// 建立大堆用于递增排序
void maxheapfixdown(int a[], int i, int n) // 自上而下调整堆
{// 从i开始“下沉”,n为元素个数
int j = i * 2 + 1;
int tmp = a[i];
while (j < n)
{
if (j + 1 < n && a[j + 1] > a[j])
j++;
if (a[j] <= tmp)
break;
a[i] = a[j];
i = j;
j = i * 2 + 1;
}
a[i] = tmp;
}
void makemaxheap(int a[], int n) // 建立最大堆
{// n为节点个数
for (int i = n / 2 - 1; i >= 0; --i)
maxheapfixdown(a, i, n);
}
void heapsort(int a[], int n)
{
makemaxheap(a, n);
print(a, n);
for (int i = n - 1; i >= 1; --i)
{
swap(a[0], a[i]);
maxheapfixdown(a, 0, i);
print(a, n);
}
}
小顶堆类似。