提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
1.顺序表概念
【百度百科】顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
概念:线性表的顺序表示指的是用一组地址连续的储存单元依次存储线性表的数据结构。
整体采用C语言,总体采用模块化编程,此次简易的顺序表采用三大模块来实现,分别是“SeqList.h”文件,"SeqList.c"文件,“test.c”文件。本人新手,实现的代码参考教材书,如有错误,请求指出。
1. "SeqList.h"文件主要包括顺序表结构搭建、顺序表类型定义与函数声明。
2. “SeqList.c”文件主要包括顺序表初始化、顺序表的打印、顺序表的扩容、顺序表的空间释放、顺序表的任意位置插入、顺序表任意位置删除、顺序表的数据查找、顺序表的数据修改。
3. “tset.c”文件主要包括一个简易菜单以及主函数的实现思路。
(1). 顺序表结构搭建,创建一个结构体。
typedef struct SeqList
{
SLDataType* a; //指向动态数组指针
int size; //数组个数
int capacity; //容量-空间大小
}SeqList;
(2). 顺序表类型定义
#pragma once
#include
#include
#include
#include
#include
typedef int SLDataType;
(3). 函数声明
void SLInit(SeqList* ps);//初始化
void SLprint(SeqList* ps);//打印顺序表
void Destory(SeqList* ps);//释放空间
void SLCheckCapacity(SeqList* ps);//检查容量空间,满了扩容
void SLInsert(SeqList* ps, int pos, SLDataType x);//任意位置插入
void SLErase(SeqList* ps, int pos);//任意位置删除
int SLFind(SeqList* ps, SLDataType x);//寻找数据
void SLModify(SeqList* ps, int pos, SLDataType x);//修改数据
(1). 顺序表初始化
void SLInit(SeqList* ps)
{
assert(ps);
ps->a = NULL;//指向动态数组指针置空
ps->capacity = ps->size = 0;//数组个数与容量-空间大小置零
}
(2). 顺序表的打印
void SLprint(SeqList* ps)
{
int i = 0;
for (i = 0; i < ps->size; i++)
{
printf("%d ", ps->a[i]);
}
printf("\n");
}
(3). 顺序表的扩容
void SLCheckCapacity(SeqList* ps)
{
assert(ps);
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
//检查空间是否为足够,如果等于零则赋值4,不等于零则扩大两倍
SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));
//扩容
assert(tmp);
ps->a = tmp;
ps->capacity = newcapacity;
}
}
(4). 顺序表的空间释放
void Destory(SeqList* ps)
{
if (ps->a)
{
free(ps->a);
ps->a = NULL;
ps->capacity = ps->size = 0;
}
}
(5). 顺序表的任意位置插入
void SLInsert(SeqList* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);
SLCheckCapacity(ps);
int end = ps->size;
while (pos < end)
{
ps->a[end] = ps->a[end - 1];//插入位置及之后的元素分别向后移一位
end--;
}
ps->a[pos] = x;
ps->size++;
}
(6). 顺序表任意位置删除
void SLErase(SeqList* ps, int pos)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);
int Begin = pos;
while (Begin < ps->size)
{
ps->a[Begin] = ps->a[Begin + 1];//被删除元素之后的元素都向前移一位
Begin++;
}
ps->size--;
}
(7). 顺序表的数据查找
int SLFind(SeqList* ps, SLDataType x)
{
assert(ps);
for (int i = 0; i < ps->size; i++)
{
if (ps->a[i] == x)
return i;
}
return -1;
}
(8). 顺序表的数据修改
void SLModify(SeqList* ps, int pos, SLDataType x)
{
assert(ps);
assert(pos >= 0 && pos <= ps->size);
ps->a[pos] = x;
}
main函数
//菜单
void menu()
{
printf("\n");
printf("####################\n");
printf("########1.ADD#######\n");
printf("########2.DEL#######\n");
printf("########3.MIDiFY####\n");
printf("########4.PRINT#####\n");
printf("########5.ENIT######\n");
printf("####################\n");
}
//插入数据
void test1(SeqList* ps)
{
int set = 0, loc = 0;
printf("请输入要插入的位置:");
scanf("%d", &loc);
printf("请输入要插入的值:");
scanf("%d", &set);
SLInsert(ps, loc, set);
}
//删除数据
void test2(SeqList* ps)
{
int set = 0;
printf("请输入要删除的值:");
scanf("%d", &set);
int pos=SLFind(ps,set);
SLErase(ps,pos);
}
//修改数据
void test3(SeqList* ps)
{
int set = 0, mod = 0;
printf("请输入要修改的值:");
scanf("%d", &set);
printf("请输入修改后的值:");
scanf("%d", &mod);
int pos = SLFind(ps, set);
SLModify(ps, pos, mod);
}
//打印链表
void test4(SeqList* ps)
{
SLprint(ps);
}
//退出
void test5(SeqList* ps)
{
printf("退出程序");
Destory(ps);
}
int main()
{
SeqList a;
SLInit(&a);
//SLtest2(&a);
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:test1(&a); break;
case 2:test2(&a); break;
case 3:test3(&a); break;
case 4:test4(&a); break;
case 5:test5(&a); return 0;
}
} while (input);
return 0;
}
1. 顺序表优点
顺序存储结构的主要优点是节省存储空间,因为分配给数据的存储单元全用存放结点的数据(不考虑c/c++语言中数组需指定大小的情况),结点之间的逻辑关系没有占用额外的存储空间。
2. 顺序表缺点
顺序存储方法的主要缺点是不便于修改,对结点的插入、删除运算时,可能要移动一系列的结点。