这次写一个简单的关于数组的算法编程题:
题目要求:
设数组A[0,…,n-1]的n个元素中有多个零元素,设计一个算法,将A中所有非零元素依次移动到A数组的前端。
首先,我写了一个算法程序,代码如下:
#include<stdio.h>
void moveZero(int A[],int n);
int main()
{
int k=8;
int A[k]={1,0,0,6,9,0,8,5};
moveZero(A,k);
for(int i=0; i<k; i++)
{
printf("%d",A[i]);
}
}
void moveZero(int A[],int n)
{
int i;
for(i=0; i<n; i++) //目的:遍历整个数组
{
if(A[i] == 0) //找到数组中等于零的元素
{
for(int j=i+1; j<n; j++) //再继续寻找不等于零的元素
{
if(A[j] != 0) /*找到不等于零的元素,赋值给A[i],
并将A[j]直接赋值为零即可,并跳出此内循环*/
{
A[i] = A[j];
A[j] = 0;
// i = i+1; //这里想多了,不需要,加上就错
break;
}
}
}
}
}
说明:
这段程序代码思路比较清晰,但是完成后,看一下,发现时间复杂度为O((n2+n)/2)=O(n2),有点大,对于这样一个简单的题目来说不值得,所以得进行改进。于是乎,有了下面的代码:
#include<stdio.h>
void moveZero(int A[],int n);
int main()
{
int k=8;
int A[k]={1,0,0,6,9,0,8,5};
moveZero(A,k);
for(int i=0; i<k; i++)
{
printf("%d",A[i]);
}
}
void moveZero(int A[],int n)
{
int i,j=-1,temp;
for(i=0; i<n; ++i)
{
if(A[i] != 0) //A[i]为第一个不为零的元素
{
++j;
if(j != i) /*A[i]不在位置j,即第一个不为零的元素
前面有零元素,则交换A[j]与A[i]*/
{
temp = A[j];
A[j] = A[i];
A[i] = temp;
}
}
}
}
说明:
此算法的时间复杂度为O(n),大大提高时间效率。
当然此程序后半部分的交换可以不需要这么做,因为由已知则可直接将A[i]赋值为0即可,即如下代码:
#include<stdio.h>
void moveZero(int A[],int n);
int main()
{
int k=8;
int A[k]={1,0,0,6,9,0,8,5};
moveZero(A,k);
for(int i=0; i<k; i++)
{
printf("%d",A[i]);
}
}
void moveZero(int A[],int n)
{
int i,j=-1;
for(i=0; i<n; ++i)
{
if(A[i] != 0) //A[i]为第一个不为零的元素
{
++j;
if(j != i)
{
A[j] = A[i];
A[i] = 0;
}
}
}
}