10-排序6 Sort with Swap(0, i) (25分)

表排序的典型题目。


分析:

/* 假设每个环的元素个数分别为m1, m2, ...
 * 其中,单一元素的环说明了该元素在正确的位置上,不考虑。多元素的环,所有元素都不在正确的位置上。
 *
 * 1. 第一个环(包括0的环),每次swap(0, i),i是arr[0]的值,都把i置于正确的位置。
 * 最后一次同时把0和最后一个要交换的元素置于正确的位置,因此swap次数是 m1 - 1,(m1 >= 2)。
 * 2. 其余环(元素个数大于1),每次都需要把其中一个元素跟0交换。
 * 然后,经过m[i] - 1次swap,其余元素都置于正确的位置,在经过一次swap,此环所有元素都置于正确的位置。
 * 同时0回到位置0.因此,swap次数是m[i] + 1.
 * 3. 算出第一个环的元素个数,算出元素大于0的环的个数。
*/


代码:

#include <iostream>
using namespace std;

//在Elem类中,isSelected作为判断元素是否已经被选入其他环的判定变量。
//只有单一元素的环,可以不更新。
struct Elem {
    bool isSelected = false;
    int data;
};

int elemCntInEachCircle(Elem *&eArr, int pos) {
    int ret = 1;
    int tmp(pos);
    //环的起点:pos位置的元素可以不改变isSelected,因为后面不会再访问到(这边就忽略了)。
    //但是该环的其他位置的元素必须要改变isSelected。
    while(eArr[tmp].data != pos) {
        tmp = eArr[tmp].data;
        eArr[tmp].isSelected = true;
        ++ret;
    }
    return ret;
}

int main(void) {
    int n;
    cin >> n;
    Elem *eArr = new Elem[n];
    for(int i(0); i < n; ++i)
        cin >> eArr[i].data;
    //第一个环的元素个数
    int elemCnt = elemCntInEachCircle(eArr, 0);
    int swapCnt = 0;
    if(elemCnt > 1) swapCnt += elemCnt - 1;
    //元素个数>1的环的swap次数,依次累加到swapCnt。
    for(int i(1); i < n-1; ++i) {
        if(eArr[i].isSelected) continue;
        elemCnt = elemCntInEachCircle(eArr, i);
        if(elemCnt > 1) swapCnt += elemCnt + 1;
    }

    cout << swapCnt << flush;

    delete[] eArr;
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值