题目
Given an array with n objects colored red, white or blue,
sort them so that objects of the same color are adjacent,
with the colors in the order red, white and blue.
Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note:
You are not suppose to use the library's sort function for this problem.
Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.
Could you come up with an one-pass algorithm using only constant space?
题目大意:对一个只含0/1/2元素的数组进行排序,不能使用排序库函数。
思路一
根据题目提示,先统计数字0/1/2出现的次数,然后重写数组即可。
实现代码如下:
void sortColors(int* nums, int numsSize) {
if(nums==NULL||numsSize<2){
return;
}
int zerosCount=0;
int oneCount=0;
int twoCount=0;
for(int i=0;i<numsSize;i++){
switch(nums[i]){
case 0:zerosCount++;break;
case 1:oneCount++;break;
case 2:twoCount++;break;
default:exit(EXIT_FAILURE);
}
}
//重写nums
for(int i=0;i<numsSize;i++){
if(i<zerosCount){
nums[i]=0;
}
else if(i>=zerosCount&&i<(zerosCount+oneCount)){
nums[i]=1;
}
else{
nums[i]=2;
}
}
}
思路二
这个思路比较好,将0放在数组的前面,将2放在数组的后面。此思路来源于网络。
实现代码如下:
void swap(int *a,int *b){
int temp=*a;
*a=*b;
*b=temp;
}
void sortColors(int* nums, int numsSize) {
if(nums==NULL||numsSize<2){
return;
}
int front=0;
int back=numsSize-1;
for(int i=0;i<=back;i++){
if(nums[i]==0){
swap(&nums[front],&nums[i]);
front++;
}
else if(nums[i]==2){
swap(&nums[back],&nums[i]);//注意:这里的i要减一,这是因为,如果不减一,则换到前面的数就不再进行检查,这是不行的
back--;
i--;
}
}
// for(int i=0;i<numsSize;i++){
// printf("%d ",nums[i]);
// }
// printf("\n");
}
测试函数
int main(void){
int n;
while(scanf("%d",&n)!=EOF){
int *arr=(int *)malloc(n*sizeof(int));
if(arr==NULL){
exit(EXIT_FAILURE);
}
for(int i=0;i<n;i++){
scanf("%d",arr+i);
}
// for(int j=0;j<n;j++){
// printf("%d ",arr[j]);
// }
sortColors(arr,n);
}
}
AC结果如下: