代码如下:
SeqList.h
#pragma once
//实现动态顺序表
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int SLDataType;
typedef struct SeqListNode
{
SLDataType* arr;//用来储存数据的数组,长度不定
int size;//储存有效数据的个数
int capacity;//空间可以储存有效数据的个数
}SL;
//顺序表的初始化
void SLInit(SL* sl);
//顺序表的打印
void SLPrint(SL* sl);
//空间处理 检查空间是否有剩余,无剩余则开辟新空间
void SLSpaceHandle(SL* sl);
//尾插
void SLInsertBack(SL* sl, SLDataType x);
//尾删
void SLPopBack(SL* sl);
//头插
void SLInsertFront(SL* sl, SLDataType x);
//头删
void SLPopFront(SL* sl);
//查找
int SLFind(SL* sl, SLDataType x);
//在下标为pos前插入数据
void SLInsert(SL* sl, int pos, SLDataType x);
//删除下标为pos的数据
void SLErase(SL* sl, int pos);
//顺序表的销毁
void SLDestory(SL* sl);
SeqList.c
#define _CRT_SECURE_NO_WARNINGS 1\
#include "SeqList.h"
//顺序表初始化
void SLInit(SL* sl)
{
assert(sl);
sl->arr = NULL;
sl->size = 0;
sl->capacity = 0;
}
//空间处理
void SLSpaceHandle(SL* sl)
{
assert(sl);
if (sl->size == sl->capacity)//相等则代表没有剩余空间
{
//开辟空间
//要先讨论一下capacity的值是否为0
int newcapacity = sl->capacity == 0 ? 4 : 2 * sl->capacity;//如果空间为0则认为给4,如果空间不为0则倍增
SLDataType* tmp = (SLDataType*)realloc(sl->arr, sizeof(SLDataType) * newcapacity);
if (tmp == NULL)//realloc失败的情况
{
perror("realloc fail!");
exit(1);
}
//如果realloc成功
sl->capacity = newcapacity;
sl->arr = tmp;
}
}
//尾插
void SLInsertBack(SL* sl, SLDataType x)
{
assert(sl);
//插入前要先检查是否有剩余空间,没有空间则扩容
SLSpaceHandle(sl);
//尾插
sl->arr[sl->size++] = x;
}
//打印
void SLPrint(SL* sl)
{
assert(sl);
assert(sl->size > 0);
int i = 0;
for (i = 0; i < sl->size; i++)
{
printf("%d ", sl->arr[i]);
}
printf("\n");
}
//头插
void SLInsertFront(SL* sl, SLDataType x)
{
assert(sl);
SLSpaceHandle(sl);
int i = 0;
for (i = sl->size - 1;i >= 0; i--)
{
sl->arr[i + 1] = sl->arr[i];
}
sl->arr[0] = x;
sl->size++;
}
//尾删
void SLPopBack(SL* sl)
{
assert(sl);
assert(sl->size > 0);
sl->size--;
}
//头删
void SLPopFront(SL* sl)
{
assert(sl);
assert(sl->size > 0);
int i = 0;
for (i = 0; i < sl->size - 1; i++)
{
sl->arr[i] = sl->arr[i + 1];
}
sl->size--;
}
//查找
int SLFind(SL* sl, SLDataType x)
{
assert(sl);
assert(sl->size > 0);
int i = 0;
for (i = 0; i < sl->size; i++)
{
//找到了
if (x == sl->arr[i])
return i;
}
//没找到
return -1;
}
//在下标为pos前插入数据
void SLInsert(SL* sl, int pos, SLDataType x)
{
assert(sl);
assert(sl->size > pos);
SLSpaceHandle(sl);
int i = 0;
for (i = sl->size - 1; i >= pos ; i--)
{
sl->arr[i + 1] = sl->arr[i];
}
sl->arr[pos] = x;
sl->size++;
}
//删除下标为pos的数据
void SLErase(SL* sl, int pos)
{
assert(sl);
assert(sl->size > pos);
int i = 0;
for (i = pos; i < sl->size - 1; i++)
{
sl->arr[i] = sl->arr[i + 1];
}
sl->size--;
}
//顺序表的销毁
void SLDestory(SL* sl)
{
assert(sl);
if (sl->arr)
{
free(sl->arr);
}
sl->arr = NULL;
sl->size = 0;
sl->capacity = 0;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"
void SLtest()
{
SL sl;
SLInit(&sl);
//测试尾插
SLInsertBack(&sl, 1);
SLPrint(&sl);
SLInsertBack(&sl, 2);
SLPrint(&sl);
SLInsertBack(&sl, 3);
SLPrint(&sl);
SLInsertBack(&sl, 4);
SLPrint(&sl);
//测试头插
//SLInsertFront(&sl, 1);
//SLPrint(&sl);
//SLInsertFront(&sl, 2);
//SLPrint(&sl);
//SLInsertFront(&sl, 3);
//SLPrint(&sl);
//SLInsertFront(&sl, 4);
//SLPrint(&sl);
//测试尾删
//SLPopBack(&sl);
//SLPrint(&sl);
//SLPopBack(&sl);
//SLPrint(&sl);
//SLPopBack(&sl);
//SLPrint(&sl);
//SLPopBack(&sl);
//SLPrint(&sl);//删完再打印会报错
//测试头删
//SLPopFront(&sl);
//SLPrint(&sl);
//SLPopFront(&sl);
//SLPrint(&sl);
//SLPopFront(&sl);
//SLPrint(&sl);
//SLPopFront(&sl);
//SLPrint(&sl);//删完再打印会报错
//测试查找
//if (SLFind(&sl, 1) >= 0)
//{
// printf("找到了,下标是%d\n", SLFind(&sl, 1));
//}
//else
// printf("没找到\n");
//if (SLFind(&sl, 7) >= 0)
//{
// printf("找到了,下标是%d\n", SLFind(&sl, 7));
//}
//else
// printf("没找到\n");
//测试指定位置前插入
//SLInsert(&sl, 3, 7);
//SLPrint(&sl);
//测试删除指定位置的数据
//SLErase(&sl, 3);
//SLPrint(&sl);
//测试销毁
SLDestory(&sl);
}
int main()
{
SLtest();
return 0;
}
测试运行:
销毁在调试中容易看出来,在控制台不容易看出
销毁前
销毁后
可见顺序表的销毁是正确的
注意与总结
1.对于顺序表的删除与插入操作,必须记得对size++或者--,不然打印的时候一定会出错
2.动态顺序表的插入操作必须要检查是否还有多余空间去插入数据,如果没有则成倍扩容
3.动态顺序表相比于静态顺序表的优势在于程序内部可以根据需要存储的数据多少自己调节所占空间大小,且一般不会出现申请空间失败的情况
如有错误,欢迎指正