数组和链表分别比较适合用于什么场景

本文对比了数组与链表这两种基本的数据结构。介绍了数组和链表的存储方式、优缺点及适用场景,帮助读者理解两者之间的区别。

1  数组和链表简介

  在计算机中要对给定的数据集进行若干处理,首要任务是把数据集的一部分(当数据量非常大时,可能只能一部分一部分地读取数据到内存中来处理)或全部存储到内存中,然后再对内存中的数据进行各种处理。

  例如,对于数据集 S{1,2,3,4,5,6},要求 S 中元素的和,首先要把数据存储到内存中,然后再将内存中的 数据相加。当内存空间中有足够大的连续空间时,可以把数据连续的存放在内存中,各种编程语言中的数组一般都是按这种 方式存储的(也可能有例外),如图 1(b);当内存中只有一些离散的可用空间时,想连续存储数据就非常困难了, 这时能想到的一种解决方式是移动内存中的数据,把离散的空间聚集成连续的一块大空间,如图 1(c)所示,这样做 当然也可以,但是这种情况因为可能要移动别人的数据,所以会存在一些困难,移动的过程中也有可能会把一些别人 的重要数据给丢失。另外一种,不影响别人的数据存储方式是把数据集中的数据分开离散地存储到这些不连续空间中, 如图(d)。这时为了能把数据集中的所有数据联系起来,需要在前一块数据的存储空间中记录下一块数据的地址,这样只要知道第一块内存空间的地址就能环环相扣地把数据集整体联系在一起了。C/C++中用指针实现的链表就是这种 存储形式。


  由上可知,内存中的存储形式可以分为连续存储和离散存储两种。因此,数据的物理存储结构就有连续存储和离散存储两种,它们对应了我们通常所说的数组和链表

数组和链表的区别

  数组是将元素在内存中连续存储的;

            优点:因为数据是连续存储的,内存地址连续,所以在查找数据的时候效 率比较高;

            缺点:在存储之前,我们需要申请一块连续的内存空间,并且在编译的时候就必须确定好它的空间的大小。在运行的时候空间的大小是无法随着你的需要进行增加和减少而改变的,当数据两比较大的时候,有可能会出现越界的情况,数据比较小的时候,又有可能会浪费掉内存空间。在改变数据个数时,增加、插入、删除数据效率比较低链表是动态申请内存空间,不需要像数组需要提前申请好内存的大小,

        链表只需在用的时候申请就可以,根据需要来动态申请或者删除内存空间,对于数据增加和删除以及插入比数组灵活。还有就是链表中数据在内存中可以在任意的位置,通过应用来关联数据(就是通过存在元素的指针来联系)。     

链表和数组使用场景

  数组应用场景:数据比较少;经常做的运算是按序号访问数据元素;数组更容易实现,任何高级语言都支持;构建的线性表较稳定

  链表应用场景:对线性表的长度或者规模难以估计;频繁做插入删除操作;构建动态性比较强的线性表


    本文来自Java程序员面试宝典。

在C语言中,`memset` 函数用于对内存块进行初始化操作。该函数按照字节为单位进行赋值,因此对于不同类型的数据数组,初始化效果会有所不同。其函数原型定义在 `<string.h>` 头文件中,形式如下: ```c void *memset(void *s, int c, size_t n); ``` 其中: - `s` 是指向要填充的内存块的指针; - `c` 是要填充的值,以 `int` 形式传递,但实际填充的是其对应的 `unsigned char` 值; - `n` 是要填充的字节数。 ### 一维数组的初始化 对于一维数组,`memset` 可以直接使用,并且适用于各种基本数据类型。例如,初始化一个整型数组为 0: ```c #include <stdio.h> #include <string.h> int main() { int arr[5] = {0}; memset(arr, 0, sizeof(arr)); for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } ``` 如果尝试将整型数组初始化为非 0 或 -1 的值,例如 1,结果将不是预期的每个整型值为 1,而是每个整型变量的每个字节都被设置为 0x01,从而形成类似 `0x01010101` 的值[^3]。 ### 字符数组的初始化 由于 `char` 类型占 1 个字节,`memset` 对字符数组的初始化效果与预期一致。例如,将字符数组初始化为字符 `'a'`: ```c #include <stdio.h> #include <string.h> int main() { char arr[5] = {0}; memset(arr, 'a', sizeof(arr) - 1); for (int i = 0; i < sizeof(arr) / sizeof(arr[0]) - 1; i++) { printf("%c ", arr[i]); } printf("\n%s\n", arr); return 0; } ``` ### 二维数组的初始化 虽然 `memset` 也可以用于二维数组,但需注意其限制。对于二维整型数组,只能安全地初始化为 0 或 -1。以下是一个将二维整型数组初始化为 0 的示例: ```c #include <stdio.h> #include <string.h> int main() { int a[10][10]; memset(a, 0, sizeof(a)); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { printf("%d ", a[i][j]); } printf("\n"); } return 0; } ``` 对于二维数组,如果尝试使用非 0 或 -1 的值进行初始化,可能导致不可预期的结果,因为 `memset` 是按字节操作的,而整型变量通常占用多个字节[^2]。 ### 总结 `memset` 是一个高效但需谨慎使用的函数。对于字符数组,它可以灵活地初始化为任意字符;而对于整型数组,尤其是二维数组,建议仅用于初始化为 0 或 -1,以避免因字节填充导致的错误值。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值