什么是无界数组,无界数组和动态分配数组之间有什么区别?与无界数组相关的常见操作是什么? (就像我们有弹出并推送堆栈数据结构一样)
答案 0 :(得分:3)
无界数组可以(通常是)静态分配。
实现无界数组时的主要问题是提供动态数组,如在运行时决定数组大小,而不会影响运行时内存分配的性能损失。
excellent article on unbounded arrays 的以下摘录简明扼要地解释了这一点 -
一般实施策略如下。我们维护一个固定长度
limit
的数组和一个内部索引size
,它跟踪数组中实际有多少元素。当我们添加新元素时,我们会增加size
,当我们删除元素时,我们会减少size
。棘手的问题是当我们已经在limit
并希望添加其他元素时如何继续。此时,我们使用较大的limit
分配一个新数组,并将我们已有的元素复制到新数组中。
请注意,在运行期间,直到size
超过limit
的初始值,没有涉及无界数组的动态分配。
无界数组的一些功能(设计要求):
记住性能,与无界数组相关的唯一附加操作(与常规数组相比)是:
add_to_end()
delete_from_end()
允许修改无界数组的大小。
不提供Insert_in_middle()
和Delete_in_middle()
等操作,请记住无界数组的主要设计原则,即性能。
有关详细信息,请查看此question的答案。
注意:虽然问题特别提及动态分配的数组,但您可能还想查看dynamic arrays。动态数组的一个很好的例子是C++ std::vector
本身,它解决了几个与无界数组相同的设计原则。
子>
答案 1 :(得分:2)
真的有两个不同的概念。 静态或动态定义的数组是有限的,因为在使用它的代码中需要知道边界是什么。 对于未绑定的数组,代码需要某种方式来发现数组本身的边界。
e.g
sArray = Array[2..10] Of Integer
dArray = Array[x..y] Of Integer
void DoSomethingToArray(Array Of Integer : myArray)
{
for(int i = myArray.LowerBound; i <= myArray.UpperBound; i++)
{
// twiddle with it.
}
}
你可以将sArray或dArray传递给函数,它会非常高兴。
Lower和UpperBound是一个选项,而!Stack.Empty,List.Count&gt; 0,一个枚举器,甚至Sizeof(myArray)/ SizeOf(myArrayType)都是可能的。重要的是,传递数组的代码不必知道数组是如何绑定的,并且可以采用特定类型的任何数组。
设置数组的边界主要是分配内存。一个使用该数组的函数,应该只关心它不引用未分配给该数组的内存。
答案 2 :(得分:1)
无界数组基本上是动态的,但动态数组在术语上可能略有不同。因为你可以动态绑定一个数组。在简单的无界数组/列表中没有限制,是的,您可以从任何无界列表或数组中推送/弹出入队/出队或添加/删除。希望我的回答能够解决你的问题。
int userInput = 0;
Array dynamic_arr = new Array[userinput];//example of dynamic array
List<string> unbounded_arr = new List<string>(); // example of unbounded array
答案 3 :(得分:1)
动态分配的数组是一个固定大小的数组,其大小在创建数组时是固定的。创建数组时,动态分配是动态的。一旦创建它就会被修复。
请注意,动态分配与动态不同。
使用无界数组,在向数组添加项目和从数组中删除项目时,数组的大小可以随意增大和缩小。无界数组通常在后台使用动态分配的数组。基本上使用动态分配的数组创建内存/内存池作为效率增益,而不是在添加新项目时不断调整大小。
从TheCodeArtist链接的文章中查看无界数组的代码:
struct ubarray {
int limit; /* limit > 0 */
int size; /* 0 <= size && size <= limit */
elem[] A; /* \length(A) == limit */
};
请注意,此数组将根据需要增长(达到限制时),并且由动态分配的数组支持:
elem[] A; /* \length(A) == limit */