我听说过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 )
也就是说,任何重新出现的值都需要移动到数组的末尾。
我的想法是首先对数组进行冒泡,然后使用这个已排序的数组,遍历数组,将任何重复出现的数据移动到数组的末尾。
可以这样做吗?如果是,获取冒泡排序数组后的算法是什么。 或者有更好的方法来实现它。
答案 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;
}
如果需要对重复的元素进行排序,则需要另外完成(使用任何排序方法)。