1、前正后负(2018吉林大学941)
一个长度为n的数组由负数、0、正数组成。编写函数,将其重新排列为前段都是负数,后段均为非负数(正数和0都为非负数)的结构。要求时间复杂度为O( n )。
本题的解题思想:
从一个无序的数组变成一个有序的数组,首先想到的是遇到正数和0后移,然后整体前移,遇负数位置不动,但是考虑到时间复杂度O(n),因此只能有一层循环,所以就想到建一个新数组,开始遍历,遇到正数放后面同时后面的指针前移,遇负数方前面同时前面的指针后移,直到将a[n]遍历完成为止。
#include <iostream>
using namespace std;
const int n=10;//const 定义了一个常量
int main()
{
int a[n]={1,-2,-3,4,0,-1,2,3,5,-2};
int b[n];
for(int i=0,j=0,q=0;i<n;i++)//由于主要算法只有一层循环,因此时间复杂度为O(n)
{
if(a[i]<0)//当a[n]中数据<0时,将其放在b[n]的前面,则此时b[n]前面就被占据了一位
{
b[j]=a[i];
j++;
}
else if(a[i]>=0)//当a[n]中数据>=0时,将其放在b[n]的后面,则此时b[n]后面就被占据了一位
{
b[n-1-q]=a[i];//b[n]的下标是从9结尾的,因此要减一,而b[n]后面被占据了一位,因此要b[n-1-p]
q++;
}
}
cout<<"原序列为:"<<endl;
for(int i=0;i<n;i++)
{
cout<<a[i]<<",";
}
cout<<endl<<"排序后的序列为:"<<endl;
for(int i=0;i<n;i++)
{
cout<<b[i]<<",";
}
return 0;
}