调整阵列中的位置以保持增加的顺序

时间:2014-01-21 17:14:26

标签: c arrays algorithm sorting swap

我在逻辑创建中遇到过C中的一个问题。我要做的是:

1)我有数组a[215] = {0,1,2,3,4,5}。现在我必须添加这个数组的两个最小元素,然后定位在同一个数组中获得的新元素,这样它将保持数组的递增顺序(a [ ],已经排序的数组)。

(2)我还必须注意两个最小添加元素不得再次参与排序和添加,如果已经添加它们必须固定在它们的位置,但是通过添加新获得的元素可以参与另外,再次排序。 例如: 我们添加两个最小元素0 and 1, 0+1=1, so "1"是通过加法获得的结果,现在这个"1"必须位于[]中,这样仍然应该有增加的顺序。 所以:

0 1 1(added here) 2 3 4 5

现在我们必须再次找到最少两个节点(请再次阅读评论(2)以便了解)。我们无法再次添加0 abnd 1因为他们已经参与了另外。所以这次我们将添加1和2(这个是在索引3处,请不要与索引2处的那个混淆)。所以我们得到1 + 2 = 3

0 1 1 2 3 3 4 5我们再次定位3以维持增加的顺序。 我们再次重复:对于索引4和5处的元素(因为我们已经在索引0,1和2,3处添加了元素),我们将得到3+3=6,再将它放在[]中。

0 1 1 2 3 3 4 5 6这次6大于4和5所以它会在5之后出现以保持增加的顺序。

At last we will get a[] like this:
a[ ]= [0 1 1 2 3 3  4 5 6 9 15].

所以保持的增加是在指数0,1和2,3以及4,5和6,7和8,9之间,最后我们有15,这是最后一个,所以在这里我们停止。

现在我已经实施了多少: 我已经实现了这个添加部分,它在数组a[ ] = [0 1 2 3 4 5]上添加了。 并将新获得的元素放在最后一个索引(我的代码中的dataSize,请参阅data[dataSize++]=newItem)

每次我调用函数PositionAdjustOfNewItem(data,dataSize);给出数组(其中也包含最后索引处新获得的元素)作为第一个参数,新获得的大小作为第二个参数。这是下面的代码:

for(i=0;i<14;i++)
   for(j=1;j<15;j++)
   { 
      // This freq contains the given array (say a[]=[0 1 2 3 4 5] in our case and
      // it is inside the struct Array { int freq}; Array data[256]; )
      newItem.freq = data[i].freq + data[j].freq;
      data[dataSize++]=newItem;
      PositionAdjustOfNewItem(data,dataSize);  // Logic of this function I am not able to develop yet. Please help me here
      i=i+2; 
      j=j+1;
   }

我无法实现函数PositionAdjustOfNewItem()的逻辑,它传递数组data [],它包含所有元素和最后索引处新添加的元素,第二个参数传递新获得的元素将新获取的元素放在最后一个索引之后的数组大小。 每当我添加两个元素时,我称之为PositionAdjustOfNewItem(),最后传递新添加的元素和新获得的大小。应该由此函数PositionAdjustOfNewItem()。

排序

此PositionAdjustOfNewItem()具有尽可能最低的复杂性。代码上方的部分只是为了让您了解我用于添加元素的机制,您无需执行任何操作,我需要你的帮助只是获得PositionAdjustOfNewItem()的逻辑。 (即使我已经使用qsort()完成了它,但复杂性非常高)。所以还需要其他方式吗?

1 个答案:

答案 0 :(得分:0)

这样的事情怎么样:

注意:在您的示例中,您正在处理一些具有freq字段的结构数组。在我的例子中,我使用简单的整数数组。

#include <stdio.h>
#include <string.h>

int a[] = {0,1,2,3,4,5};

int main(void) {
  int i,j;
  // Initialize a new array big enough to hold the result.
  int* array = new int[15];
  memcpy(array, a, 6*sizeof(int));
  int length=6;

  // Loop over consecutive indeces.
  for (i=0; i+1<length; i+=2) {
    // Get the sum of these two indeces.
    int sum=array[i]+array[i+1];

    // Insert the sum in the array, shifting elements where necessary.
    for (j=length-1; j>i+1; j--) { 
      if (sum >= array[j]) {
        // Insert here
        break;
      } else {
        // Shift
        array[j+1]=array[j];
      }
    }
    array[j+1]=sum;
    // We now have one more element in the array
    length++;
  }

  // Display the array.
  printf("{ ");
  for (j=0; j<length; j++) {
    printf("%d ", array[j]);
  }
  printf("}\n");
}

要插入总和,我们要做的是从末端到前面遍历数组,寻找它所属的点。如果我们遇到的值小于总和,那么我们只需在此值之后插入它。否则(即值大于总和),我们需要在之前插入它。因此,需要将值移动一个位置更高,然后我们检查先前的值。继续,直到找到位置。

如果你只需要PositionAdjustNewItem方法,那就是它的样子:

void PositionAdjustOfNewItem(int* array, int length) {
  int newItem = array[length-1];
  for (int j=length-2; j>i+1; j--) { 
    if (sum >= array[j]) {
      // Insert here
      break;
    } else {
      // Shift
      array[j+1]=array[j];
    }
  }
  array[j+1]=sum;
}

当你运行它时,它会产生你期望的输出。

$ ./a.out
{ 0 1 1 2 3 3 4 5 6 9 15 }