• 数据结构-静态链表创建


    静态链表:

            也是一种线性存储结构,它结合了顺序表和链表的优点,既能快速访问元素,又能快速增加或删除数据元素。使用静态链表存储数据,数据全部存储在数组中(和顺序表一样),但存储位置是随机的,数据之间"一对一"的逻辑关系通过一个整形变量(称为"游标",和指针功能类似)维持(和链表类似)。

    创建静态链表实例:

    存储数据:{1,2,3}

    在内存中开辟一块大小为6的空间,

     再给数组中分配数据和游标:

     在上图中,从 a[1] 存储的数据元素 1 开始,通过存储的游标变量 3,就可以在 a[3] 中找到元素 1 的直接后继元素 2;同样,通过元素 a[3] 存储的游标变量 5,可以在 a[5] 中找到元素 2 的直接后继元素 3,这样的循环过程直到某元素的游标变量为 0 截止(因为 a[0] 默认不存储数据元素)。

    在静态链表的结点中分成数据域和游标两部分,根据游标可以找到下一个结点在数组中的存储位置。通常,静态链表会将第一个数据元素放到数组下标为 1 的位置(a[1])中。

    静态链表的节点:

    静态链表存储数据元素也需要自定义数据类型,至少需要包含以下 2 部分信息:

    数据域:用于存储数据元素的值;

    游标:其实就是数组下标,表示直接后继元素所在数组中的位置;

    1. typedef struct {
    2. int data;//数据域
    3. int cur;//游标
    4. }component;

     备用链表:

    静态链表中,除了数据本身通过游标组成的链表外,还需要有一条连接各个空闲位置的链表,称为备用链表。
    备用链表的作用是回收数组中未使用或之前使用过(目前未使用)的存储空间,留待后期使用。也就是说,静态链表使用数组申请的物理空间中,存有两个链表,一条连接数据,另一条连接数组中未使用的空间。

    通常,备用链表的表头位于数组下标为 0(a[0]) 的位置,而数据链表的表头位于数组下标为 1(a[1])的位置。

    静态链表中设置备用链表的好处是,可以清楚地知道数组中是否有空闲位置,以便数据链表添加新数据时使用。比如,若静态链表中数组下标为 0 的位置上存有数据,则证明数组已满。

    上图中,备用链表上连接的依次是 a[0]、a[2] 和 a[4],而数据链表上连接的依次是 a[1]、a[3] 和 a[5]。 

    创建静态链表:

     (1)在数据链表未初始化之前,数组中所有位置都处于空闲状态,因此都应被链接在备用链表上,

    当向静态链表中添加数据时,需提前从备用链表中摘除节点,以供新数据使用。

    插入数据:

     完整代码:

    1. #include
    2. #define maxSize 6
    3. //定义静态链表结点
    4. typedef struct{
    5. int data;
    6. int cur;
    7. }component;
    8. //创建备用链表
    9. void reserveArr(component*array){
    10. for(int i=0;i
    11. array[i].cur=i+1;
    12. array[i].data=-1;
    13. }
    14. array[maxSize-1].cur=0;//链表最后一个结点游标为0
    15. }
    16. //提取分配空间
    17. int mallocArr(component* array){
    18. //若备用链表非空则返回分配的结点的下标,否则返回0 (当分配最后一个结点时,该结点的游标值为 0)
    19. int i=array[0].cur;
    20. if(array[0].cur){
    21. array[0].cur=array[i].cur;
    22. }
    23. return i;
    24. }
    25. //初始化静态链表
    26. int initArr(component*array){
    27. reserveArr(array);
    28. int body=mallocArr(array);
    29. //声明一个变量,把它当指针使,指向链表的最后的一个结点,因为链表为空,所以和头结点重合
    30. int tempBody=body;
    31. for (int i=1; i<4; i++) {
    32. int j=mallocArr(array);//从备用链表中拿出空闲的分量
    33. array[tempBody].cur=j;//将申请的空闲分量链接在链表的最后一个结点后面
    34. array[j].data=i;//给新申请的分量的数据域初始化
    35. tempBody=j;//将指向链表最后一个结点的指针后移
    36. }
    37. array[tempBody].cur=0;//新的链表最后一个结点的指针设置为0
    38. return body;
    39. }
    40. void displayArr(component * array,int body){
    41. int tempBody=body;//tempBody准备做遍历使用
    42. while (array[tempBody].cur) {
    43. printf("%d,%d ",array[tempBody].data,array[tempBody].cur);
    44. tempBody=array[tempBody].cur;
    45. }
    46. printf("%d,%d\n",array[tempBody].data,array[tempBody].cur);
    47. }
    48. int main(){
    49. component array[maxSize];
    50. int body=initArr(array);
    51. printf("静态链表为:\n");
    52. displayArr(array, body);
    53. return 0;
    54. return 0;
    55. }

    输出结果:

  • 相关阅读:
    从服务智能化中寻找新增量
    python项目模块打包本地发布并上传到到PyPI官网
    SkyWalking告警通知
    springboot 从环境变量读取配置的流程
    UML之类图,继承,实现,聚合,组合
    【开发篇】十三、J2cache缓存框架
    始祖双碳新闻 | 2022年8月5日碳中和行业早知道
    SQL语句查询关键字
    递归神经网络 (RNN)
    CMake库搜索函数居然不搜索LD_LIBRARY_PATH
  • 原文地址:https://blog.csdn.net/qq_51701007/article/details/126124664