排列一个n大小的数组的所有元素,使输出数组首先包含所有负数元素,然后是零和正数元素而不排序

时间:2018-03-24 10:24:48

标签: arrays algorithm dynamic-programming partitioning

给定一个大小为n的数组,我想安排元素,以便输出将返回具有第一个所有负元素的数组,然后是零,最后是所有正元素,而不对数组进行排序。也就是说,我想将数组分成3部分,获得复杂性O(n)而不使用其他数组。

下面的代码是一次尝试,但它对数组进行排序,这不是我想要的,因为即使优化它我也只能实现时间复杂度O(nlogn)。

using System;

public class sort
{
public static void Main(string[] args)
{
    int n, k, t;
    Console.WriteLine("Enter the size of array");
    n = Convert.ToInt32(Console.ReadLine());
    int[] arr = new int[n];
    for (k = 0; k < n; k++)
    {
        Console.Write("\nEnter your number:\t");
        arr[k] = Convert.ToInt32(Console.ReadLine());
    }

    for (int j = 0; j <= n- 2; j++)
    {
        for (int i = 0; i <= n - 2; i++)
        {
            if (arr[i] > arr[i + 1])
            {
                t = arr[i + 1];
                arr[i + 1] = arr[i];
                arr[i] = t;
            }
        }
    }
    Console.WriteLine("The output array :");
    foreach (int aray in arr)
        Console.Write(aray + " ");
        Console.ReadLine();
}
}

提前感谢您的建议。

2 个答案:

答案 0 :(得分:2)

感谢m69的建议。这是C#中实现Dijkstra 3分区的正确代码:

using System;
using System.Diagnostics;

public class Program
{
    public static void Main()
    {
        int[] array1 = {1, -3, 5, 7, -9, 0, 2, -4, 6, 8, 0}; 
        printArray(partitioning(array1, 0));
    }

    public static int[] partitioning(int[] array, int mid)
    {
        int i = 0, j = 0, n = array.Length;
        Trace.Assert(n > 0);
        while (j < n)
        {
            if (array[j] < mid)
            {
                swap(ref array[i], ref array[j]);
                i += 1;
                j += 1;
            }
            else if (array[j] > mid)
            {
                swap(ref array[j], ref array[n-1]);
                n -= 1;
            }
            else 
                j += 1;
        }

        //Time complexity: O(n)
        return array;
    }

    public static void printArray(int[] array)
    {
        for(int i=0; i<array.Length; ++i) {
            Console.Write("" + array[i] + " ");
        }
        Console.WriteLine("");
    }

    public static void swap(ref int a, ref int b)
    {
        int temp = a;
        a = b;
        b = temp;
    }
}

答案 1 :(得分:0)

可以通过获取另一个数组来完成。让另一个数组 b 首先,我们遍历初始数组并将负数存储在数组 b 中。然后,我们再次遍历初始数组并将零存储在数组 b 中。这样,在数组 b 中的负数之后出现零,因为数组 b 中最后一个数字的索引在另一个变量 j中维护。现在,我们再次遍历初始数组并将正数存储在数组 b 中。这样,如果我们输出数组 b 的元素,我们将首先获得所有负数元素,然后是零,最后是所有正元素。

以下代码完全是这样的:

using System;

public class sort
{
public static void Main(string[] args)
{
    int n, k, i, t, j=0;
    Console.WriteLine("Enter the size of array");
    n = Convert.ToInt32(Console.ReadLine());
    int[] arr = new int[n];
    int[] b = new int[n];
    for (k = 0; k < n; k++)
    {
        Console.Write("\nEnter your number:\t");
        arr[k] = Convert.ToInt32(Console.ReadLine());
    }
    for(i = 0; i < n; i++){
       if(arr[i] < 0)
         {b[j] = arr[i]; j++;}
       }
    for(i = 0; i < n; i++){
       if(arr[i] == 0)
         {b[j] = arr[i]; j++;}
       }
    for(i = 0; i < n; i++){
       if(arr[i] > 0)
         {b[j] = arr[i]; j++;}
       }

    Console.WriteLine("The output array :");
    foreach (int aray in b)
        Console.Write(aray + " ");
        Console.ReadLine();
}
}

三个循环各自具有O(n)

的时间复杂度