排序算法之选择排序

选择排序:每一趟在n-i+1个有数据中选取最大(小)的数据,作为有序数组的第i个元素。
直接选择排序:

  • 在元素集合array[i]~array[j]中选择关键码最小的元素
  • 若他不是这组元素中的第一个元素,就将它与这组元素中的第一个元素交换
  • 在剩余的array[i+1]~array[n-1]集合中,重复以上步骤,直到结合只剩下一个元素,排序完成

代码实现:

void SelectSort(int array[], int size){
	int min;//记录最小元素的下标
	for (int i = 0; i < size - 1; i++){
		min = i;
		for (int j = i + 1; j < size; j++){
			if (array[j] < array[min]){
				min = j;
			}
		}
		if (i != min){
			int k = array[i];
			array[i] = array[min];
			array[min] = k;
		}
	}
	Print(array, size);
}

总结:

  • 时间复杂度:O(N^2)
  • 稳定性:不稳定

堆排序:
堆排序是利用堆积树这种数据机构所设计的一种排序算法,它是通过堆来进行选择数据,需要注意的是排升序建大堆,排降序建小堆。
堆的逻辑结构就是一个完全二叉树,存储结构是一个一维数组,数组中的每一个元素满足

//小堆
array[i]<=array[i*2+1];
array[i]<=array[i*2+2];
//或
//大堆
array[i]>=array[i*2+1];
array[i]>=array[i*2+2];

节点node的左节点的数组下标是node2+1,右节点的数组下标是node2+2,根节点的数组下标为0。

处理一个待排序的序列,用堆排序进行排序分为以下几步:
1.建堆升序建大堆,降序建立小堆。

建大堆只能将待排序列中的最大值放在跟节点,小堆反之。

 void GreateHeap(int array[], int size){
	for (int i = (size - 2) / 2; i >= 0; i--){
		AdjustDown(array, size, i);
	}
}
 void AdjustDown(int array[], int size, int root){

	int i = 2 * root + 1;
	int j = 2 * root + 2;

	if (i >= size){
		return;
	}

	int m = i;
	if ( j<size && array[j]>array[i])
		m = j;

	if (array[m] > array[root]){
		Swap(array + m, array + root);
		AdjustDown(array, size, m);
	}
}

2.经过一次建堆操作,找出了最大数,将这个最大的数交换到待排序列的最后位置,然后再对这个待排序列除去交换到最后位置的哪个元素再进行建堆操作,确认新的最值,然后再将新确认的最值和新的序列的最后一位元素继续交换,重复以上操作,直到新的待排序列只剩下一个元素,得到的序列就是升序(降序)的。

void HeapSort(int array[], int size){
	GreateHeap(array, size);
	for (int i = 0; i < size; i++){
		Swap(array, array + size - i - 1);
		AdjustDown(array, size-1 - i, 0);
	}
	
}

总结:
时间复杂度:O(N*logN)
空间复杂度:O(1)
稳定性:不稳定

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值