• 初阶数据结构学习记录——둘 顺序表


    目录

    1、线性表

    2、顺序表

    SeqList.h

    SeqList.c


    1、线性表

    线性表是n个具有相同特征的数据元素的有限序列。在逻辑上呈现线性结构,但是物理上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。

    2、顺序表

    顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般采用数组存储。在数组上完成数据的增删查改。

    具体以代码形式呈现

    SeqList.h

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. typedef int SLDataType;
    6. typedef struct SeqList
    7. {
    8. SLDataType* a;
    9. int size; // 记录存储多少个有效数据
    10. int capacity; // 空间容量大小
    11. }SL;
    12. void SLPrint(SL* ps);
    13. void SLInit(SL* ps);
    14. void SLDestroy(SL* ps);
    15. void SLCheckCapacity(SL* ps);
    16. // 尾插尾删
    17. void SLPushBack(SL* ps, SLDataType x);
    18. void SLPopBack(SL* ps);
    19. // 头插头删
    20. void SLPushFront(SL* ps, SLDataType x);
    21. void SLPopFront(SL* ps);
    22. // 中间插入删除
    23. // 在pos位置插入数据
    24. void SLInsert(SL* ps, int pos, SLDataType x);
    25. // 删除pos位置数据
    26. void SLErase(SL* ps, int pos);
    27. // begin查找x的起始位置
    28. int SLFind(SL* ps, SLDataType x, int begin);

    SeqList.c

    1. #include"SeqList.h"
    2. void SLPrint(SL* ps)
    3. {
    4. assert(ps);
    5. for (int i = 0; i < ps->size; ++i)
    6. {
    7. printf("%d ", ps->a[i]);
    8. }
    9. printf("\n");
    10. }
    11. void SLCheckCapacity(SL* ps)
    12. {
    13. assert(ps);
    14. if (ps->size == ps->capacity)
    15. {
    16. int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    17. SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));
    18. if (tmp == NULL)
    19. {
    20. perror("realloc fail");
    21. exit(-1);
    22. }
    23. ps->a = tmp;
    24. ps->capacity = newCapacity;
    25. }
    26. }
    27. void SLInit(SL* ps)
    28. {
    29. assert(ps);
    30. ps->a = NULL;
    31. ps->size = 0;
    32. ps->capacity = 0;
    33. }
    34. void SLDestroy(SL* ps)
    35. {
    36. assert(ps);
    37. //if (ps->a != NULL)
    38. if (ps->a)
    39. {
    40. free(ps->a);
    41. ps->a = NULL;
    42. ps->size = ps->capacity = 0;
    43. }
    44. }
    45. // O(1)
    46. void SLPushBack(SL* ps, SLDataType x)
    47. {
    48. /*assert(ps);
    49. SLCheckCapacity(ps);
    50. ps->a[ps->size] = x;
    51. ps->size++;*/
    52. SLInsert(ps, ps->size, x);
    53. }
    54. void SLPopBack(SL* ps)
    55. {
    56. //assert(ps);
    57. 温柔的检查
    58. ///*if (ps->size == 0)
    59. //{
    60. //return;
    61. //}*/
    62. 暴力的检查
    63. //assert(ps->size > 0);
    64. ps->a[ps->size - 1] = 0;
    65. //ps->size--;
    66. SLErase(ps, ps->size - 1);
    67. }
    68. // O(N)
    69. void SLPushFront(SL* ps, SLDataType x)
    70. {
    71. //assert(ps);
    72. //SLCheckCapacity(ps);
    73. 挪动数据
    74. //int end = ps->size - 1;
    75. //while (end >= 0)
    76. //{
    77. // ps->a[end + 1] = ps->a[end];
    78. // end--;
    79. //}
    80. //ps->a[0] = x;
    81. //ps->size++;
    82. SLInsert(ps, 0, x);
    83. }
    84. void SLPopFront(SL* ps)
    85. {
    86. /*assert(ps);
    87. assert(ps->size > 0);
    88. int begin = 1;
    89. while (begin < ps->size)
    90. {
    91. ps->a[begin - 1] = ps->a[begin];
    92. begin++;
    93. }
    94. ps->size--;*/
    95. SLErase(ps, 0);
    96. }
    97. // 在pos位置插入数据
    98. void SLInsert(SL* ps, int pos, SLDataType x)
    99. {
    100. assert(ps);
    101. assert(pos >= 0);
    102. assert(pos <= ps->size);
    103. SLCheckCapacity(ps);
    104. int end = ps->size - 1;
    105. while (end >= pos)
    106. {
    107. ps->a[end + 1] = ps->a[end];
    108. end--;
    109. }
    110. ps->a[pos] = x;
    111. ps->size++;
    112. }
    113. // 删除pos位置数据
    114. void SLErase(SL* ps, int pos)
    115. {
    116. assert(ps);
    117. assert(pos >= 0);
    118. assert(pos < ps->size);
    119. //assert(ps->size > 0);
    120. // 挪动数据覆盖
    121. int begin = pos + 1;
    122. while (begin < ps->size)
    123. {
    124. ps->a[begin - 1] = ps->a[begin];
    125. begin++;
    126. }
    127. ps->size--;
    128. }
    129. int SLFind(SL* ps, SLDataType x, int begin)
    130. {
    131. assert(ps);
    132. for (int i = begin; i < ps->size; ++i)
    133. {
    134. if (ps->a[i] == x)
    135. {
    136. return i;
    137. }
    138. }
    139. return -1;
    140. }

    之前的通讯录本身与顺序表相似,不过顺序表重点在于头插头删,尾插尾删,指定位置增删功能。尾部操作都是直接改变size来实现,而头部两个操作异曲同工,需要一个个挪动元素。指定位置增删也相似,增加右移,留出pos位置,然后添加。删除则是左移覆盖过去。当实现pos位置增删后,头尾插删其实也就可以完全用这两个函数来代替。

    结束。

  • 相关阅读:
    C++ 提高编程
    【高阶数据结构】图详解第三篇:最小生成树(Kruskal算法+Prim算法)
    【Hyperledger Fabric 学习】部署智能合约到通道上
    k8s 创建UserAccount
    .NET6发布项目到腾讯云Windows2012R全网最详细教程
    肝了47天最终上岸美团,这份最新版千页Java八股到底是有多全面?
    Docker手把手教程(二)核心命令
    AOP(JDK动态代理实现)
    scrollIntoView多重校验rules滚动到指定位置
    SSM整合流程
  • 原文地址:https://blog.csdn.net/kongqizyd146/article/details/127623766