C/C++插入排序-优化版(无需额外申请存储空间)-(异或交换法)-(临时变量标记法)-(炫技版)

时间: 2020-06-16 19:43

int arr[] = { 6,9,2,5,1,7,3,8,4 };
	int len = sizeof(arr) / sizeof(arr[0]);
	
/**************************************
				第一版
**************************************/
//最容易想到的插入排序, 一般方法
	for (int i = 1; i < len; ++i) {
		for (int j = i; j > 0; --j) {
			if (arr[j] < arr[j - 1]) {
			//无需额外申请空间的异或交换法
				arr[j - 1] = arr[j] ^ arr[j - 1];
				arr[j] = arr[j] ^ arr[j - 1];
				arr[j - 1] = arr[j] ^ arr[j - 1];
			}
			else {	//此时当前元素大于当前元素的前一个元素, 直接跳出
				break;
			}
		}
	}


/**************************************
				第二版
**************************************/
/*这里把  arr[j] < arr[j - 1]  放入  for  循环括号中, 
减少代码量, 更为美观, 简洁, 且一旦  arr[j] < arr[j - 1]  条件不满足则直接跳出*/
	for (int i = 1; i < len; ++i) {
		for (int j = i; j > 0 && arr[j] < arr[j - 1]; --j) {
		//无需额外申请空间的异或交换法
			arr[j - 1] = arr[j] ^ arr[j - 1];
			arr[j] = arr[j] ^ arr[j - 1];
			arr[j - 1] = arr[j] ^ arr[j - 1];
		}
	}


/**************************************
				第三版
**************************************/
//采用临时变量标记, 确定所有需移动的元素后, 统一左移, 再插入
	for (int i = 1; i < len; ++i) {
		int tmp = arr[i];	//采用临时变量标记当前元素的值
		int p = i;	//标记当前元素的下标
		for (int j = i - 1; j >= 0; --j) {	//查找需要移动位置的最左元素的下标
			if (tmp < arr[j]) {	//判断是否符合移动情况, 符合则刷新 p 
				p = j;
			}
			else {	//此时碰到需移动位置的最左元素的左边的元素, 跳出
				break;
			}
		}

		if (p != i) {	//依次把当前元素的前一个元素直到需要移动位置的最左元素往后移动一个位置
			for (int k = i - 1; k >= p; --k) {
				arr[k + 1] = arr[k];
			}

			arr[p] = tmp;	//将当前元素插入到需要移动位置的最左元素的地方
		}
	}


/**************************************
				第四版
**************************************/
//和第三版效果一样, 但更加精炼简洁
for (int i = 1; i < len; ++i) {
		int curLastIndex = i - 1;	//当前元素的前一个元素的下标
		int curValue = arr[i];	//当前元素的值
		
		//使用 while 循环依次判断是否需要移动, 若需要, 则直接移动
		while (curLastIndex >= 0 && curValue < arr[curLastIndex]) {
			arr[curLastIndex + 1] = arr[curLastIndex];
			--curLastIndex;
		}

		arr[curLastIndex + 1] = curValue;	
		//将当前元素插入最终位置(所有需移动元素的最左元素的位置)
	}	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值