仅限 0到n-1这种情况。数组包含n个元素,只不过可能是乱序的,需要排序。
1.检测是否有序:
2.排序。拿起第一个元素k,将其放到p[k]位置,刚才的p[k]元素,也放到他相应的位置上。
#include <iostream>
#include <algorithm>
#include <iterator>
#include <time.h>
#include <stdio.h>
using namespace std;
void sort_n(int *p, int n, int &);
void func_test();
void time_test();
int main()
{
//1.功能测试
cout<<"1.功能测试"<<endl;
//func_test();
//2.性能测试
cout<<"2.性能测试"<<endl;
time_test();
return 0;
}
void func_test()
{
int n = 100;
int it = 0;
int const N = 40;
int x;
while(it++ < n)
{
int ar[N];
int j;
for (j = 0; j< N; j++)
ar[j] = j;
random_shuffle(ar, ar + N);
cout<<it<<endl;
cout<<"原始数组:";
copy(ar, ar + N, ostream_iterator<int>(cout, " ") );
cout<<endl;
sort_n(ar, N, x);
cout<<"排序数组:";
copy(ar, ar + N, ostream_iterator<int>(cout, " ") );
cout<<endl;
cout<<endl;
}
}
void time_test()
{
clock_t t1, t2;
int N = 10000;
int M = 0;
int *ap = NULL;
int length[] = {1000, 10000, 100000, 1000000};
int k = 0;
int x = 0;
for (k=0; k<4; k++)
{
M = length[k]; // 数组长度
ap = new int[M];
int s = 0; // 累积时间
int i = 0;
x = 0;
while(i<N)
{
int j;
for (j=0; j < M; j++)
ap[j] = j; // 构造数组并置乱
random_shuffle(ap, ap + M);
t1 = clock(); // 排序并计时
sort_n(ap, M, x);
t2 = clock();
s += (t2 - t1);
i++;
}
delete []ap;
//cout<<"长度为 "<<M<<" 的数组,循环 "<<N<<" 次 的时间: "<<s<<endl;
printf("长度为 %-8d 的数组,循环 %d 次, 耗时: %-4d ms, 复杂度 %d\n", M, N, s, x);
}
}
// 假定输入是合法的,0 ~ n-1 之间的乱序数组
void sort_n(int *p, int n, int &x)
{
if (p == NULL || n <= 0) return;
int tmp1, tmp2;
int i;
for (i=0; i<n; i++)
{
if (p[i] == i) continue;
x++;
tmp1 = p[i];
p[i] = -1; // 起始的点标记为-1,用于判断是否回到起始点
while (p[tmp1] != -1)
{ // 每遇到一个点,做三件事:1.将该点的值放入tmp1,2.将p[tmp1]暂存到tmp2;3.将p[tmp1]赋值为tmp1. 最后更新tmp1的值进入下次循环
x++;
tmp2 = p[tmp1];
p[tmp1] = tmp1;
tmp1 = tmp2;
}
p[tmp1] = tmp1;
}
}
1.功能测试
2.性能测试
长度为 1000 的数组,循环 10000 次, 耗时: 47 ms, 复杂度 9990184
长度为 10000 的数组,循环 10000 次, 耗时: 528 ms, 复杂度 99990747
长度为 100000 的数组,循环 10000 次, 耗时: 10161 ms, 复杂度 999990558
长度为 1000000 的数组,循环 10000 次, 耗时: 857858 ms, 复杂度 1410055579
PS:看复杂度觉得挺线性的,为什么时间的表现这么。。。