我在完成这项家庭作业时遇到了一些问题。任务说:
“编写一个名为 MoveSmallest 的函数,该函数将所有最小整数元素移动到数组的开头。所有其余项必须保留在它们的位置。(数组及其大小是参数)
示例:数组:2、3、5、1、2、3、6、4、2、1、1变为1、1、1、2、3、5, 2、3、6、4、2
void MoveSmallest(int A[],int n)
{
int Min;
for(int i=0;i<n;i++)
{
if(i==0)
{
Min=A[i];
}
else if(A[i]<=Min)
{
Min=A[i];
}
}
到目前为止,我只想知道哪一个是数组中最小的元素。我不知道下一步该怎么做。
答案 0 :(得分:0)
从数组的末尾开始,跟踪您遇到了多少个最小元素。然后,每当遇到非最小元素时,将其移至到目前为止所遇到的最小元素数的右侧:
void MoveSmallest(int A[], int n)
{
int min;
//Find min logic
//shift non-min elements and count min elements
int cnt = 0;
for (int i = n-1; i >=0; --i)
{
if (A[i] == min)
cnt++;
else
A[i+cnt] = A[i];
}
//Add min elements
for (int i = 0; i < cnt; ++i)
A[i] = min;
}
这将在O(n)时间和O(1)空间中运行。
答案 1 :(得分:0)
一旦找到了最小值,剩下的就是要做的事情就是四处移动以使最小值在数组的开头。
您可以通过排列值直到到达数组的“左侧”(即索引0)来完成此操作。
void MoveSmallest(int A[],int n)
{
int Min;
for(int i=0;i<n;i++)
{
if(i==0)
{
Min=A[i];
}
else if(A[i]<=Min)
{
Min=A[i];
}
}
for(int i = 0; i < n; i++)
{
if(A[i] == Min)
{
for(int j = i; j > 0; j--)
{
int tmp = A[j];
A[j] = A[j-1];
A[j-1] = tmp;
}
}
}
}
您还可以使用std::swap
代替临时变量tmp
进行排列。
答案 2 :(得分:0)
由于您的帖子提到“基本C ++”,但没有提及“基本”,因此这是另一种解决方案。在这种假设下,出于“工作”目的创建数组被视为“基本C ++”。
void MoveSmallest(int A[], int n)
{
// get the minimum value
int Min = A[0];
for (int i = 1; i < n; ++i)
{
if (A[i] < Min)
Min = A[i];
}
// get the count of the number of minimum values
int minCount = 0;
for (int i = 0; i < n; ++i)
{
if (A[i] == Min)
++minCount;
}
if (minCount > 0)
{
// create a work array and fill in the first
// minCount values with the minimum value
int *B = new int[n];
for (int i = 0; i < minCount; ++i)
B[i] = Min;
// now fill in the rest of the work array with the values
// in the A[] array that are not equal to Min
int current_pos = minCount;
for (int i = 0; i < n; ++i)
{
if (A[i] != Min)
B[current_pos++] = A[i];
}
// Now copy work array back to A array
for (int i = 0; i < n; ++i)
A[i] = B[i];
// get rid of work array
delete[] B;
}
}
此时间以线性时间O(n)
运行,而不是二次时间O(n*n)
。
当然,缺点是您需要为工作阵列腾出空间,因此内存成本是线性O(n)
。