问题描述:
对一个数组排序,已知数组每个元素的移动距离不超高k,选择最合适的排序方法。
解题思路:
每个元素移动距离不超过k,说明最小的元素一定在前k个中。可以通过建立一个k个元素的最小堆,依次剔除最小元素,并加入下一个元素,循环此过程。时间复杂度为Nlgk。
源码:
#include <iostream>
#include <vector>
using namespace std;
int leftchild(int a)
{
return 2 * a + 1;
}
void perDown(vector<int> &A, int i, int n)
{
int child;
int tmp = std::move(A[i]);
for (; leftchild(i)<n; i = child)
{
child = leftchild(i);
if (child < n - 1 && A[child] > A[child + 1])
++child;
if (tmp>A[child])
A[i] = std::move(A[child]);
else
break;
}
A[i] = std::move(tmp);
}
vector<int> sortElement(vector<int> A, int n, int k) {
// write code here
vector<int> B;
for (int i = 0; i != k; ++i)
B.push_back(A[i]);
for (int i = k / 2 - 1; i >= 0; --i)
perDown(B, i, k);
vector<int> C;
C.push_back(B[0]);
for (int i = k; i < n; ++i)
{
B[0] = A[i];
perDown(B, 0, k);
C.push_back(B[0]);
}
for (int i = k - 1; i >= 0; --i)
for (int j = 0; j < i; ++j)
{
if (B[j] > B[j + 1])
std::swap(B[j], B[j + 1]);
}
for (int i = 1; i < k; ++i)
C.push_back(B[i]);
return C;
}
int main()
{
vector<int> A{ 4, 3, 2, 1, 9, 8, 7, 6 };
vector<int> c = sortElement(A, 8, 4);
for (auto x : c)
cout << x << endl;
}