线性表是 0 个或者多个数据元素的有序序列。
-
特性:
- 数据元素之间是有序的
- 数据元素个数是有限的
- 数据元素类型是相同的
为线性表的第一个元素,只有一个后继。
为线性表的最后一个元素,只有一个前驱。
- 除
和
外的其他元素
,既有前驱,又有后继。
- 线性表能够逐项访问和顺序存放。
线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储数据元素

C 语 言 实 现 单 链 表
- typedef struct {
- int* pArr; // 存放数据地址
- int size; // 长度,当前元素个数
- int capacity; // 容量,当前最大能容纳元素
- }Dynamic_Array;
- // 初始化
- Dynamic_Array* Init_Array();
-
-
- // 插入
- void Push_back_Array(Dynamic_Array* arr,int val);
-
-
- // 根据 位置 删除
- void RemoveByPos_Array(Dynamic_Array* arr, int pos);
-
-
- // 根据 数据 删除
- void RemoveByValue_Array(Dynamic_Array* arr, int val);
-
-
- // 查找
- int Find_Array(Dynamic_Array* arr, int val);
-
-
- // 打印
- void Print_Array(Dynamic_Array* arr);
-
-
- // 释放动态数组内存
- void FreeSpace_Array(Dynamic_Array* arr, int pos);
-
-
- // 清空数组
- void Clear_Array(Dynamic_Array* arr);
-
-
- // 获取容量
- int Capactiy_Array(Dynamic_Array* arr);
-
-
- // 获取长度
- int Size_Array(Dynamic_Array* arr);
-
-
- // 根据 位置 获取元素
- int At_Array(Dynamic_Array* arr, int pos);
- // 初始化
- Dynamic_Array* Init_Array() {
-
- // 申请空间
- Dynamic_Array* myArray = (Dynamic_Array*)malloc(sizeof(Dynamic_Array));
- // 初始化
- myArray->size = 0;
- myArray->capacity = 20;
- myArray->pArr = (int*)malloc(sizeof(int) * myArray->capacity);
-
- return myArray;
- }
-
- // 插入
- void Push_back_Array(Dynamic_Array* arr, int val) {
-
- if (arr == NULL) return;
-
- // 判断容量是否足够
- if (arr->size >= arr->capacity) {
-
- // 申请更大空间 默认两倍
- int* NewSpace = (int*)malloc(sizeof(int) * arr->capacity * 2);
-
- // 拷贝数据到新空间
- if (NewSpace != NULL) {
- memcpy(NewSpace, arr->pArr, arr->capacity * sizeof(int));
- }
-
- // 释放旧空间内存
- free(arr->pArr);
-
- // 更新容量
- arr->capacity = arr->capacity * 2;
-
- // 更新指针指向
- arr->pArr = NewSpace;
- }
- // 尾插 插入 新元素
- arr->pArr[arr->size] = val;
-
- // 更新长度
- arr->size++;
- }
-
- // 根据位置删除
- void RemoveByPos_Array(Dynamic_Array* arr, int pos) {
-
- if (arr == NULL) return;
-
- // 判断 位置 是否有效
- if (pos < 0 || pos >= (arr->size)) return;
-
- // 删除
- for (int i = pos; i < arr->size - 1; i++) {
- arr->pArr[i] = arr->pArr[i + 1];
- }
-
- // 更新长度
- arr->size--;
- }
-
- // 根据值删除
- void RemoveByValue_Array(Dynamic_Array* arr, int val) {
-
- if (arr == NULL) return;
-
- int pos = Find_Array(arr, val);
-
- // 调用 按位置 删除
- RemoveByPos_Array(arr, pos);
- }
-
- // 查找
- int Find_Array(Dynamic_Array* arr, int val) {
-
- int pos = -1;
-
- if (arr == NULL) return pos;
-
- for (int i = 0; i < arr->size; i++) {
- if (arr->pArr[i] == val) {
- pos = i;
- break;
- }
- }
- return pos;
- }
-
- // 打印
- void Print_Array(Dynamic_Array* arr) {
-
- if (arr == NULL) return;
-
- for (int i = 0; i < arr->size; i++)
- printf("%d ", arr->pArr[i]);
-
- printf("\n");
- }
-
- // 释放动态数组内存
- void FreeSpace_Array(Dynamic_Array* arr) {
-
- if (arr == NULL) return;
-
- if (arr->pArr != NULL) free(arr->pArr);
-
- free(arr);
- }
-
- // 清空数组
- void Clear_Array(Dynamic_Array* arr) {
-
- if (arr == NULL) return;
-
- arr->size = 0;
- }
-
- // 获取容量
- int Capactiy_Array(Dynamic_Array* arr) {
-
- if (arr == NULL) return 0;
-
- return arr->capacity;
- }
-
- // 获取长度
- int Size_Array(Dynamic_Array* arr) {
-
- if (arr == NULL) return 0;
-
- return arr->size;
- }
-
- // 根据位置获取元素
- int At_Array(Dynamic_Array* arr, int pos) {
-
- if (arr == NULL) return -1;
-
- return arr->pArr[pos];
- }
CPP 实 现 单 链 表
- class DynamicArray {
- public:
- // 构造
- DynamicArray();
-
- // 插入
- void Pushback_Array(const Person& p);
-
- // 根据 下标 删除
- void RemoveByPos_Array(const int& pos);
-
- // 根据 数据 删除
- void RemoveByVal_Array(const Person& p);
-
- // 根据 下标 修改
- void ModifyByPos_Array(const int& pos);
-
- // 根据 数据 修改
- void ModifyByVal_Array(const Person& p);
-
- // 根据 下标 查找
- Person& FindByPos_Array(const int& pos);
-
- // 根据 数据 查找
- int FindByVal_Array(const Person& p);
-
- // 打印
- void Print_Array();
-
- // 清空
- void Clear_Array();
-
- // 获取长度
- int Get_Size_Array();
-
- // 获取容量
- int Get_Capactiy_Array();
-
- // 析构
- ~DynamicArray();
-
- DynamicArray& operator=(const DynamicArray& da);
-
- public:
- Person* m_Parr;
- int m_Size;
- int m_Capactiy;
- };
- class Person {
-
- friend std::ostream& operator<<(std::ostream& cout, const Person& p);
-
- public:
- Person(std::string name, std::string sex, int age);
- Person();
-
- void Set_Name(std::string name);
- void Set_Sex(std::string sex);
- void Set_Age(int age);
-
- std::string Get_Name();
- std::string Get_Sex();
- int Get_Age();
- Person& operator=(const Person& p);
- bool operator==(const Person& p);
- private:
- std::string m_Name;
- std::string m_Sex;
- int m_Age;
- };
-
- std::ostream& operator<<(std::ostream& cout, const Person& p);
- // 构造
- DynamicArray::DynamicArray() {
- this->m_Capactiy = 20;
- this->m_Parr = new Person[this->m_Capactiy];
- this->m_Size = 0;
- }
-
- // 尾插
- void DynamicArray::Pushback_Array(const Person& p) {
- // 空间不足
- if (this->m_Size >= this->m_Capactiy) {
- // 创建一个新空间
- Person* NewSpace = new Person[this->m_Capactiy * 2];
-
- // 旧数据放到新空间
- for (int i = 0; i < this->m_Capactiy; i++) {
- NewSpace[i].Set_Name(this->m_Parr[i].Get_Name());
- NewSpace[i].Set_Sex(this->m_Parr[i].Get_Sex());
- NewSpace[i].Set_Age(this->m_Parr[i].Get_Age());
- //NewSpace[i] = this->m_Parr[i];
- }
-
- // 释放原有空间
- delete[] this->m_Parr;
-
- // 更改指针指向
- this->m_Parr = NewSpace;
-
- // 更新容量
- this->m_Capactiy = this->m_Capactiy * 2;
- }
-
- // 插入元素
- this->m_Parr[this->m_Size] = p;
-
- // 更新长度
- this->m_Size++;
- }
-
- // 根据 下标 删除
- void DynamicArray::RemoveByPos_Array(const int& pos) {
-
- if (pos < 0 || pos >= this->m_Size) {
- return;
- }
-
- // pos 位置之后开始往前移动
- for (int i = pos; i < this->m_Size - 1; i++) {
- this->m_Parr[i] = this->m_Parr[i + 1];
- }
-
- // 更新长度
- this->m_Size--;
- }
-
- // 根据 数据 删除
- void DynamicArray::RemoveByVal_Array(const Person& p) {
-
- // 通过值查找
- int pos = FindByVal_Array(p);
-
- // 通过下标删除
- RemoveByPos_Array(pos);
- }
-
- // 根据 下标 查找
- Person& DynamicArray::FindByPos_Array(const int& pos) {
- return this->m_Parr[pos];
- }
-
- // 根据 数据 查找
- int DynamicArray::FindByVal_Array(const Person& p) {
-
- int pos = -1;
- for (int i = 0; i < this->m_Size; i++) {
- if (this->m_Parr[i] == p) {
- pos = i;
- break;
- }
- }
- return pos;
- }
-
- // 打印
- void DynamicArray::Print_Array() {
- for (int i = 0; i < this->m_Size; i++) {
- std::cout << this->m_Parr[i].Get_Name() << " "
- << this->m_Parr[i].Get_Sex() << " "
- << this->m_Parr[i].Get_Age()
- << std::endl;
- }
- std::cout << std::endl;
-
- }
-
- // 清空
- void DynamicArray::Clear_Array() {
-
- this->m_Size = 0;
-
- delete[] this->m_Parr;
-
- this->m_Parr = NULL;
- }
-
- // 获取长度
- int DynamicArray::Get_Size_Array() {
- return this->m_Size;
- }
-
- // 获取容量
- int DynamicArray::Get_Capactiy_Array() {
- return this->m_Capactiy;
- }
-
- // 析构
- DynamicArray::~DynamicArray() {
- if (this->m_Parr != NULL) {
- delete[] this->m_Parr;
- this->m_Parr = NULL;
- }
-
- }
-
- // 重载 =
- DynamicArray& DynamicArray::operator=(const DynamicArray& da) {
- // 容量复制
- this->m_Capactiy = da.m_Capactiy;
-
- // 长度复制
- this->m_Size = da.m_Size;
-
- // 内容复制
- for (int i = 0; i < this->m_Size; i++) {
- this->m_Parr[i].Set_Name(da.m_Parr[i].Get_Name());
- this->m_Parr[i].Set_Sex(da.m_Parr[i].Get_Sex());
- this->m_Parr[i].Set_Age(da.m_Parr[i].Get_Age());
- }
-
- return *this;
- }
- Person::Person(std::string name, std::string sex, int age){
- this->m_Name = name;
- //if (sex != "男" || sex != "女") {
- // throw sex;
- //}
- this->m_Sex = sex;
- this->m_Age = age;
- }
-
- Person::Person(){}
-
- void Person::Set_Name(std::string name){
- this->m_Name = name;
- }
-
- void Person::Set_Sex(std::string sex){
- this->m_Sex = sex;
- }
-
- void Person::Set_Age(int age){
- this->m_Age = age;
- }
-
- std::string Person::Get_Name(){
- return this->m_Name;
- }
-
- std::string Person::Get_Sex(){
- return this->m_Sex;
- }
-
- int Person::Get_Age(){
- return this->m_Age;
- }
-
- Person& Person::operator=(const Person& p){
- this->m_Age = p.m_Age;
- this->m_Name = p.m_Name;
- this->m_Sex = p.m_Sex;
- return *this;
- }
-
- bool Person::operator==(const Person& p) {
- if (this->m_Name == p.m_Name && this->Get_Age() == p.m_Age && this->Get_Sex() == p.m_Sex) {
- return true;
- }
- else false;
- }
-
- std::ostream& operator<<(std::ostream& cout, const Person& p) {
- std::cout << p.m_Name << " " << p.m_Sex << " " << p.m_Age << std::endl;
- return std::cout;
- }
在写 cpp 线性表的时候出现很奇怪的bug,平时一般都是头文件(.h)写声明,源文件(.cpp)写实现,两个文件名写成相同的,但是总是出现 LNK2019 的错误链接器工具错误 LNK2019 | Microsoft Docs

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

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