对于数组元素的移动问题,在上一篇博客中有提到过,这篇博客通过新的问题,再介绍一些新的思路和方法。
问题描述如下:设有一数据集合Data={3,2,5,8,4,1,7,9,6},将数据集合中的所有奇数移至偶数前。
方法一:
#include<stdio.h>
void Move (int a[],int n)
{
int b[9]={0},c[9]={0};
int x=0,k=0,j;
for(j=0;j<n;j++){
if(a[j]%2!=0){
b[x++]=a[j];
}
else
c[k++]=a[j];
}
for(j=0;j<x;j++){
a[j]=b[j];
}
k=0;
for(j=x;j<n;j++){
a[j]=c[k++];
}
}
int main()
{
int i;
int a[9]={3,2,5,8,4,1,7,9,6};
Move (a,9);
for(i=0;i<9;i++)
printf("%5d",a[i]);
printf("\n");
}
分析总结:该程序思路虽然简单,但是又令设了两个数组分别来存储奇数和偶数,浪费空间,故不是首选的方法。
方法二:
#include<stdio.h>
void Move (int a[],int n)
{
int i,j,x,end;
i=0;
end=n;
while(i<end-1)
{
if(a[i]%2!=0)
i++;
else
{
x=a[i];
for(j=i;j<end-1;j++)
a[j]=a[j+1];
a[j]=x;
end--;
}
}
}
int main()
{
int i;
int a[9]={3,2,5,8,4,1,7,9,6};
Move (a,9);
for(i=0;i<9;i++)
printf("%5d",a[i]);
printf("\n");
}
方法三:快速排序
#include<stdio.h>
void Move(int a[],int n)
{
int i=0,j=n-1,t;
while(i<j)
{
while(i<n&&a[i]%2) //i从前向后找偶数
i++;
while(j>-1&&!(a[j]%2)) //j从后向前找奇数
j--;
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
int main()
{
int i;
int a[9]={3,2,5,8,4,1,7,9,6};
Move(a,9);
for(i=0;i<9;i++)
printf("%5d",a[i]);
printf("\n");
}
分析总结:本程序核心代码如下:while(i<n&&a[i]%2) i++; // i从前向后找偶数
while(j>-1&&!(a[j]%2)) j--; // j从后向前找奇数if(i<j) a[i] <=>a[j]
方法三改进:
#include<stdio.h>
void Move(int a[],int n)
{
int i=0,j=n-1,t;
while(i<j)
{
if(a[i]%2)
i++;
else if(!(a[j]%2))
j--;
else{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
int main()
{
int i;
int a[9]={3,2,5,8,4,1,7,9,6};
Move(a,9);
for(i=0;i<9;i++)
printf("%5d",a[i]);
printf("\n");
}
分析总结:与方法三相比,该程序的时间复杂度降低,运行效率提高。