我的问题如下:
我有一个函数来操作MAX元素数组的内容。此功能将如下所示:
//GLobal Variables
uint8_t my_array[ MAX ];
#define EMPTY 0xFF
...
void initArray( void )
{
for( uint8_t i=0; i<MAX; i++ )
{
my_array[ i ] = EMPTY;
}
}
void manipulateArray( uint8_t value )
{
for( uint8_t i=0; i<MAX; i++ )
{
if( EMPTY == my_array[ i ] )
{
my_array[ i ] = value;
break;
}
}
}
...
int main( void )
{
...
initArray();
...
while( false == exit_flag )
{
manipulateArray( value );
//get new value from user
//update exit_flag based on new value
}
...
return 0;
}
但后来我认为,如果我最终做了大量的插入/删除,那么我将使用像疯狂一样的循环,这必然会影响程序的速度或大O(N)。所以我想如果我使用另一个全局
变量用于跟踪数组中下一个空运动的位置,而不是每次都循环通过它:
//GLobal Variables
uint8_t my_array[ MAX ];
uint8_t idx = 0;
...
void manipulateArray( uint8_t value )
{
my_array[ idx++ ] = value;
}
我的假设在这里是否正确?在这种特殊情况下使用另一种更适合于操作性质(大量插入和无删位)的数据结构也是更好的:向量,链表......
提前致谢,
答案 0 :(得分:2)
通常解释一下,我带你去询问“插入”值的问题是覆盖EMPTY
值,还是用EMPTY
代替“删除”值。在这种情况下,您建议维护一个跟踪下一个“空”位置的全局变量,以避免必须在数组中搜索该位置。
实际上,如果你知道下一个插入位置的位置,那么你可以在O(1)步骤中执行插入,而如果你需要执行线性搜索,最好的界限是O(n)。如果你总是在数组的(非空部分)的末尾插入或删除,那么维护你提出的元数据是一个非常好的策略,因为你可以用O(1)步骤维护辅助变量,太
但是假设您需要支持从任意位置删除,而不移动其他数组元素,并且您还希望能够使用插入函数重新填充这些位置。在这种情况下,您必须解决维护多个空位置的信息的问题。单个标量变量是不够的,依赖于数组本身需要您在数组中搜索空位置,这将返回到您开始的位置。
另一种方法是使用更复杂的数据结构 - 例如数组或链表 - 来跟踪主阵列中的开口。通过这种方式,您可以在任何序列的任何位置实现任意数量的插入和删除的O(1)复杂度,代价是使用O(n)内存来维护关于开放阵列位置的元数据。这是一个经典的空间与速度的权衡:实现更快的算法需要使用更多的内存,但是你可以通过使用更慢的算法来节省内存。