方法一:从头扫描这个数组,每碰到一个正数时,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位。挪完 之后在数组的末尾有一个空位,这时把该正数放入这个空位。由于碰到一个正,需要移动O(n)个数字,因此总的时间复杂度是O(n2),空间复杂度为O(1)。

View Code
 1 #include <iostream.h>
 2 void fun1(int a[],int n)
 3 {
 4     if (n<1)
 5     {
 6         cout<<"input error!"<<endl;
 7         return;
 8     }
 9     int num=0;
10     for (int k=0;k<n;k++)
11     {
12         if (a[k]<0)
13         {
14             num++;
15         }
16     }
17 
18     int temp;
19     for (int i=0;i<n;i++)
20     {
21         if (i<num)
22         {
23             while(a[i]>0)
24             {
25                 temp=a[i];
26                 for(int j=i+1;j<n;j++)
27                 {
28                     a[j-1]=a[j];
29                 }
30                 a[n-1]=temp;
31             }
32         }
33         else
34         {
35             break;
36         }
37     }
38 
39 }
40 
41 void main()
42 {
43     int data[6]={9,1,15,7,-5,-12};
44     fun1(data,6);
45     for (int i=0;i<6;i++)
46     {
47         cout<<data[i]<<" ";
48     }
49 }

方法二:既然题目要求的是把负数放在数组的前半部分,正数放在数组的后半部分,因此所有的负数应该位于正数的前面。也就是说我们在扫描这个数组的时候,如果发现有正数出现在负数的前面,我们可以交换他们的顺序,交换之后就符合要求了。因此我们可以维护两个指针,第一个指针初始化为数组的第一个数字,它只向后移动;第二个指针初始化为数组的最后一个数字,它只向前移动。在两个指针相遇之 前,第一个指针总是位于第二个指针的前面。如果第一个指针指向的数字是正而第二个指针指向的数字是负数,我们就交换这两个数字。时间复杂度为O(n),空间复杂度为O(1).

View Code
 1 #include <iostream.h>
 2 #include <algorithm>
 3 using namespace std;
 4 void fun2(int a[],int n)
 5 {
 6     if (n<=1)
 7     {
 8         return;
 9     }
10     int low=0,high=n-1;
11     while(low<high)
12     {
13         while(a[low]<0 && low<high)
14         {
15             low++;
16         }
17         while(a[high]>0 && low<high)
18         {
19             high--;
20         }
21         swap(a[low],a[high]);
22     }
23 
24 }
25 
26 void main()
27 {
28     int data[6]={-1,1,15,-3,-5,-12};
29     fun2(data,6);
30     for (int i=0;i<6;i++)
31     {
32         cout<<data[i]<<" ";
33     }
34 }

方法三:与方法二相类似,不过此方法不会改变数组中元素的相对顺序。

View Code
 1 #include <iostream.h>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 void fun3(int *a,int n)
 6 {
 7     if (NULL==a || n<=1)
 8     {
 9         return;
10     }
11     int *p=a;
12     int *q=a;
13     int *pos=q;
14     while(p<a+n)
15     {
16         if (*p<0)
17         {
18             swap(*p,*q);
19             pos=q;
20             while(pos<p)
21             {
22                 ++pos;
23                 swap(*pos,*p);
24             }
25             q++;
26         }
27         p++;
28     }
29 }
30 
31 void main()
32 {
33     int data[6]={-1,1,15,-3,-5,-12};
34     fun3(data,6);
35     for (int i=0;i<6;i++)
36     {
37         cout<<data[i]<<" ";
38     }
39 }

方法四:分配一段与原数组相同大小的内存,从左至右遍历一遍原数组,将负数放在分配内存中前部分,并记录负数的个数;然后再一次从左至右遍历一遍数组,找出正数,将正数放在已放好的负数后面,此时负数已经在前面,而正数在后面,并且它们之间的相对顺序也未改变。时间复杂度为O(n),但是空间复杂度为O(n)。

View Code
 1 #include <iostream.h>
 2 #include <string.h>
 3 
 4 void fun4(int *a,int n)
 5 {
 6     if (NULL==a || n<=1)
 7     {
 8         return;
 9     }
10     int num1=0,num2=0;
11     int *temp=new int[n];
12     for (int i=0;i<n;i++)
13     {
14         if (a[i]<0)
15         {
16             temp[num1]=a[i];
17             num1++;
18         }
19     }
20     num2=n-num1;
21     if (num2<=0)
22     {
23         return;
24     }
25     num2=0;
26     for (i=0;i<n;i++)
27     {
28         if (a[i]>0)
29         {
30             temp[num1+num2]=a[i];
31             num2++;
32         }
33     }
34     memcpy(a,temp,sizeof(int)*n);
35     delete []temp;
36 }
37 
38 
39 void main()
40 {
41     int data[6]={1,1,15,3,5,12};
42     fun4(data,6);
43     for (int i=0;i<6;i++)
44     {
45         cout<<data[i]<<" ";
46     }
47 }