• 【数据结构】线性表


    • 基本概念

    线性表是 0 个或者多个数据元素的有序序列

    -

    特性

    1. 数据元素之间是有序的
    2. 数据元素个数是有限的
    3. 数据元素类型是相同的

    • 性质
    • a_{0} 为线性表的第一个元素,只有一个后继。
    • a_{n} 为线性表的最后一个元素,只有一个前驱。
    • 除 a_{0} 和 a_{n} 外的其他元素 a_{i} ,既有前驱,又有后继。
    • 线性表能够逐项访问和顺序存放。

    • 线性表存储的方式

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


     C 语 言 实 现 单 链 表

    • 结构体框架
    1. typedef struct {
    2. int* pArr; // 存放数据地址
    3. int size; // 长度,当前元素个数
    4. int capacity; // 容量,当前最大能容纳元素
    5. }Dynamic_Array;
    • 操作函数声明
    1. // 初始化
    2. Dynamic_Array* Init_Array();
    3. // 插入
    4. void Push_back_Array(Dynamic_Array* arr,int val);
    5. // 根据 位置 删除
    6. void RemoveByPos_Array(Dynamic_Array* arr, int pos);
    7. // 根据 数据 删除
    8. void RemoveByValue_Array(Dynamic_Array* arr, int val);
    9. // 查找
    10. int Find_Array(Dynamic_Array* arr, int val);
    11. // 打印
    12. void Print_Array(Dynamic_Array* arr);
    13. // 释放动态数组内存
    14. void FreeSpace_Array(Dynamic_Array* arr, int pos);
    15. // 清空数组
    16. void Clear_Array(Dynamic_Array* arr);
    17. // 获取容量
    18. int Capactiy_Array(Dynamic_Array* arr);
    19. // 获取长度
    20. int Size_Array(Dynamic_Array* arr);
    21. // 根据 位置 获取元素
    22. int At_Array(Dynamic_Array* arr, int pos);
    • 操作函数实现
    1. // 初始化
    2. Dynamic_Array* Init_Array() {
    3. // 申请空间
    4. Dynamic_Array* myArray = (Dynamic_Array*)malloc(sizeof(Dynamic_Array));
    5. // 初始化
    6. myArray->size = 0;
    7. myArray->capacity = 20;
    8. myArray->pArr = (int*)malloc(sizeof(int) * myArray->capacity);
    9. return myArray;
    10. }
    11. // 插入
    12. void Push_back_Array(Dynamic_Array* arr, int val) {
    13. if (arr == NULL) return;
    14. // 判断容量是否足够
    15. if (arr->size >= arr->capacity) {
    16. // 申请更大空间 默认两倍
    17. int* NewSpace = (int*)malloc(sizeof(int) * arr->capacity * 2);
    18. // 拷贝数据到新空间
    19. if (NewSpace != NULL) {
    20. memcpy(NewSpace, arr->pArr, arr->capacity * sizeof(int));
    21. }
    22. // 释放旧空间内存
    23. free(arr->pArr);
    24. // 更新容量
    25. arr->capacity = arr->capacity * 2;
    26. // 更新指针指向
    27. arr->pArr = NewSpace;
    28. }
    29. // 尾插 插入 新元素
    30. arr->pArr[arr->size] = val;
    31. // 更新长度
    32. arr->size++;
    33. }
    34. // 根据位置删除
    35. void RemoveByPos_Array(Dynamic_Array* arr, int pos) {
    36. if (arr == NULL) return;
    37. // 判断 位置 是否有效
    38. if (pos < 0 || pos >= (arr->size)) return;
    39. // 删除
    40. for (int i = pos; i < arr->size - 1; i++) {
    41. arr->pArr[i] = arr->pArr[i + 1];
    42. }
    43. // 更新长度
    44. arr->size--;
    45. }
    46. // 根据值删除
    47. void RemoveByValue_Array(Dynamic_Array* arr, int val) {
    48. if (arr == NULL) return;
    49. int pos = Find_Array(arr, val);
    50. // 调用 按位置 删除
    51. RemoveByPos_Array(arr, pos);
    52. }
    53. // 查找
    54. int Find_Array(Dynamic_Array* arr, int val) {
    55. int pos = -1;
    56. if (arr == NULL) return pos;
    57. for (int i = 0; i < arr->size; i++) {
    58. if (arr->pArr[i] == val) {
    59. pos = i;
    60. break;
    61. }
    62. }
    63. return pos;
    64. }
    65. // 打印
    66. void Print_Array(Dynamic_Array* arr) {
    67. if (arr == NULL) return;
    68. for (int i = 0; i < arr->size; i++)
    69. printf("%d ", arr->pArr[i]);
    70. printf("\n");
    71. }
    72. // 释放动态数组内存
    73. void FreeSpace_Array(Dynamic_Array* arr) {
    74. if (arr == NULL) return;
    75. if (arr->pArr != NULL) free(arr->pArr);
    76. free(arr);
    77. }
    78. // 清空数组
    79. void Clear_Array(Dynamic_Array* arr) {
    80. if (arr == NULL) return;
    81. arr->size = 0;
    82. }
    83. // 获取容量
    84. int Capactiy_Array(Dynamic_Array* arr) {
    85. if (arr == NULL) return 0;
    86. return arr->capacity;
    87. }
    88. // 获取长度
    89. int Size_Array(Dynamic_Array* arr) {
    90. if (arr == NULL) return 0;
    91. return arr->size;
    92. }
    93. // 根据位置获取元素
    94. int At_Array(Dynamic_Array* arr, int pos) {
    95. if (arr == NULL) return -1;
    96. return arr->pArr[pos];
    97. }

    CPP 实 现 单 链 表

    • DynamicArray类声明
    1. class DynamicArray {
    2. public:
    3. // 构造
    4. DynamicArray();
    5. // 插入
    6. void Pushback_Array(const Person& p);
    7. // 根据 下标 删除
    8. void RemoveByPos_Array(const int& pos);
    9. // 根据 数据 删除
    10. void RemoveByVal_Array(const Person& p);
    11. // 根据 下标 修改
    12. void ModifyByPos_Array(const int& pos);
    13. // 根据 数据 修改
    14. void ModifyByVal_Array(const Person& p);
    15. // 根据 下标 查找
    16. Person& FindByPos_Array(const int& pos);
    17. // 根据 数据 查找
    18. int FindByVal_Array(const Person& p);
    19. // 打印
    20. void Print_Array();
    21. // 清空
    22. void Clear_Array();
    23. // 获取长度
    24. int Get_Size_Array();
    25. // 获取容量
    26. int Get_Capactiy_Array();
    27. // 析构
    28. ~DynamicArray();
    29. DynamicArray& operator=(const DynamicArray& da);
    30. public:
    31. Person* m_Parr;
    32. int m_Size;
    33. int m_Capactiy;
    34. };
    • Person类声明
    1. class Person {
    2. friend std::ostream& operator<<(std::ostream& cout, const Person& p);
    3. public:
    4. Person(std::string name, std::string sex, int age);
    5. Person();
    6. void Set_Name(std::string name);
    7. void Set_Sex(std::string sex);
    8. void Set_Age(int age);
    9. std::string Get_Name();
    10. std::string Get_Sex();
    11. int Get_Age();
    12. Person& operator=(const Person& p);
    13. bool operator==(const Person& p);
    14. private:
    15. std::string m_Name;
    16. std::string m_Sex;
    17. int m_Age;
    18. };
    19. std::ostream& operator<<(std::ostream& cout, const Person& p);
    • DynamicArray类方法实现
    1. // 构造
    2. DynamicArray::DynamicArray() {
    3. this->m_Capactiy = 20;
    4. this->m_Parr = new Person[this->m_Capactiy];
    5. this->m_Size = 0;
    6. }
    7. // 尾插
    8. void DynamicArray::Pushback_Array(const Person& p) {
    9. // 空间不足
    10. if (this->m_Size >= this->m_Capactiy) {
    11. // 创建一个新空间
    12. Person* NewSpace = new Person[this->m_Capactiy * 2];
    13. // 旧数据放到新空间
    14. for (int i = 0; i < this->m_Capactiy; i++) {
    15. NewSpace[i].Set_Name(this->m_Parr[i].Get_Name());
    16. NewSpace[i].Set_Sex(this->m_Parr[i].Get_Sex());
    17. NewSpace[i].Set_Age(this->m_Parr[i].Get_Age());
    18. //NewSpace[i] = this->m_Parr[i];
    19. }
    20. // 释放原有空间
    21. delete[] this->m_Parr;
    22. // 更改指针指向
    23. this->m_Parr = NewSpace;
    24. // 更新容量
    25. this->m_Capactiy = this->m_Capactiy * 2;
    26. }
    27. // 插入元素
    28. this->m_Parr[this->m_Size] = p;
    29. // 更新长度
    30. this->m_Size++;
    31. }
    32. // 根据 下标 删除
    33. void DynamicArray::RemoveByPos_Array(const int& pos) {
    34. if (pos < 0 || pos >= this->m_Size) {
    35. return;
    36. }
    37. // pos 位置之后开始往前移动
    38. for (int i = pos; i < this->m_Size - 1; i++) {
    39. this->m_Parr[i] = this->m_Parr[i + 1];
    40. }
    41. // 更新长度
    42. this->m_Size--;
    43. }
    44. // 根据 数据 删除
    45. void DynamicArray::RemoveByVal_Array(const Person& p) {
    46. // 通过值查找
    47. int pos = FindByVal_Array(p);
    48. // 通过下标删除
    49. RemoveByPos_Array(pos);
    50. }
    51. // 根据 下标 查找
    52. Person& DynamicArray::FindByPos_Array(const int& pos) {
    53. return this->m_Parr[pos];
    54. }
    55. // 根据 数据 查找
    56. int DynamicArray::FindByVal_Array(const Person& p) {
    57. int pos = -1;
    58. for (int i = 0; i < this->m_Size; i++) {
    59. if (this->m_Parr[i] == p) {
    60. pos = i;
    61. break;
    62. }
    63. }
    64. return pos;
    65. }
    66. // 打印
    67. void DynamicArray::Print_Array() {
    68. for (int i = 0; i < this->m_Size; i++) {
    69. std::cout << this->m_Parr[i].Get_Name() << " "
    70. << this->m_Parr[i].Get_Sex() << " "
    71. << this->m_Parr[i].Get_Age()
    72. << std::endl;
    73. }
    74. std::cout << std::endl;
    75. }
    76. // 清空
    77. void DynamicArray::Clear_Array() {
    78. this->m_Size = 0;
    79. delete[] this->m_Parr;
    80. this->m_Parr = NULL;
    81. }
    82. // 获取长度
    83. int DynamicArray::Get_Size_Array() {
    84. return this->m_Size;
    85. }
    86. // 获取容量
    87. int DynamicArray::Get_Capactiy_Array() {
    88. return this->m_Capactiy;
    89. }
    90. // 析构
    91. DynamicArray::~DynamicArray() {
    92. if (this->m_Parr != NULL) {
    93. delete[] this->m_Parr;
    94. this->m_Parr = NULL;
    95. }
    96. }
    97. // 重载 =
    98. DynamicArray& DynamicArray::operator=(const DynamicArray& da) {
    99. // 容量复制
    100. this->m_Capactiy = da.m_Capactiy;
    101. // 长度复制
    102. this->m_Size = da.m_Size;
    103. // 内容复制
    104. for (int i = 0; i < this->m_Size; i++) {
    105. this->m_Parr[i].Set_Name(da.m_Parr[i].Get_Name());
    106. this->m_Parr[i].Set_Sex(da.m_Parr[i].Get_Sex());
    107. this->m_Parr[i].Set_Age(da.m_Parr[i].Get_Age());
    108. }
    109. return *this;
    110. }
    • Person类实现
    1. Person::Person(std::string name, std::string sex, int age){
    2. this->m_Name = name;
    3. //if (sex != "男" || sex != "女") {
    4. // throw sex;
    5. //}
    6. this->m_Sex = sex;
    7. this->m_Age = age;
    8. }
    9. Person::Person(){}
    10. void Person::Set_Name(std::string name){
    11. this->m_Name = name;
    12. }
    13. void Person::Set_Sex(std::string sex){
    14. this->m_Sex = sex;
    15. }
    16. void Person::Set_Age(int age){
    17. this->m_Age = age;
    18. }
    19. std::string Person::Get_Name(){
    20. return this->m_Name;
    21. }
    22. std::string Person::Get_Sex(){
    23. return this->m_Sex;
    24. }
    25. int Person::Get_Age(){
    26. return this->m_Age;
    27. }
    28. Person& Person::operator=(const Person& p){
    29. this->m_Age = p.m_Age;
    30. this->m_Name = p.m_Name;
    31. this->m_Sex = p.m_Sex;
    32. return *this;
    33. }
    34. bool Person::operator==(const Person& p) {
    35. if (this->m_Name == p.m_Name && this->Get_Age() == p.m_Age && this->Get_Sex() == p.m_Sex) {
    36. return true;
    37. }
    38. else false;
    39. }
    40. std::ostream& operator<<(std::ostream& cout, const Person& p) {
    41. std::cout << p.m_Name << " " << p.m_Sex << " " << p.m_Age << std::endl;
    42. return std::cout;
    43. }

    在写 cpp 线性表的时候出现很奇怪的bug,平时一般都是头文件(.h)写声明,源文件(.cpp)写实现,两个文件名写成相同的,但是总是出现 LNK2019 的错误链接器工具错误 LNK2019 | Microsoft Docs

    文档看了半天也没看出来哪里有问题,最后把写实现的(.cpp)文件改了名字(不和 .h 头文件一样)结果就好了

    期间试了很多方法,说把头文件后缀改为 (.hpp、.H 、....)都尝试过,但都不行

  • 相关阅读:
    SpringBoot学习小结之Swagger
    基于Python Web的学生成绩管理系统--文档
    论文中的小细节——为什么论文中总是写WX而不是XW?
    MySQL使用简单教程
    信息系统基础选择题真题
    企业级DevOps平台搭建及技术选型-项目管理篇
    17_方法
    Android 开发错误集合
    Python 使用Scapy构造特殊数据包
    计算机网络(四)
  • 原文地址:https://blog.csdn.net/xuan3215/article/details/126296359