顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
目录
首先,我们先定义变量,创建结构体。
顺序表接口的创建
void SeqListInit(SL* ps)
void SeqListDestroy(SL* ps)
void SeqListCheckCapacity(SL* ps)
void SeqListPushBack(SL* ps, SLDataType x)
void SeqListPopBack(SL* ps)
void SeqListPushFront(SL* ps, SLDataType x)
void SeqListPopFront(SL* ps)
int SeqListFind(SL* ps, SLDataType x)
void SeqListInsert(SL* ps, int pos, SLDataType x)
void SeqListErase(SL* ps, int pos)
void SeqListPrint(SL* ps)
void SeqListModify(SL* ps, int pos, SLDataType x)
完整代码
SeaList.h
SeqList.c
测试:test.c
顺序表优缺点
首先,我们先定义变量,创建结构体。 typedef int SLDataType; typedef struct SeqList { SLDataType* a; int size; int capacity; }SL; typedef int SLDataType; //用SLDataType 来代替int,方便后来对操作的数据类型的修改 typedef struct SeqList { SLDataType* a; //定义一个指针,能够指向一块连续的内存空间。 int size; //用来表示当前存储数据的个数 int capacity;//记录当前开辟空间的大小 }SL;
注意: 在这里int size将被初始化成0的方法,代表该空间最后一个存储数据的位置的1下一个位置是size指向的位置。
顺序表接口的创建 //初始化顺序表 void SeqListInit(SL* ps); //每次增容前检查空间的使用情况,并做出相应的调整 void SeqListCheckCapacity(SL* ps); //摧毁开辟的空间 void SeqListDestroy(SL* ps); //尾插 void SeqListPushBack(SL* ps, SLDataType x); //尾删 void SeqListPopBack(SL* ps); //头插 void SeqListPushFront(SL* ps, SLDataType x); //头删 void SeqListPopFront(SL* ps); //查找指定数据的下标 int SeqListFind(SL* ps, SLDataType x); //在pos位置插入一个数据 void SeqListInsert(SL* ps, int pos, SLDataType x); //删除pos位置的数据 void SeqListErase(SL* ps, int pos); //打印顺序表 void SeqListPrint(SL* ps); //修改pos位置的数据 void SeqListModify(SL* ps, int pos, SLDataType x);
参照着以上接口,我们将在下面一一去实现他们的功能
void SeqListInit(SL* ps) void SeqListInit(SL* ps) { assert(ps); ps->a = NULL; ps->size = ps->capacity = 0; } //首先对顺序表进行初始化
void SeqListInit(SL* ps) { assert(ps); //首先,先判断ps是否为有效地址,接下来才可以使用 ps->a = NULL; //将a指向的那块空间首先置为空 ps->size = ps->capacity = 0; //容量和有效数据置为0 }
void SeqListDestroy(SL* ps) void SeqListDestroy(SL* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->size = ps->capacity = 0; } 对顺序表动态开辟的空间进行销毁,防止内存泄漏
void SeqListDestroy(SL* ps) { assert(ps); free(ps->a); //顺序表开辟的是一块连续的空间,对a指向的那块空间进行释放就可以了 ps->a = NULL; ps->size = ps->capacity = 0; }
void SeqListCheckCapacity(SL* ps) void SeqListCheckCapacity(SL* ps) { assert(ps); if (ps->size == ps->capacity)//满了 { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SL)); if (tmp == NULL) { printf("realloc fail\n"); exit(-1); } else { ps->a = tmp; ps->capacity = newcapacity; } } }
对顺序表空间使用情况进行检查并调整
void SeqListCheckCapacity(SL* ps) { assert(ps); if (ps->size == ps->capacity)//满了,此时数据个数和空间容量大小一样,就要增容 {
//newcapacity新空间的容量,如果原空间为0,则newcapacity为4;否则newcapacity 容量为原空间容量的两倍
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
//realloc使用时,如果ps->a=NULL(指针指向的空间)时,这时候它的功能相当于 malloc的功能
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SL));
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
else
{
ps->a = tmp;
ps->capacity = newcapacity; //原空间大小被赋值成新的空间大小
}
}
}
void SeqListPushBack(SL* ps, SLDataType x) void SeqListPushBack(SL* ps, SLDataType x) { assert(ps); SeqListCheckCapacity( ps); ps->a[ps->size] = x; ps->size++; //SeqListInsert(ps, ps->size, x); } 从尾部插入数据
void SeqListPushBack(SL* ps, SLDataType x) { assert(ps); SeqListCheckCapacity( ps); ps->a[ps->size] = x; //在尾部插入数据,ps->size的地方还没有数据 ps->size++; //插入数据后,记录数据个数加1 //SeqListInsert(ps, ps->size, x);//在这里先不解释 }
void SeqListPopBack(SL* ps) void SeqListPopBack(SL* ps) { assert(ps); assert(ps->size > 0); ps->size--; //SeqListErase(ps, ps->size - 1); } 删除尾部数据
void SeqListPopBack(SL* ps) { assert(ps); assert(ps->size > 0); //保证有数据才能删除 ps->size--; //数据个数减1 //SeqListErase(ps, ps->size - 1); }
void SeqListPushFront(SL* ps, SLDataType x) void SeqListPushFront(SL* ps, SLDataType x) { assert(ps); SeqListCheckCapacity(ps); int i = ps->size-1; for ( ; i >=0; i--) { ps->a[i+1] = ps->a[i]; } ps->a[0] = x; ps->size++; //SeqListInsert(ps, 0, x); } 从头部插入数据
void SeqListPushFront(SL* ps, SLDataType x) { assert(ps); SeqListCheckCapacity(ps); //每次增容前都要检查空间使用情况 int i = ps->size-1; //从后往前挪,目的地在后,ps->size-1的地方存储着最后一个数据 for ( ; i >=0; i--) { ps->a[i+1] = ps->a[i]; } ps->a[0] = x;//头插,第一个数据赋值 ps->size++; //记得插入数据后数据个数加1 //SeqListInsert(ps, 0, x); }
void SeqListPopFront(SL* ps) void SeqListPopFront(SL* ps) { assert(ps); assert(ps->size > 0); int i = 0; for (i = 0; i < ps->size - 1; i++) { ps->a[i] = ps->a[i + 1]; } ps->size--; //SeqListErase(ps, 0); } 删除第一个数据
void SeqListPopFront(SL* ps) { assert(ps); assert(ps->size > 0);//保证有数据时才能删 int i = 0; for (i = 0; i < ps->size - 1; i++) //从前往后覆盖,目的地在前 { ps->a[i] = ps->a[i + 1]; } ps->size--; 删除数据后,数据个数减1 //SeqListErase(ps, 0); }
int SeqListFind(SL* ps, SLDataType x) int SeqListFind(SL* ps, SLDataType x) { assert(ps); int i = 0; for (i = 0; i < ps->size; i++) { if (ps->a[i] == x) //找到了,就返回下标 { return i; } } return -1;//没有找到,返回-1 } 查找指定数据
int SeqListFind(SL* ps, SLDataType x) //函数返回类型为int { assert(ps); int i = 0; for (i = 0; i < ps->size; i++) //一一遍历数据 { if (ps->a[i] == x) //找到了,就返回下标 { return i; } } return -1;//没有找到,返回-1 }
void SeqListInsert(SL* ps, int pos, SLDataType x) void SeqListInsert(SL* ps, int pos, SLDataType x) { assert(ps); assert(pos <= ps->size && pos >= 0); SeqListCheckCapacity(ps); int end = ps->size - 1; while (end >= pos) { ps->a[end + 1] = ps->a[end]; end--; } ps->a[pos] = x; ps->size++; } 在pos位置插入一个数据
void SeqListInsert(SL* ps, int pos, SLDataType x) { assert(ps);
//可以插入数据的位置,[0,ps->size]
1、ps->size地方还没有数据,这里相当于尾插,所以在上面可以替换尾插
2、0的位置插入数据,就相当于头插,在上面可以替换头插 assert(pos <= ps->size && pos >= 0); SeqListCheckCapacity(ps); //检查空间使用情况 int end = ps->size - 1; //从后往前挪 while (end >= pos) //pos挪完后结束 { ps->a[end + 1] = ps->a[end]; end--; } ps->a[pos] = x;//指定位置插入指定数据 ps->size++; //插入数据后,记得+1 }
void SeqListErase(SL* ps, int pos) void SeqListErase(SL* ps, int pos) { assert(ps); assert(pos >= 0 && possize); int end = pos; while (end < ps->size - 1) { ps->a[end] = ps->a[end + 1]; end++; } ps->size--; } 删除pos位置的数据
void SeqListErase(SL* ps, int pos) { assert(ps);
//可以删除数据的位置,[0,ps->size-1]
1、ps->size-1有最后位置的数据,这里相当于尾删,所以在上面可以替换尾删
2、删除0位置的数据,就相当于头删,在上面可以替换头删
assert(pos >= 0 && pos<ps->size);
int end = pos; //pos位置开始
while (end < ps->size - 1) //从前往后进行覆盖
{
ps->a[end] = ps->a[end + 1];
end++;
}
ps->size--; //删除数据后记得-1
}
void SeqListPrint(SL* ps) void SeqListPrint(SL* ps) { assert(ps); assert(ps->size > 0); int i = 0; for (i = 0; i < ps->size; i++) { printf("%d->", ps->a[i]); } printf("NULL\n"); } 打印顺序表中的数据
void SeqListPrint(SL* ps) { assert(ps); assert(ps->size > 0); //确保顺序表中有数据 int i = 0; for (i = 0; i < ps->size; i++) { printf("%d->", ps->a[i]); } printf("NULL\n"); //最后一个位置打印空并换行 }
void SeqListModify(SL* ps, int pos, SLDataType x) void SeqListModify(SL* ps, int pos, SLDataType x) { assert(ps); assert(pos >= 0 && pos < ps->size); ps->a[pos] = x; } 修改pos位置得值
void SeqListModify(SL* ps, int pos, SLDataType x) { assert(ps); assert(pos >= 0 && pos < ps->size); //[0,ps->size)这些地方存储的有数据,可以进行修改 ps->a[pos] = x; //pos位置进行赋值 }
完整代码 SeaList.h #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<stdio.h> #include<assert.h> #include<stdlib.h>
typedef int SLDataType; typedef struct SeqList { SLDataType* a; int size; int capacity; }SL;
//初始化顺序表 void SeqListInit(SL* ps); //每次增容前检查空间的使用情况,并做出相应的调整 void SeqListCheckCapacity(SL* ps); //摧毁开辟的空间 void SeqListDestroy(SL* ps); //尾插 void SeqListPushBack(SL* ps, SLDataType x); //尾删 void SeqListPopBack(SL* ps); //头插 void SeqListPushFront(SL* ps, SLDataType x); //头删 void SeqListPopFront(SL* ps); //查找指定数据的下标 int SeqListFind(SL* ps, SLDataType x); //在pos位置插入一个数据 void SeqListInsert(SL* ps, int pos, SLDataType x); //删除pos位置的数据 void SeqListErase(SL* ps, int pos); //打印顺序表 void SeqListPrint(SL* ps); //修改pos位置的数据 void SeqListModify(SL* ps, int pos, SLDataType x);
SeqList.c #define _CRT_SECURE_NO_WARNINGS 1 #include"SeqList.h"
void SeqListInit(SL* ps) { assert(ps); ps->a = NULL; ps->size = ps->capacity = 0; }
void SeqListDestroy(SL* ps) { assert(ps); free(ps->a); ps->a = NULL; ps->size = ps->capacity = 0; }
void SeqListCheckCapacity(SL* ps) { assert(ps); if (ps->size == ps->capacity)//满了 { int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SL)); if (tmp == NULL) { printf("realloc fail\n"); exit(-1); } else { ps->a = tmp; ps->capacity = newcapacity; } } }
void SeqListPushBack(SL* ps, SLDataType x) { assert(ps); SeqListCheckCapacity( ps); ps->a[ps->size] = x; ps->size++; //SeqListInsert(ps, ps->size, x); }
void SeqListPopBack(SL* ps) { assert(ps); assert(ps->size > 0); ps->size--; //SeqListErase(ps, ps->size - 1); }
void SeqListPushFront(SL* ps, SLDataType x) { assert(ps); SeqListCheckCapacity(ps); int i = ps->size-1; for ( ; i >=0; i--) { ps->a[i+1] = ps->a[i]; } ps->a[0] = x; ps->size++; //SeqListInsert(ps, 0, x); }
void SeqListPopFront(SL* ps) { assert(ps); assert(ps->size > 0); int i = 0; for (i = 0; i < ps->size - 1; i++) { ps->a[i] = ps->a[i + 1]; } ps->size--; //SeqListErase(ps, 0); }
int SeqListFind(SL* ps, SLDataType x) { assert(ps); int i = 0; for (i = 0; i < ps->size; i++) { if (ps->a[i] == x) //找到了,就返回下标 { return i; } } return -1;//没有找到,返回-1 }
void SeqListInsert(SL* ps, int pos, SLDataType x) { assert(ps); assert(pos <= ps->size && pos >= 0); SeqListCheckCapacity(ps); int end = ps->size - 1; while (end >= pos) { ps->a[end + 1] = ps->a[end]; end--; } ps->a[pos] = x; ps->size++; }
void SeqListErase(SL* ps, int pos) { assert(ps); assert(pos >= 0 && possize); int end = pos; while (end < ps->size - 1) { ps->a[end] = ps->a[end + 1]; end++; } ps->size--; }
void SeqListPrint(SL* ps) { assert(ps); assert(ps->size > 0); int i = 0; for (i = 0; i < ps->size; i++) { printf("%d->", ps->a[i]); } printf("NULL\n"); }
void SeqListModify(SL* ps, int pos, SLDataType x) { assert(ps); assert(pos >= 0 && pos < ps->size); ps->a[pos] = x; }
测试:test.c #define _CRT_SECURE_NO_WARNINGS 1 #include"SeqList.h" void Test1() { SL sl; SeqListInit(&sl); SeqListPushBack(&sl, 1); SeqListPushBack(&sl, 2); SeqListPushBack(&sl, 3); SeqListPushBack(&sl, 4);
SeqListPushFront(&sl, 10);
SeqListPushFront(&sl, 20);
SeqListPushFront(&sl, 30);
int pos=SeqListFind(&sl, 10);
if (pos != -1)
{
SeqListInsert(&sl, pos, 100);
}
pos = SeqListFind(&sl, 20);
if (pos != -1)
{
SeqListErase(&sl, pos);
}
SeqListModify(&sl, pos, 200);
//SeqListPopFront(&sl);
//SeqListPopFront(&sl);
SeqListPrint(&sl);
SeqListDestroy(&sl);
} int main() { Test1(); return 0; }