一、小概述
二、代码解析
下面利用顺序表实现增删改查的功能:
//动态顺序表
#include <iostream>
using namespace std;
typedef int SLDataType;//适用于多种类型
typedef struct SeqList
{
SLDataType* a;//数组
int size;//表示数组中存储了多少个元素
int capacity;//表示数组实际能够储存的空间容量是多少
}SL;//SL为SeqList的别名
1)初始化顺序表
void SeqlistInit(SL* ps)//初始化,将数组置为空
{
ps->a = NULL;
ps->size = ps->capacity = 0;
}
2)尾插法
//尾差法
void SeqListPushBack(SL* ps,SLDataType x)
{
//要先检查数组的容量与现所储存元素个数的匹配度
//当capacity=size时
if (ps->capacity == ps->size)
{
//利用三目运算符,判断数组原来的容量是否为空
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
//利用realloc函数进行扩容,形成新的数组
//realloc(数组的地址,扩容空间的字节数)
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
//验证是否扩容成功
if (tmp == NULL)
{
cout << "realloc fail!" << endl;//扩容失败,异常退出
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
//进行尾插操作
ps->a[ps->size] = x;
ps->size++;
}
每写一步就要测试一步的代码!如:一下为初始化和尾差法的测试
编写打印函数来验证结果:
void SeqListPrint(SL* ps)
{
for (int i = 0; i < ps->size; i++)
{
cout << ps->a[i]<<" ";
}
cout << endl;
}
void TestSeqList1()//测试函数,每写一个接口函数,就要进行一次测试
{
SL sl;//定义一个结构体
SeqListInit(&sl);//初始化操作
cout << "尾插法测试:" << endl;
SeqListPushBack(&sl, 1);//尾插法测试,capacity=4
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);
SeqListPushBack(&sl, 5);//capacity=8,size=5
SeqListPrint(&sl);//1 2 3 4 5
cout << "---------------" << endl;
}
3)顺序表的销毁
//顺序表销毁
void SeqListDestory(SL* ps)
{
//把空间还给系统,防止内存泄露
free(ps->a);//free释放的是动态分配的内存空间,而不是清空内存中的数据
//free后要自己清空a中的数据,如果没有清空就会造成内存泄露
ps->a = NULL;
ps->capacity = ps->size = 0;//滞空
}
4)尾删法
//尾删法(删除掉数组中的最后一个元素,直接size-1)
void SeqListPopBack(SL* ps)
{
//法1:使用if循环语句,判断size是否大于0
//法2:使用断言(简单粗暴)
assert(ps->size > 0);//当size<=0时,直接终止程序,不再运行,提高效率
ps->size--;
}
5)头插法
要先检查数组的容量
//检查数组的容量(要放在头插法的前面,否则编译器会找不到相对应的标识符)
void SeqListCheckCapacity(SL* ps)
{
//重复尾插法的操作
//空间已满/空间为0,进行扩容操作
if (ps->capacity == ps->size)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
if (tmp == NULL)
{
cout << "realloc fail!" << endl;
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
}
// 头插法
void SeqListPushFront(SL* ps, SLDataType x)
{
//在挪动数据进行插入前,要先检查数组的容量!
SeqListCheckCapacity(ps);//数组空间不够时,进行扩容操作
//将数组中的元素依次向后挪动
int end = ps->size - 1;//end表示数组中的最后一个元素
while (end >= 0)
{
ps->a[end+1] = ps->a[end];
end--;
}
//放入新插入的数据
ps->a[0] = x;
ps->size++;
}
6)头删法
// 头删法
void SeqListPopFront(SL* ps)
{
//当数组中的元素个数>0时,将数组中的元素依次往前挪动
assert(ps->size > 0);
int begin = 1;//数组中的第二个元素,即要被删除元素的下一个元素
while (begin<ps->size)
{
ps->a[begin-1] = ps->a[begin];
begin++;
}
ps->size--;
}
7)查找
//查找
int SeqListFind(SL* ps, SLDataType x)
{
for (int i = 0; i < ps->size; i++)
{
if (ps->a[i] == x)
{
return i;
}
}
return -1;
}
8)在指定位置插入数据
// 在指定位置插入数据
void SeqListInsert(SL* ps,int pos,SLDataType x)
{
//在插入数据前要先检查数组是否需要扩容!
//断言
assert(pos >= 0 && pos <= ps->size);
SeqListCheckCapacity(ps);//检查数组的容量
//插入新的数据
int end = ps->size - 1;
while (pos<=end)
{
ps->a[end+1] = ps->a[end];
end--;
}
ps->a[pos] = x;
ps->size++;
}
9)删除指定位置的数据
// 在指定位置删除数据
void SeqListErase(SL* ps,int pos)
{
assert(pos >= 0 && pos <= ps->size);
int begin = pos+1;
//挪动数据
while (begin<=ps->size)
{
ps->a[begin-1] = ps->a[begin];
begin++;
}
ps->size--;
}
测试函数汇总
void TestSeqList1()//测试函数,每写一个接口函数,就要进行一次测试
{
SL sl;//定义一个结构体
SeqListInit(&sl);//初始化操作
cout << "尾插法测试:" << endl;
SeqListPushBack(&sl, 1);//尾插法测试,capacity=4
SeqListPushBack(&sl, 2);
SeqListPushBack(&sl, 3);
SeqListPushBack(&sl, 4);
SeqListPushBack(&sl, 5);//capacity=8,size=5
SeqListPrint(&sl);
cout << "---------------" << endl;
cout << "头插法测试:" << endl;
SeqListPushFront(&sl,1);//头插法测试
SeqListPushFront(&sl,2);
SeqListPushFront(&sl,3);
SeqListPushFront(&sl,4);
SeqListPushFront(&sl,5);
SeqListPrint(&sl);
cout << "---------------" << endl;
cout << "头删法测试:" << endl;
SeqListPopFront(&sl);//头删法测试
SeqListPopFront(&sl);
SeqListPopFront(&sl);
SeqListPopFront(&sl);
SeqListPopFront(&sl);
SeqListPrint(&sl);
cout << "---------------" << endl;
cout << "查找元素测试:" << endl;
cout <<SeqListFind(&sl, 3) << endl;
cout << "---------------" << endl;
cout << "在指定位置插入数据测试:" << endl;
SeqListInsert(&sl, 3, 9);//1 2 3 9 4 5
//若不知道数据的位置,可以与查找函数配合使用
//int pos = SeqListFind(&sl, 4);
//if (pos != -1)
//{
// SeqListInsert(&sl, pos, 89);
//}
SeqListPrint(&sl);
cout << "---------------" << endl;
cout << "在指定位置删除数据测试:" << endl;
SeqListErase(&sl,4);
SeqListPrint(&sl);
cout << "---------------" << endl;
cout << "在销毁数组测试:" << endl;
SeqListDestory(&sl);//销毁数组,即将数组变为初始化的状态
SeqListPrint(&sl);
}
int main()
{
TestSeqList1();
return 0;
}
运行结果: