`

实现只有0、1、2的数组的排序

 
阅读更多
题目:一个数组中只有0,1,2三种元素,要求对这样的数组进行排序。

1.思路:

1.1思路1:

  第一眼看到这样的题目,会举得非常简单,只需要两次遍历数组就可以完成了。第一次遍历,扫描数组中的元素,每次遇到0则count0++,遇到1则count1++,遇到2则count2++,这样一趟下来就能够统计出数组中0,1,2的个数了。然后第二次遍历的时候,只需要对数组进行重新赋值就可以了,从头开始赋值count0个0,count1个1,count2个2。最终完成对数组的排序。

1.2思路2:

  既然是面试题,那么肯定不会让你这么简单就解决出来了的。面试官说,加入只能进行一次遍历怎么办,然后你就不知道了。

  这道题目如果只能进行一次遍历,我们肯定会想到使用多指针。这种题目之前碰到过很多。类似折半查找需要设置两个指针,不过这道题目却需要三个指针,分别指向数组中0,1,2三个元素末尾。加入有排好序的数组{0,0,1,1,2,2},那么p0指向下标为1的那个0,p1指向下标为3的那个1,而p2则指向下标为5的那个2。

p0和p1从前往后扫描,p2从后往前扫描,

初始化时:

p0指向第一个非0元素,那么arry[p0]=1||2

p1指向第一个非1元素,那么arry[p1]=0||2

p2指向第一个非2元素,那么arry[p2]=0||1

假如:

arry[p0]==2,arry[p2]==0,交换两个元素

arry[p1]==2,arry[p2]==1,交换两个元素

arry[p0]==1,arry[p1]==0,交换两个元素

否则的话只可能是p0,p1,p2指向的三个数各不相同,那么进行如下赋值

arry[p0]==0,arry[p1]==1,arry[p2]==2。

假如经过上述swap以后出现i>k的情况,将k=i。(PS:2012-10-5)

2.代码示例

复制代码
#include<iostream>
#include<stdlib.h>
using namespace std;

void PrintArry(int arry[],int len)
{
    for(int i=0;i<len;i++)
        cout<<arry[i]<<" ";
    cout<<endl;
}

void swap(int arry[],int i,int j)
{
    int temp=arry[i];
    arry[i]=arry[j];
    arry[j]=temp;
}

void sort(int arry[],int len)
{

    int i= 0;//头指针指向0
    int j = len - 1;//尾指针指向2
    int k = 0;//中间指针指向1
    while(i <= j && k <= j && i <= k)
    {
        //i指向第一个非0值
        while(arry[i] == 0){
            i++;
        }
        //k指向第一个非1值
        while(arry[k] == 1){
            k++;
        }
        //j指向第一个非2值
        while(arry[j] == 2){
            j--;
        }

        if(i <= j && arry[j] == 0 && arry[i] == 2){
            swap(arry,i,j);
            i++;
            j--;
        }

        else if(k <= j && arry[k] == 2 && arry[j] == 1){
            swap(arry,k,j);
            k++;
            j--;
        }

        else if(i <= k && arry[k] == 0 && arry[i] == 1){
            swap(arry,k,i);
            i++;
            k++;
        }

        else if(i < k && k < j){
            arry[i] = 0;
            arry[k] = 1;
            arry[j] = 2;
            i++;
            k++;
            j--;
        }

        if(i>k)
        {
            k=i;
        }
    } 
}

void main()
{
    int arry[]={1,0,2,2,0,1,0,1};
    int len=sizeof(arry)/sizeof(int);

    PrintArry(arry,len);
    sort(arry,len);
    PrintArry(arry,len);

    system("pause");
}                
复制代码
 
简化思路:

经试验sort函数好像还可以精简
void sort(int arry[],int len)
{

int i= 0;//头指针指向0
int k = 0;//中间指针指向1
int j = len - 1;//尾指针指向2
while(k <= j && i <= k)
{
//i指向第一个非0值
while(arry[i] == 0)
i++;
//k指向第一个非1值
while(arry[k] == 1)
k++;
//j指向第一个非2值
while(arry[j] == 2)
j--;
if(i > k)
k = i;

if(i < j && arry[j] == 0 && arry[i] == 2)
{
swap(arry,i,j);
}
else if(k <j && arry[k] == 2 && arry[j] == 1)
{
swap(arry,k,j);
}
else if(i < k && arry[k] == 0 && arry[i] == 1)
{
swap(arry,k,i);
}
else if(i < k && k < j)
{
arry[i] = 0;
arry[k] = 1;
arry[j] = 2;
}

}

分享到:
评论

相关推荐

    使用快速排序法对一维数组进行排序

    3. **递归排序**:对基准左右两边的子数组分别进行快速排序,这个过程一直持续到子数组只有一个元素,排序结束。 在实际应用中,选择基准的方式会影响快速排序的效率。常见的方法有以下几种: - **首尾取中法**:取...

    VC多线程实现数组排序

    本话题主要探讨如何利用VC++的多线程特性来实现数组排序。数组排序是计算机科学中的基本问题,通常涉及各种排序算法,如冒泡排序、选择排序、插入排序、快速排序等。而将多线程应用于排序可以显著提高处理大量数据时...

    java数组排序.docx

    "Java数组排序" Java数组排序是Java语言中对数组进行排序的方法,包括快速排序、选择排序、冒泡排序和插入排序等。这些排序算法都是Java语言中常用的数组排序方法,每种算法都有其特点和应用场景。 冒泡排序是Java...

    c 实现数组和指针的快速排序

    3. **递归排序(Recursion)**:对基准左边和右边的子数组分别进行快速排序,直到所有子数组只有一个元素或者为空,排序结束。 以下是一个简单的C语言实现快速排序的示例代码: ```c #include void swap(int* a,...

    VB 数组做参数合并排序

    在VB(Visual Basic)编程中,数组是一种存储多个相同类型数据的数据结构,它允许程序员以高效的方式处理一组数据。...因此,对于VB编程中的数组排序需求,特别是需要处理大量数据时,合并排序是一个理想的选择。

    用C语言实现数组元素最大值/最小值查找、数组元素平均值计算、数组元素排序等功能

    利用C语言可以实现对数组的各种操作,如输入数组元素,输出数组元素、求数组元素平均值、输出数组元素最大值、输出数组元素最小值、查找某数值元素是否存在、给数组元素排序等功能。本压缩文件中是上述功能对应的...

    归并排序C语言实现

    2. **递归**:归并排序的分治过程通常用递归来实现。在C语言中,递归函数可以方便地处理这种自相似的问题。递归调用需要一个基本情况(base case),即当数组只有一个或零个元素时,可以直接认为它是有序的,无需再...

    使用直接插入法对一维数组进行排序

    1. **初始状态**:数组分为已排序部分和未排序部分,开始时,已排序部分只有一个元素,即数组的第一个元素。 2. **比较与移动**:从未排序部分选取第一个元素,与已排序部分的最后一个元素进行比较。如果选取元素较...

    java进阶(文件读写、递归、数组排序、单体工厂模式)

    本课程着重讲解了四个核心概念:文件读写、递归、数组排序以及单体工厂模式。这些知识点都是Java开发者日常工作中不可或缺的部分。 首先,我们来探讨文件读写。在Java中,文件操作主要依赖于I/O(Input/Output)流...

    Golang算法问题之数组按指定规则排序的方法分析

    1. **有效性检查**:在进行排序之前,我们先检查数组是否为空或者只有一个元素,如果是,则直接返回原数组。 2. **排序逻辑**:我们使用Go标准库中的`sort`包来实现排序。为了能够支持多列排序,我们需要定义一个...

    排序问题(选择法排序, 冒泡法排序, 合并法排序),VB6.0源代码编写

    在VB6.0中,这三种排序算法的源代码实现会涉及到基本的数组操作,条件判断,循环结构以及可能的递归调用。文件"VB090610-排序问题(选择法排序, 冒泡法排序, 合并法排序)"应该包含了这三个排序算法的详细代码示例,...

    【源代码】C++算法(五)一维数组去重(复杂度为n且不新开辟空间)

    这段代码会将数组`{1, 2, 3, 2, 4, 3, 5, 6}`去重为`{1, 2, 3, 4, 5, 6, 0, 0}`,其中`0`作为结束标记。在实际应用中,可能需要根据具体需求来处理这些重复元素。 数组去重算法的效率关键在于它只遍历数组一次,...

    c语言编程题之数组操作删除排序数组中的重复项.zip

    // 如果数组为空或只有一个元素,无需处理 int j = 0; // 用于记录新数组的索引 for (int i = 1; i ; i++) { if (arr[i] != arr[j]) { // 当前元素与前一个元素不相等 arr[++j] = arr[i]; // 将不重复的元素...

    C语言数组(C语言课件)

    a[0][0]、a[0][1]、a[0][2]等是数组的元素,它们占用的是连续的内存空间。 字符数组是一种特殊的数组类型,它用于存储字符串。例如,char a[10];定义了一个字符数组,数组名为a,此数组有10个元素。a[0]、a[1]、a[2...

    java实现归并排序

    在上面的代码实现中,我们可以看到,归并排序的时间复杂度为 O(nlog2^n),这是因为我们需要将原始数组分割成小组,并对每个小组进行排序,然后将排序好的小组合并成一个有序数组。空间复杂度为 O(N),这是因为我们...

    Python自定义类的数组排序实现代码

    总结起来,Python自定义类的数组排序可以通过`sort()`方法和`lambda`表达式实现,这种方式灵活且高效。`lambda`表达式提供了一种创建简短匿名函数的途径,尤其适用于简单的操作,如上述的比较和计算。理解这些概念...

    C语言实现的插入排序

    初始时,已排序部分只有一个元素(数组的第一个元素)。接下来,每次从未排序部分取出一个元素,与已排序部分的元素进行比较,并找到合适的位置将其插入,确保插入后已排序部分仍然保持有序。这个过程会一直持续到...

    归并排序算法实现(排序算法系列1)

    2. 递归排序:对每个子数组递归执行归并排序。如果子数组只有一个元素,那么它已经是有序的,无需进一步处理。否则,继续将子数组分割并排序。 3. 合并:这是归并排序的关键步骤。将两个已排序的子数组合并为一个...

    快排序的Java实现

    1. **选择枢轴元素(Pivot Selection)**:在待排序的数组中选取一个元素作为枢轴,通常选择第一个或最后一个元素,也可以随机选择。 2. **分区操作(Partitioning)**:重新排列数组,使得所有小于枢轴的元素位于枢...

    常见数组面试题

    否则,递归调用`sum(a, n - 1)`来计算除最后一个元素外所有元素的和,再加上最后一个元素`a[n - 1]`的值,从而实现了整个数组的求和功能。这种递归策略简洁明了,同时避免了循环的显式控制结构,使代码更加紧凑。 #...

Global site tag (gtag.js) - Google Analytics