# 原地排序与链表翻转

85 篇文章 0 订阅

#include <stdio.h>
#include <algorithm>
#include <vector>

struct A {
int key; // must be one kind of integer type
int val; // should be any type, use int for demo
};

void reorder(A* a, int n) {
for (int i = 0; i < n; ++i) {
if (a[i].key == i) continue;
int j = i;
int k = a[i].key;
do { // reverse the list
int next = a[k].key;
a[k].key = j;
j = k; k = next;
} while (k != i);
a[i].key = j;
int tmp = a[i].val;
do { // reorder: move to right place
a[k].key = k;
a[k].val = a[j].val;
k = j; j = a[j].key;
} while (j != i);
a[k].key = k;
a[k].val = tmp;
}
}

int main() {
int n = 20;
std::vector<A> a(n);
for (int i = 0; i < n; ++i)
a[i].key = a[i].val = i;
std::random_shuffle(a.begin(), a.end());
for (int i = 0; i < n; ++i)
printf("%d %d\n", a[i].key, a[i].val);
printf("----------------\n");
reorder(&a[0], (int)a.size());
for (int i = 0; i < n; ++i)
printf("%d %d\n", a[i].key, a[i].val);
return 0;
}


• 如果 val 类型的拷贝代价很低（比如象上面demo中的int），可以也可以不用翻转链表，多拷贝两次即可：
void reorder(A* a, int n) {
for (int i = 0; i < n; ++i) {
if (a[i].key == i) continue;
int j = i;
int k = a[i].key;
int t = a[i].val;
do {
int t2 = a[k].val;
a[j].key = j;
a[k].val = t;
j = k;
t = t2;
k = a[k].key;
} while (k != i);
a[j].key = j;
a[i].val = t;
}
}

05-24
06-14 74
01-28 193
05-18 4268
01-15 618
12-03 1521
08-01 9407
04-27 5635

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

Terark-CTO-雷鹏

¥2 ¥4 ¥6 ¥10 ¥20

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