- 论坛徽章:
- 0
|
挑战数组腾挪大法
[这个贴子最后由samhoo在 2002/10/26 12:13pm 编辑]
实在是愚钝,费了牛劲才把它实现出来。
MoveIt是完成交换的核心函数。
Check用于检验结果的正确性。
MakeRandomList生成随机数组
CreateList分配内存。
它们无关主题,图省事直接从别的书抄过来了。
不知道还有没有更明了的算法。
wwjxjtu算法复杂度为O(n^2),代价太高。
蛤蟆兄不如简单说明一下思路。
#include<stdio.h>;
/*
* 问题:给定一个数组long L[n],且已知X是其中的一个元素, 请调整该数组
* 使得所有小于X的元素位于数组左边, 大于X的元素位于数组右边, 并得到X
* 在数组中的下标.
*
* 要求:1)如何不使用额外的数组; 2)时间复杂度不大于O(n)
*
* 算法: left = 0; right = n - 1;
* 1)比较L[left]和X, 如果小于X, left加1, 重复本步骤;
* 如果等于X跳到步骤2; 如果大于X, 跳到步骤3.
* 2)比较L[left]以右的数, 如果小于X,交换之, left加1, 重复本步骤
* 如果等于X, left加1, 重复本步骤; 如果大于X, 跳到步骤3.
* 3)做法与步骤1相似, right向左移动.
* 4)做法与步骤2相似, right向左移动.
* 5)交换L[left], L[right];
*/
#define DISPLAY \
{ \
int i; \
printf("L[]=" ; \
for (i = 0; i < num; i++) \
printf("%d ", L); \
printf("\n" ; \
}
int Check(long *L, int num, int X, int position);
int SWAP(long *L, int a, int b);
long *MakeRandomList(int *num);
long *CreateList(int n);
int MoveIt(long *L, int n, long X)
{
int left = 0, left_ep = 0, right = n -1, right_ep = n - 1;
/* 大数:大于X的数; 小数:小于X的数 */
while(left < right){
/* 找到左边用于交换的大数 */
while( (L[left] <= X) && (left < right) ){
if (L[left] < X){ /* 如果是小数,向右移动 */
left++;
left_ep++;
}
else{
while((L[left] == X) && (left <= right))
left++;
if (left >; right)
break;
SWAP(L, left, left_ep);
if (L[left] < X){
left++;
left_ep++;
}
else
left = left_ep;
}
}
/* 找到右边用于交换的小数 */
while( (L[right] >;= X) && (left < right) ){
if (L[right] >; X){
right--;
right_ep--;
}
else{
while((L[right] == X) && (left <= right))
right--;
if (left >; right)
break;
SWAP(L, right, right_ep);
if (L[right] >; X){
right--;
right_ep--;
}
else
right = right_ep;
}
}
/* 交换 */
if (left < right){
SWAP(L, left, right);
left++;
left_ep++;
right--;
right_ep--;
}
}
return left_ep;
}
int main()
{
long X;
long *L;
//long L[]={5,5,5,5,5,5,7,1,6,8};
int num = 10;
int pos = 0;
L=MakeRandomList(&num);
X = L[(num - 1) / 2];
printf("X=%ld\n", X);
DISPLAY
printf("--------------------------------------------------------------------\n" ;
pos = MoveIt(L, num, X);
if (Check(L, num, X, pos))
printf("incorrect.\n" ;
else
printf("correct.\n" ;
printf("--------------------------------------------------------------------\n" ;
printf("position=%ld\n", pos);
DISPLAY
return 0;
}
long *CreateList(int n)
/* Allocates memory for an array of n longs */
{
long *L;
L = (long *) malloc( n * sizeof(long) );
if( L == NULL) { /* Exit program if memory cannot be allocated */
printf("\nCannot allocate enough memory for list.\n" ;
exit(0);
}
return (L);
}
long *MakeRandomList(int *num)
{
long *L; /* pointer to List */
unsigned int seed; /* seed for random number generator */
int i; /* index of for loop */
printf("\nNumber of elements to sort=>;" ;
scanf("%d",num);
printf("\nSeed for random number generator (integer)=>;" ;
scanf("%d",&seed);
srand(seed);
/* Allocate memory for # of elements. If memory cannot be allocated,
display message and terminate program. Read in the elements. */
L = CreateList(*num);
if (L == NULL) {
printf("\nCannot allocate enough memory for number list.\n" ;
exit(0);
}
for (i = 0; i < *num; ++i)
L = rand();
return(L); /* Return the List */
}
int Check(long *L, int num, int X, int position)
{
int i, lpos, rpos;
for (i = 0; i < num; i++)
if (L == X)
break;
lpos = i;
for (i = num - 1; i >;= 0; i--)
if (L == X)
break;
rpos = i;
for (i = lpos; i <= rpos; i++)
if (L != X)
return -1;
for (i = 0; i < lpos; i++)
if (L >; X)
return -1;
for (i = num - 1; i >; rpos; i--)
if (L < X)
return -1;
if ( (position < lpos) || (position >; rpos) )
return -1;
return 0;
}
int SWAP(long *L, int a, int b)
{
long temp;
temp = L[a];
L[a] = L;
L = temp;
return 0;
}
这是几组输出结果:
X=5
L[]=5 5 5 5 5 5 7 1 6 8
--------------------------------------------------------------------
correct.
--------------------------------------------------------------------
position=1
L[]=1 5 5 5 5 5 5 7 6 8
Number of elements to sort=>;10
Seed for random number generator (integer)=>;1
X=31051
L[]=16838 5758 10113 17515 31051 5627 23010 7419 16212 4086
--------------------------------------------------------------------
correct.
--------------------------------------------------------------------
position=9
L[]=16838 5758 10113 17515 5627 23010 7419 16212 4086 31051
欢迎给出反例子(如果有的话) |
|