将元素插入排序数组

Inserting element into sorted array

本文关键字:数组 插入排序 元素      更新时间:2023-10-16

我需要做的是从数组的后面工作(我必须使用动态数组)。填充数组时,我需要检查如果要插入的元素小于当前元素,我必须移动这些元素以创建一个"孔"。

假设我有一个如下所示的数组:

index:    0   |   1   |   2   |   3   |   4
value:    10  |   11  |   13  |   14  |   NULL

在我的当前代码中,数组大小始终比当前大小大 1。因此,在上面,数组的大小将为 5。这允许四处移动。

现在假设我需要将元素12插入数组中。所以我需要从位置4x[3]开始,其值为14.

我目前有以下内容:

// theSize is a private member of a class that holds the array
int j = theSize - 1;
// dynamic allocation
int *temp = new int[theSize];
for (int k = 0; k < theSize; k++) {
temp[k] = x[k];
}
delete [] x;
// using j >=0 because I need to check as low as the x[0] value
for(; j >=0 && element < temp[j]; --j) {
// So in the first run starting at x[3]
//    this would be the value at x[3] is now at x[4]
temp[j] = temp[j+1];
}
temp[j] = element;
x = temp;
delete [] temp;
theSize++

例如,在第一次运行后,数组将如下所示:

index:    0   |   1   |   2   |   3   |   4
value:    10  |   11  |   13  |       |   14

我看到很多从后面移动数组但改变的例子:

x[j] = x[j+1]x[j] = x[j-1]

我不确定你为什么要x[j-1]因为左边是 1 个值,我想向右移动。

我对数组索引的理解是否需要更正?

TL:DR我遇到的问题是,有时,当比较布尔值返回element < temp[j]时,该值不小于实际上的值。我已经通过调试器,并且正在比较正确的值,但它让我想知道它是否从旧的数组索引中提取值。

似乎你的代码有问题(你有一个new[]但有两个delete[],你认为这如何工作?

int *temp = new int[theSize];
/* ... */
x = temp;
delete [] temp;       // delete memory pointed to by x

您只需删除动态分配的数组,呈现x悬而未决的指针。我很惊讶你没有遇到分段错误。只需取下delete[] temp;


此外,无需先将所有数据复制到临时数组,然后再随机播放。您只需一次扫描即可完成所有操作:

int k = Size;             // Size is the actual size, not one larger
int*temp = new int[Size+1];
for(; k && element < x[k-1]; --k)
temp[k] = x[k-1];
temp[k] = element;
for(; k; --k)
temp[k-1] = x[k-1];
delete[] x;
x = temp;
++Size;

按原样使用std::set和 KISS。

#include <iostream>
#include <set>
using namespace std;
int main() {
std::set<int> x={10,11,13,14};
x.insert(12);

for (const int& i : x) // access by const reference
std::cout << i << ' ';
std::cout << 'n';
return 0;
}

活生生的例子!

结果:

10 11 12 13 14

注意:
这使得存储在x中的数据具有排序和唯一性,如果需要,可以将其更改为std::multiset(与set不同,允许多个具有等效值的键)。

两件事:

首先,您的代码在释放temp后分配x = temp时会产生内存泄漏和未定义的行为。

其次,我将查找元素的代码与移动数组中元素的代码分开,而不是自己复制一个值。对于复制元素,您可以使用std::copy_nstd::copy_backward(如果源和目标范围重叠)。要查找"最近"值,可以使用std::lower_bound。请参阅以下代码,该代码使程序适应这些函数的使用:

int main() {
int *x = new int[4] { 10  ,   11  ,   13  ,   14 };
int theSize = 4;
int *temp = new int[theSize+1];
std:copy_n(x, theSize, temp);
int* f = std::lower_bound(temp,temp+theSize,12);
std::copy_backward(f,temp+theSize,temp+theSize+1);
*f = 12;
delete[] x;
x = temp;
theSize++;
return 0;
}

没有足够的代表发表评论,终于在潜伏了很长时间后做了一个帐户。 我会考虑使用双向链表,使列表迭代和在设定位置注入变量变得更加容易。 例如,您可以使用 header.back 引用第一个和最后一个项目,这将是最后一个项目,将其视为一个圆圈,而 header.next 将引用第一个项目,具体取决于您如何定义标题。 您可以根据需要根据自己的用例操作链表,因为每个项目都引用它之前和之后的项目。 如果这听起来有益,我可以挖掘一些项目作为可靠的例子。