• 让人不顺眼的顺序表


    顺序表的本质:数组

    此篇实现顺序表

    一、基本框架

    1. 初始设置

    1. #include
    2. #include
    3. #include
    4. typedef int SLDataType;
    5. typedef struct SeqList
    6. {
    7. SLDataType* a; //存数据
    8. int size; //大小
    9. int capacity; //容量
    10. }SL;

     

    2. 函数实现概览

    1. void SLInit(SL* ps);
    2. void SLDestroy(SL* ps);
    3. void SLPrint(SL* ps);
    4. void SLPushBack(SL* ps, SLDataType x);
    5. void SLPushFront(SL* ps, SLDataType x);
    6. void SLPopBack(SL* ps);
    7. void SLPopFront(SL* ps);
    8. int SLFind(SL* ps, SLDataType x); //此处返回的是下标,所以返回类型是int
    9. void SLInsert(SL* ps, int pos, SLDataType x);
    10. void SLErase(SL* ps, int pos);

    二、函数实现

    1. 初始化

    1. void SLInit(SL* ps)
    2. {
    3. assert(ps);
    4. ps->a = NULL;
    5. ps->size = 0;
    6. ps->capacity = 0;
    7. }

     

    2. 销毁

    1. void SLDestroy(SL* ps)
    2. {
    3. assert(ps);
    4. if (ps->a != NULL)
    5. {
    6. free(ps->a);
    7. ps->a = NULL;
    8. ps->size = 0;
    9. ps->capacity = 0;
    10. }
    11. }

     

    3. 打印

    注意检查是否为空

    1. void SLPrint(SL* ps)
    2. {
    3. assert(ps);
    4. if (ps->size == 0)
    5. printf("ݴӡ\n");
    6. else
    7. {
    8. for (int i = 0; i < ps->size; i++)
    9. {
    10. printf("%d ", ps->a[i]);
    11. }
    12. printf("\n");
    13. }
    14. }

     

    4. 检查函数

    此函数可以不包含在头文件中,因为只在SeqList.c文件中使用

    1. void CheckCap(SL* ps)
    2. {
    3. assert(ps);
    4. if (ps->size == ps->capacity)
    5. {
    6. int newCap = ps->capacity == 0 ? 4 : ps->capacity * 2;
    7. SLDataType* tmp = (SLDataType*)realloc(ps->a, newCap*sizeof(SLDataType));
    8. if (tmp == NULL)
    9. {
    10. perror("realloc");
    11. return;
    12. }
    13. ps->a = tmp;
    14. ps->capacity = newCap;
    15. }
    16. }

    为什么我看顺序表不顺眼,就是因为每一次插入数据都要检查容量是否足够,内存小了要扩容,而没有用上的空间就会被浪费,烦不烦?!

    5. 尾插头插

    1. void SLPushBack(SL* ps, SLDataType x)
    2. {
    3. assert(ps);
    4. CheckCap(ps);
    5. ps->a[ps->size] = x;
    6. ps->size++;
    7. }

    头插前还得将后面的元素往后调,真服了~

    1. void SLPushFront(SL* ps, SLDataType x)
    2. {
    3. assert(ps);
    4. CheckCap(ps);
    5. for (int i = ps->size ; i > 0; --i)
    6. {
    7. ps->a[i] = ps->a[i - 1];
    8. }
    9. ps->a[0] = x;
    10. ps->size++;
    11. }

     

    6. 尾删头删

    1. void SLPopBack(SL* ps)
    2. {
    3. assert(ps);
    4. assert(ps->size > 0);
    5. ps->size--;
    6. }

    头删完之后还得将后面的元素往前调,麻烦!

    1. void SLPopFront(SL* ps)
    2. {
    3. assert(ps);
    4. assert(ps->size > 0);
    5. int begin = 0;
    6. while (begin < ps->size)
    7. {
    8. ps->a[begin] = ps->a[begin + 1];
    9. ++begin;
    10. }
    11. ps->size--;
    12. }

    7. 查找

    遍历就完事了

    1. int SLFind(SL* ps, SLDataType x)
    2. {
    3. assert(ps);
    4. int i = 0;
    5. for (i = 0; i < ps->size; i++)
    6. {
    7. if (ps->a[i] == x)
    8. break;
    9. }
    10. return i;
    11. }

    8. 插入消除

    与前面的函数类似

    1. void SLInsert(SL* ps, int pos, SLDataType x)
    2. {
    3. assert(ps);
    4. assert(pos > 0 && pos <= ps->size); //保证位置合法
    5. CheckCap(ps);
    6. for (int i = ps->size-1; i >= pos; i--)
    7. {
    8. ps->a[i + 1] = ps->a[i];
    9. }
    10. ps->a[pos] = x;
    11. ps->size++;
    12. }

    1. void SLErase(SL* ps, int pos)
    2. {
    3. assert(ps);
    4. assert(pos > 0 && pos < ps->size);
    5. int begin = pos + 1;
    6. while (begin < ps->size)
    7. {
    8. ps->a[begin - 1] = ps->a[begin];
    9. ++begin;
    10. }
    11. ps->size--;
    12. }

    虽然顺序表有很多的缺点,但也不是一无是处,比如找尾的速度是比链表快的。

    所以任何事情都要辩证看待呀,不要一叶障目不见泰山。

    三、代码汇总

    SeqList.h

    1. #include
    2. #include
    3. #include
    4. typedef int SLDataType;
    5. typedef struct SeqList
    6. {
    7. SLDataType* a;
    8. int size;
    9. int capacity;
    10. }SL;
    11. void SLInit(SL* ps);
    12. void SLDestroy(SL* ps);
    13. void SLPrint(SL* ps);
    14. void SLPushBack(SL* ps, SLDataType x);
    15. void SLPushFront(SL* ps, SLDataType x);
    16. void SLPopBack(SL* ps);
    17. void SLPopFront(SL* ps);
    18. int SLFind(SL* ps, SLDataType x);
    19. void SLInsert(SL* ps, int pos, SLDataType x);
    20. void SLErase(SL* ps, int pos);

    SeqList.c

    1. #include "SeqList.h"
    2. void SLInit(SL* ps)
    3. {
    4. assert(ps);
    5. ps->a = NULL;
    6. ps->size = 0;
    7. ps->capacity = 0;
    8. }
    9. void SLDestroy(SL* ps)
    10. {
    11. assert(ps);
    12. if (ps->a != NULL)
    13. {
    14. free(ps->a);
    15. ps->a = NULL;
    16. ps->size = 0;
    17. ps->capacity = 0;
    18. }
    19. }
    20. void SLPrint(SL* ps)
    21. {
    22. assert(ps);
    23. if (ps->size == 0)
    24. printf("ݴӡ\n");
    25. else
    26. {
    27. for (int i = 0; i < ps->size; i++)
    28. {
    29. printf("%d ", ps->a[i]);
    30. }
    31. printf("\n");
    32. }
    33. }
    34. void CheckCap(SL* ps)
    35. {
    36. assert(ps);
    37. if (ps->size == ps->capacity)
    38. {
    39. int newCap = ps->capacity == 0 ? 4 : ps->capacity * 2;
    40. SLDataType* tmp = (SLDataType*)realloc(ps->a, newCap*sizeof(SLDataType));
    41. if (tmp == NULL)
    42. {
    43. perror("realloc");
    44. return;
    45. }
    46. ps->a = tmp;
    47. ps->capacity = newCap;
    48. }
    49. }
    50. void SLPushBack(SL* ps, SLDataType x)
    51. {
    52. assert(ps);
    53. CheckCap(ps);
    54. ps->a[ps->size] = x;
    55. ps->size++;
    56. }
    57. void SLPushFront(SL* ps, SLDataType x)
    58. {
    59. assert(ps);
    60. CheckCap(ps);
    61. for (int i = ps->size ; i > 0; --i)
    62. {
    63. ps->a[i] = ps->a[i - 1];
    64. }
    65. ps->a[0] = x;
    66. ps->size++;
    67. }
    68. void SLPopBack(SL* ps)
    69. {
    70. assert(ps);
    71. assert(ps->size > 0);
    72. ps->size--;
    73. }
    74. void SLPopFront(SL* ps)
    75. {
    76. assert(ps);
    77. assert(ps->size > 0);
    78. int begin = 0;
    79. while (begin < ps->size)
    80. {
    81. ps->a[begin] = ps->a[begin + 1];
    82. ++begin;
    83. }
    84. ps->size--;
    85. }
    86. int SLFind(SL* ps, SLDataType x)
    87. {
    88. assert(ps);
    89. int i = 0;
    90. for (i = 0; i < ps->size; i++)
    91. {
    92. if (ps->a[i] == x)
    93. break;
    94. }
    95. return i;
    96. }
    97. void SLInsert(SL* ps, int pos, SLDataType x)
    98. {
    99. assert(ps);
    100. assert(pos > 0 && pos <= ps->size);
    101. CheckCap(ps);
    102. for (int i = ps->size-1; i >= pos; i--)
    103. {
    104. ps->a[i + 1] = ps->a[i];
    105. }
    106. ps->a[pos] = x;
    107. ps->size++;
    108. }
    109. void SLErase(SL* ps, int pos)
    110. {
    111. assert(ps);
    112. assert(pos > 0 && pos < ps->size);
    113. int begin = pos + 1;
    114. while (begin < ps->size)
    115. {
    116. ps->a[begin - 1] = ps->a[begin];
    117. ++begin;
    118. }
    119. ps->size--;
    120. }

  • 相关阅读:
    这样做框架结构图,让你的PPT更有创意!
    微软中国总部半日游学小记
    Chrome 扩展是什么?我们如何建造它?
    Java+SSM+Vue网上书城系统源码+论文+答辩PPT
    Docker部署ZooKeeper分布式协调服务
    前沿对话:聚焦元宇宙,数字营销都能玩什么丨温州元宇宙月
    22款奔驰GLE450升级香氛负离子 清新淡雅
    《HelloGitHub》第 72 期
    奥威BI做数据可视化大屏报表,不踩坑更省心
    微信小程序日历插件用法-举例为(爸妈搜日历)
  • 原文地址:https://blog.csdn.net/m0_73969414/article/details/134478683