我正在为C考试学习,我的教授说我对练习的解决方案不够有效。如何提高效率?
锻炼:编写一个程序,在其中初始化N个元素的数组(N是常数)。在程序中,生成并打印一个新数组,其中第一个数组中的元素将根据奇偶校验进行排序(第一个偶数,然后是奇数,它们的大小不必一定如此)。
我的解决方法是这样:
#include <stdio.h>
#define N 10
int
main ()
{
int a[N] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int b[N];
int i, j, temp;
for (i = 0; i < N - 1; i++)
{
for (j = i + 1; j < N; j++)
{
if (a[j] % 2 == 0)
{
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
for (i = 0; i < N; i++)
{
b[i] = a[i];
printf ("%d,", b[i]);
}
}
答案 0 :(得分:0)
您的算法为O(N ** 2),因为您有两个嵌套循环,每个循环都重复O(N)次。
最有效的算法的复杂度为O(n)。这是一个简单的稳定分区算法:
int write_pos = 0;
/* copy only even: O(N) */
for (int i=0 ; i < N ; i++)
{
if (a[i] % 2 == 0)
{
b[write_pos++] = a[i];
}
}
/* copy only odd: O(N) */
similar to the above
总复杂度O(N)+ O(N)= O(N)。
我正在使用额外的内存(在问题中给出了),但是分区也可以就地完成。如果可以接受不稳定分区,则在O(n)中进行分区。
如果目标是拥有O(1)个额外的内存和一个稳定的分区(保留元素的相对顺序),则运行时复杂度将变为O(n log n)。这种划分是在一半大小的数组上递归执行的。然后,通过旋转中间尺寸来合并一半尺寸的数组。