数据结构--顺序表&链表
1.线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以顺序结构和链式结构的形式存储。
特征:
- 对于同一个线性表,其每一个数据元素的值虽然不同,但必须具有相同的数据类型;
- 数据元素之间具有一种线性的或“一对一”的逻辑关系。
①第一个数据元素没有前驱,这个数据元素被称为开始节点;
②最后一个数据元素没有后继,这个数据元素被称为终端节点;
③除了第一个和最后一个数据元素外,其他数据元素有且仅有一个前驱和一个后继。
2.顺序表
2.1概念及基本结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。可以理解他就是顺序存储的线性表。
顺序表一般可以分为:
- 静态顺序表:使用定长数组存储。
- 动态顺序表:使用动态开辟的数组存储。
// 顺序表的静态存储
#define N 100
typedef int SLDataType;
typedef struct SeqList
{
SLDataType array[N]; // 定长数组
size_t size; // 有效数据的个数
}SeqList;
// 顺序表的动态存储
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size ; // 有效数据个数
size_t capicity ; // 容量空间的大小 不够则增容
}SeqList;
2.2 顺序表的代码实现
静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以我们实现动态顺序表。
//顺序表的动态存储
#include<iostream>
#include<assert.h>
using namespace std;
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* array; // 指向动态开辟的数组
size_t size; // 有效数据个数
size_t capicity; // 容量空间的大小
}SeqList;
// 基本增删查改接口
//初始化
void SeqListInit(SeqList* psl, size_t capacity) {
psl->array = (SLDataType*)calloc(capacity, sizeof(SeqList));
psl->size = 0;
psl->capicity = capacity;
}
//销毁
void SeqListDestory(SeqList* psl) {
assert(psl);
if (psl->array) {
free(psl->array);
psl->size = 0;
psl->capicity = 0;
}
}
//检查容量
void CheckCapacity(SeqList* psl) {
assert(psl);
if (psl->size == psl->capicity) {
psl->capicity *= 2;
psl->array = (SLDataType*)realloc(psl->array, psl->capicity * sizeof(SLDataType));
}
}
//尾插
void SeqListPushBack(SeqList* psl, SLDataType x) {
CheckCapacity(psl);
psl->array[psl->size++] = x;
//psl->array[psl->size]=x;
//++size;
}
//尾删
void SeqListPopBack(SeqList* psl) {
assert(psl || psl->size);
--psl->size;
}
//头插
void SeqListPushFront(SeqList* psl, SLDataType x) {
assert(psl);
CheckCapacity(psl);
for (int i = psl->size; i>0; --i) {
psl->array[i] = psl->array[i-1];
}
++psl->size;
psl->array[0] = x;
}
//头删
void SeqListPopFront(SeqList* psl) {
assert(psl || psl->size);
for (int i = 1; i < psl->size; ++i) {
psl->array[i - 1] = psl->array[i];
}
--psl->size;
}
//查找
int SeqListFind(SeqList* psl, SLDataType x) {
assert(psl);
for (int i = 0; i < psl->size; ++i) {
if (psl->array[i] == x)
return i;
}
return -1;
}
//插入 在第pos个位置上插入元素
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) {
assert(psl || pos <= psl->size);
CheckCapacity(psl);
for (int i = psl->size; i >= pos; --i) {
psl->array[i] = psl->array[i-1];
}
psl->array[pos] = x;
++psl->size;
}
//删除 删除第pos个位置上的元素
void SeqListErase(SeqList* psl, size_t pos) {
assert(psl || pos <= psl->size);
for (int i = pos-1; i < psl->size-1; ++i) {
psl->array[i] = psl->array[i + 1];
}
--psl->size;
}
//删除所有值为x的元素
void SeqListRemove(SeqList* psl, SLDataType x) {
assert(psl);
int i;
while ((i = SeqListFind(psl,</