顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
-
静态顺序表:使用定长数组存储。
-
动态顺序表:使用动态开辟的数组存储。
// 顺序表的静态存储#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;
这里来看一下动态存储
Seq.h
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define SLDataType int
typedef struct SeqList
{
SLDataType *arry; //动态数组
size_t _size; //数组里当前存储的数量
size_t _capicity; //数组的容量
}SeqList;
void SeqListInit(SeqList *psl, size_t capicity);//初始化顺序表
void SeqListDestory(SeqList *psl);//清空顺序表
void CheckCapicity(SeqList *psl);//检查顺序表
void SeqListPushbBack(SeqList *psl, SLDataType x);//尾插
void SeqListPopBack(SeqList *psl);//尾删
void SeqListPushFront(SeqList *psl, SLDataType x);//头插
void SeqListPopFront(SeqList *psl);//头删
void SeqListPrint(SeqList *psl);//打印顺序表
int SeqListFind(SeqList *psl,SLDataType x);//查找顺序表中元素
void SeqListInsert(SeqList *psl, SLDataType x, size_t pos);//任意位置插入元素
void SeqListErase(SeqList *psl, size_t pos);//删除一个位置的元素
void SeqListRemove(SeqList *psl, SLDataType x);//删除所有x元素
void SeqListModify(SeqList *psl, size_t pos, SLDataType x);//修改某个位置的元素
Seq.c
#include"Seq.h"
void SeqListInit(SeqList *psl, size_t capicity)
{
assert(psl);
psl->_size = 0;
psl->_capicity = capicity;
psl->arry =(SeqList*)malloc((psl->_capicity)*sizeof(SLDataType));//动态开辟元素个数为capicity的数组
}
void SeqListDestory(SeqList *psl)
{
assert(psl);
psl->_size = 0;
psl->_capicity = 0;//该函数也可以用malloc将数组重新分配为0
}
void CheckCapicity(SeqList *psl)
{
assert(psl);
if (psl->_size == psl->_capicity && psl->_capicity > 0)//如果存满了
{
psl->_capicity *= 2;
psl->arry = (SeqList*)realloc(psl->arry,sizeof(SLDataType)*(psl->_capicity));//2倍扩展
}
if (psl->_capicity == 0)//如果容量为0
{
psl->_capicity = 5;
psl->arry = (SeqList*)malloc(sizeof(SLDataType)*5);
}
}
void SeqListPushbBack(SeqList *psl, SLDataType x)
{
assert(psl);
CheckCapicity(psl);//插入时注意要检查容量是否满了
psl->arry[psl->_size] = x;
psl->_size++;
}
void SeqListPopBack(SeqList *psl)
{
assert(psl);
CheckCapicity(psl);//删除时要注意是否容量为0
psl->_size--;
}
void SeqListPushFront(SeqList *psl,SLDataType x)
{
assert(psl);
CheckCapicity(psl);
size_t flag = psl->_size;//设置一个从后面开始的标记
while (flag > 0)//先把所有元素从后面开始往后挪动一位
{
psl->arry[flag] = psl->arry[flag - 1];
flag--;
}
psl->arry[0] = x;//挪动完把插入的元素放在首位,即插入成功
psl->_size++;
}
void SeqListPopFront(SeqList *psl)
{
assert(psl);
CheckCapicity(psl);
size_t start = 0;//头删只需要把第一个后面的所有元素一个个往前面挪动即可
while (start < psl->_size-1)
{
psl->arry[start] = psl->arry[start + 1];
start++;
}
psl->_size--;
}
void SeqListPrint(SeqList *psl)
{
assert(psl);
int i = 0;
for (i = 0; i < psl->_size; i++)//注意打印的是实际存储的元素,不是capicity
{
printf("%d,", psl->arry[i]);
}
}
int SeqListFind(SeqList *psl, SLDataType x)
{
assert(psl);
int i = 0;
for (; i < psl->_size; i++)
{
if (psl->arry[i] == x)
{
return i;//只是查找了第一个是x的元素的下标
}
}
return -1;
}
void SeqListInsert(SeqList *psl, SLDataType x, size_t pos)
{
assert(psl);
CheckCapicity(psl);//检查是否满了
size_t start = psl->_size;
while (start > pos-1) //将pos和pos后面的元素,从最后面开始向后挪动
{
psl->arry[start] = psl->arry[start - 1];
start--;
}
psl->arry[pos - 1] = x;
psl->_size++;
}
void SeqListErase(SeqList *psl, size_t pos)
{
assert(psl);
CheckCapicity(psl);
size_t start = pos;
while (start < psl->_size)//将pos之后的元素从pos开始不断的向前挪动
{
psl->arry[start-1] = psl->arry[start];
start++;
}
psl->_size--;
}
void SeqListRemove(SeqList *psl, SLDataType x)
{ //把所有是x的元素删除
assert(psl);
CheckCapicity(psl);
size_t left = 0;
size_t right = 0;
while (right<psl->_size)//类似双指针,right向后走,把不等于x的给left,最后结果就是没有x的结果
{
if (x != psl->arry[right])
{
psl->arry[left] = psl->arry[right];
left++;
}
right++;
}
psl->_size = left;
}
void SeqListModify(SeqList *psl, size_t pos, SLDataType x)
{
assert(psl);
if (pos >= psl->_size)//如果输入的位置超出的实际存储的数量,则不操作
{
return;
}
psl->arry[pos - 1] = x;
}
test.c
#include"Seq.h"
int main()
{
SeqList psl;
SeqListInit(&psl,5);
SeqListPushFront(&psl, 1);
SeqListPushFront(&psl, 1);
SeqListPushFront(&psl, 2);
SeqListPushFront(&psl, 1);
SeqListPushFront(&psl, 3);
SeqListPushFront(&psl, 5);
SeqListPushFront(&psl, 1);
SeqListPushFront(&psl, 1);
SeqListPrint(&psl);
printf("\n");
SeqListRemove(&psl, 1);
SeqListPrint(&psl);
printf("\n");
SeqListModify(&psl, 4, 4);
SeqListPrint(&psl);
system("pause");
return 0;
}