算法实现之简单选择排序、二元选择排序和堆排序

 

简单选择排序

基本思想:

在要排序的一组数中,选出最小(或者最大)的一个数与第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);
		}
	}

 

 

小顶堆类似。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值