• 【C】顺序表


    目录

    顺序表

            头文件

            源文件

    相关练习


    顺序表

    顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构

            头文件

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. typedef int SLDataType;//将 int 重命名为 SLDataType
    6. typedef struct SeqList
    7. {
    8. SLDataType* data;//指向存储数据空间的指针
    9. int capacity;//表当前的最大容量
    10. int size;//表中当前数据数量
    11. }SL;
    12. void SLInit(SL* psl);//初始化表
    13. void SLDestroy(SL* psl);//释放表中数据
    14. void SLInsert(SL* psl, size_t pos, SLDataType x);//将数据插入表中指定位置前
    15. void SLPushFront(SL* psl, SLDataType x);//头插
    16. void SLPushBack(SL* psl, SLDataType x);//尾插
    17. void SLErase(SL* psl, int pos);//删除表中指定数据
    18. void SLPopFront(SL* psl);//头删
    19. void SLPopBack(SL* psl);//尾删
    20. int SLFind(SL* psl, SLDataType x);//查找表中指定数据并返回下标
    21. void SLModify(SL* psl, int pos, SLDataType x);//修改表中指定数据

            源文件

    1. #include"SeqList.h"
    2. void SLInit(SL* psl)//初始化表
    3. {
    4. assert(psl);
    5. psl->data = NULL;
    6. psl->capacity = psl->size = 0;
    7. }
    8. void SLDestroy(SL* psl)//释放表中数据
    9. {
    10. assert(psl);
    11. if (psl->data == NULL)
    12. return;
    13. free(psl->data);
    14. psl->data = NULL;
    15. psl->capacity = psl->size = 0;
    16. }
    17. void AddCap(SL* psl)//扩容
    18. {
    19. assert(psl);
    20. int newcap = psl->capacity == 0 ? 4 : psl->capacity * 2;//增容后的容量
    21. SLDataType* tmp = (SLDataType*)realloc(psl->data, newcap * sizeof(SLDataType));//重新开辟空间
    22. assert(tmp);//判断空间是否开辟失败
    23. psl->data = tmp;//将新开辟的空间赋给指向存放数据空间的指针
    24. psl->capacity = newcap;//更新原容量
    25. }
    26. void SLInsert(SL* psl, size_t pos, SLDataType x)//将数据插入到下标 pos 前
    27. {
    28. assert(psl);
    29. assert(pos <= psl->size && pos >= 0);//pos 要在 size 间,pos = size 时为尾插
    30. if (psl->capacity == psl->size)//检查容量
    31. AddCap(psl);
    32. //将 pos 后的数据依次向后移动一位(包括 pos),最后给 pos 位赋值
    33. int end = psl->size;//最后一个元素的后一个位置
    34. while (end > pos)
    35. {
    36. //向后移动
    37. psl->data[end] = psl->data[end - 1];
    38. end--;
    39. }
    40. //赋值
    41. psl->data[pos] = x;
    42. psl->size++;
    43. }
    44. void SLPushFront(SL* psl, SLDataType x)//头插
    45. {
    46. assert(psl);
    47. SLInsert(psl, 0, x);
    48. }
    49. void SLPushBack(SL* psl, SLDataType x)//尾插
    50. {
    51. assert(psl);
    52. SLInsert(psl, psl->size, x);
    53. }
    54. void SLErase(SL* psl, int pos)//删除表中下标为 pos 的数据
    55. {
    56. assert(psl);
    57. assert(pos < psl->size&& pos >= 0);//pos 要在 size
    58. if (psl->size == 0)//判断数据是否为空
    59. return;
    60. //将 pos 后的数据依次向前覆盖
    61. while (pos < psl->size - 1)
    62. {
    63. psl->data[pos] = psl->data[pos + 1];
    64. pos++;
    65. }
    66. psl->size--;
    67. }
    68. void SLPopFront(SL* psl)//头删
    69. {
    70. assert(psl);
    71. SLErase(psl, 0);
    72. }
    73. void SLPopBack(SL* psl)//尾删
    74. {
    75. assert(psl);
    76. SLErase(psl, psl->size - 1);
    77. }
    78. int SLFind(SL* psl, SLDataType x)//查找表中指定数据并返回下标
    79. {
    80. assert(psl);
    81. for (int i = 0; i < psl->size; i++)
    82. {
    83. if (psl->data[i] == x)
    84. {
    85. return i;
    86. }
    87. }
    88. return -1;//未找到返回 -1
    89. }
    90. void SLModify(SL* psl, int pos, SLDataType x)//修改表中下标为 pos 数据
    91. {
    92. assert(psl);
    93. assert(pos < psl->size && pos > -1);// pos 要在 size
    94. psl->data[pos] = x;
    95. }

    相关练习

    (1)27. 移除元素 - 力扣(LeetCode) https://leetcode.cn/problems/remove-element/

    思路:使用两个下标分别寻找 val 和非 val,使用找到的非 val 替换找到的 val。

    1. int removeElement(int* nums, int numsSize, int val)
    2. {
    3. int des = 0;//用来找 val
    4. int src = 0;//用来找非 val
    5. while (src < numsSize)
    6. {
    7. if (nums[src] != val)
    8. {
    9. nums[des] = nums[src];
    10. des++;
    11. src++;
    12. }
    13. else
    14. {
    15. src++;
    16. }
    17. }
    18. return des;//这时的 des 正好是元素个数
    19. }

    (2)26. 删除有序数组中的重复项 - 力扣(LeetCode) https://leetcode.cn/problems/remove-duplicates-from-sorted-array/

    思路:使用两个下标,一个快,一个慢,当两个下标指向的值相等,快下标继续向后寻找不同的值并赋给慢下标的后一个位置。

    1. int removeDuplicates(int* nums, int numsSize)
    2. {
    3. int slow = 0;
    4. int fast = 0;
    5. while (fast < numsSize)
    6. {
    7. if (nums[fast] == nums[slow])
    8. {
    9. fast++;
    10. }
    11. else
    12. {
    13. slow++;
    14. nums[slow] = nums[fast];
    15. fast++;
    16. }
    17. }
    18. return slow + 1;
    19. }

    (3)88. 合并两个有序数组 - 力扣(LeetCode) https://leetcode.cn/problems/merge-sorted-array/

    思路:定义 3 个下标,分别指向如下位置。

     将下标 1 和下标 3 指向的值进行对比,把较大的值放入下标 2 指向的位置,依次向前。

    1. void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
    2. {
    3. int end1 = m - 1;
    4. int end2 = n - 1;
    5. int index = m + n - 1;
    6. while (end1 >= 0 && end2 >= 0)
    7. {
    8. if (nums1[end1] > nums2[end2])
    9. {
    10. nums1[index] = nums1[end1];
    11. end1--;
    12. index--;
    13. }
    14. else
    15. {
    16. nums1[index] = nums2[end2];
    17. end2--;
    18. index--;
    19. }
    20. }
    21. if (end2 >= 0)//2 号数组剩下元素进行拷贝,由于 1 号数组为自身,所以无需拷贝
    22. {
    23. while (end2 >= 0)
    24. {
    25. nums1[index] = nums2[end2];
    26. index--;
    27. end2--;
    28. }
    29. }
    30. }

  • 相关阅读:
    【代码随想录】算法训练计划16
    net-tools 和 iproute2 笔记221103
    Apache Seata -- 一款开源的分布式事务解决方案
    算法|每日一题|倍数求和|容斥原理
    springboot中如何进行业务层测试事务回滚
    小米妙想PC端连接平板5教程
    【零基础入门MyBatis系列】第三篇——使用MyBatis完成CRUD
    Yolov5如何训练自定义的数据集,以及使用GPU训练,涵盖报错解决
    记录 mybatis plus QuerWapper使用 FIND_IN_SET
    小节3:数据类型
  • 原文地址:https://blog.csdn.net/Domeecky/article/details/126804251