您的位置:首页 > 理论基础 > 数据结构算法

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

2016-11-10 23:08 393 查看
表排序的典型题目。

分析:

/* 假设每个环的元素个数分别为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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息