自定义排序数组中的元素

时间:2013-12-14 18:15:15

标签: c++ c arrays algorithm sorting

我听说过quicksort,bubblesort,mergesort等许多分类技术。我有一个像

这样的数组
arr[]={2, 3, 4, 1, 9, 5, 1, 2, 6, 8, 1, 3}

使用冒泡排序我可以将排序完成为

arr[]={1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 8, 9}

但我需要以这种方式对给定数组进行排序

arr[]={1, 2, 3, 4, 5, 6, 8, 9, 1, 1, 2, 3 )

也就是说,任何重新出现的值都需要移动到数组的末尾。

我的想法是首先对数组进行冒泡,然后使用这个已排序的数组,遍历数组,将任何重复出现的数据移动到数组的末尾。

可以这样做吗?如果是,获取冒泡排序数组后的算法是什么。 或者有更好的方法来实现它。

2 个答案:

答案 0 :(得分:1)

您可以两次进行冒泡排序。

在第一遍中,找到最小的元素并将其放在第一位。然后找到比找到的最后一个元素更大的元素,但是从批次中最小的元素并将其放在第二位。

执行上述操作直至达到最大元素。

一旦达到最大元素,通常会对数组的剩余部分进行冒泡排序。

复杂程度:完全按照冒号排序,因为你只是分成两半。

C ++中的完整工作代码:

#include <iostream>


using namespace std;

int main()
{
    int arr[] = {2, 3, 4, 1, 9, 5, 1, 2, 6, 8, 1, 3};
    int size = 12;
    // find max element.
    int max = -1;
    for ( int I = 0; I < size; I++ ) {
      if ( arr[I] > max )
        max = arr[I];
    }


    int begin = 0;
    bool maxPlaced = false;
    int lastFound = -1;
    while ( !maxPlaced ) {

      // find the first element from the end,
      // that is greater than elements already placed.
      int end = size-1;
      while ( arr[end] <= lastFound )
          end--;

      for ( int I = end; I > begin; I-- ) {

        // swap if arr[i-1] is higher than arr[i]
        // or arr[i-1] is a number that we have already placed.
        if ( arr[I] < arr[I-1] || lastFound >= arr[I-1] ) {
            int temp = arr[I];
            arr[I] = arr[I-1];
            arr[I-1] = temp;
        }
      }
      // lastfound is the highest number that we have placed till now.
      lastFound = arr[begin];
      begin++;
      if ( lastFound == max )
        maxPlaced = true;

    }

    //continue bubble sort from begin position.
    for ( int I = begin; I < size; I++ ) {
      for ( int j = begin; j < size - 1 - (I-begin); j++ ) {
        if (arr[j] > arr[j+1]) {
            int temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
        }
      }
    }

    for ( int i = 0; i < size; i++ )
        cout << arr[i] << " ";

    return 0;
}

输出:

1 2 3 4 5 6 7 8 9 1 1 2 3

输入{4,5,6,1,1,3,3,4,4,4,1,9,9,8,8}

输出:

1 3 4 5 6 8 9 1 1 3 4 4 4 8 9

答案 1 :(得分:1)

请记住,冒泡排序是你提到的那些3中效率最低的排序算法 这是O(n2)平均情况,而其他人是O(n log n)

<强>堆排序

heap-sort的变体可以作为一种有效的(O(n log n))方式来实现。

  • 构建一堆项目。

  • 在数组中有一个左右迭代器,分别指向最左侧和最右侧位置。

  • 虽然堆不是空的:

    • 删除最大值。

    • 如果删除的项目与上次删除的项目相同,请将其插入右边的迭代器并减少迭代器。

    • 否则将其插入左迭代器并增加迭代器。

现在如果最后的项目也需要进行排序,只需颠倒它们的顺序(在上述过程结束时它们应该是相反的顺序)。

就地替代 - 选择排序

Selection sort在每一步找到最大元素,因此如果它们大于已找到的元素,可以很容易地修改它以跳过适用的元素。

这可以就地完成(上面不能这样做),但又是O(n2)

int arr[] = {2, 3, 4, 1, 9, 5, 1, 2, 6, 8, 1, 3};
int arrLength = 12;
for (int i = 0; i < arrLength; i++)
{
   int minPos = -1;
   for (int j = i; j < arrLength; j++)
      // either it's the first element, or it's greater than the last element
      //   and either it's the first such element we find, or smaller than the best one
      if ((i == 0 || arr[j] > arr[i-1]) && 
          (minPos == -1 || arr[j] < arr[minPos]))
      {
         minPos = j;
      }

   // no more elements to sort
   if (minPos == -1)
      break;

   int temp = arr[i];
   arr[i] = arr[minPos];
   arr[minPos] = temp;
}

Live demo

如果需要对重复的元素进行排序,则需要另外完成(使用任何排序方法)。