时间: 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;
//将当前元素插入最终位置(所有需移动元素的最左元素的位置)
}