一.定义
1.线性表
(1)线性表的定义(逻辑结构):具有相同数据类型的n(n>=0)的有限个数的数据元素的有序排列。
(2)线性表的运算(操作):创建销毁,增删改查。
(3)线性表的存储结构:顺序存储(产生了顺序表),链式存储(产生了链表)
2.顺序表
使用静态数组是实现顺序表的一种方式。
使用静态数组十分简单,但是由于静态分配时,数组的大小和空间已经固定,一旦空间占满,再想加入新的数据就会造成数据溢出,进而导致程序崩溃。
二.代码分块
1.定义结构体
typedef struct{
int data[Maxsize];//用静态数组存储数据元素
int length;//表示顺序表的长度
}SqList;//typedef别名函数将该结构体别名为SqList
2.初始化和数据元素预添加
void InitList(SqList *L){//初始化顺序表
for(int i=0;i<Maxsize;i++){//循环遍历该顺序表
L->data[i]=0;//将每个数据元素置为0,初始化
}
L->length=0;//将顺序表长度置为0
}
void AddList(SqList *L){//给该顺序表添加元素
int x = 1;
int helfsize = Maxsize/2;//初始赋值长度为表总长度的一半
for(int i=0;i<helfsize;i++){
L->data[i] = x;//将x的值赋给顺序表该位置的数据元素
x++;//增加x的值
L->length++;//增加顺序表表长
}
}
3.数据元素插入
bool InsertList(SqList *L){
int inputPosition = 0;//定义记录插入位置并初始化
int inputNum = 0;//定义记录插入数据元素的值并初始化
printf("请输入要插入的位置:");
scanf("%d",&inputPosition);//获取插入位置
printf("请输入要插入的内容:");
scanf("%d",&inputNum);//获取插入内容
if(inputPosition>L->length||inputPosition<1){
//条件判断一:该插入位置不能大于现在顺序表的总长
//(提问为什么不能插入到超过总长的地方?因为顺序表是线性存储的,其数据元素逻辑相邻,并且存储相邻)
//条件判断二:插入位置不能小于最初位置
return false;
}
if(L->length>=Maxsize){
//条件判断三:该顺序表是否存满
return false;
}
for(int i = L->length;i>=inputPosition;i--){//执行插入操作 :循环将要插入位置之后的元素全部后移一位
L->data[i] = L->data[i-1];//将顺序表最后一个位置的数据元素值放入下一个位置
//请注意位序和数组下标的关系
//该处造成的时间复杂度为O(n)
}
L->data[inputPosition-1]=inputNum;//将插入值赋给要插入的位置
L->length++;//顺序表长度+1
return true;
}
4.按位查找
bool GetElem(SqList L){//按位查找
int ElemPosition = 0;//定义记录查找的位置并初始化
printf("请输入要查找的位置:");
scanf("%d",&ElemPosition);//获取查找位置
//感觉将输入输出这部分也封装一下会很方便使用
if(ElemPosition>L.length||ElemPosition<1){
//判断输入是否合法
return false;
}
int Elemdata = L.data[ElemPosition-1];//顺序表的存储结构是顺序存储,其优点为随机存储,时间复杂度为O(1);
printf("%d位置的元素值为%d\n",ElemPosition,Elemdata);
return true;
}
5.按值查找
bool LocateElem(SqList L){//按值查找
int ElemData = 0;//定义记录查找的值并初始化
printf("请输入要查找的数据元素:");
scanf("%d",&ElemData);//获取查找位置
for(int i=0;i<L.length;i++){//按值查找无法发挥顺序表随机存储的优势
if(L.data[i]==ElemData){
printf("要查找的值为%d,其位置为%d\n",ElemData,i+1);
//按值查找的平均时间复杂度为O(n)
return true;
}
}
printf("没有找到该值!\n");
return true;
}
6.删除操作
bool DelList(SqList *L,int *deldata){//删除操作
int DelPosition = 0;//定义记录要删除数据元素的位置并初始化
printf("请输入要删除数据元素的位置:");
scanf("%d",&DelPosition);//获取查找位置
if(DelPosition>L->length||DelPosition<1){
//判断输入是否合法
return false;
}
*deldata = L->data[DelPosition-1];//先将要删除的值存储一下
for(int i =DelPosition;i<L->length;i++){//从删除点开始,将后一个元素迁移,一直到将最后一个元素都向前移动一位为止
L->data[i-1] = L->data[i];//将后一个元素前移
}
L->length--;//顺序表长度-1
return true;
}
三.整体代码
//用静态数组的方式实现顺序表
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 10 //宏定义最大长度
//*L是指向顺序表的指针,&L是该顺序表的地址
typedef struct{
int data[Maxsize];//用静态数组存储数据元素
int length;//表示顺序表的长度
}SqList;//typedef别名函数将该结构体别名为SqList
void InitList(SqList *L){//初始化顺序表
for(int i=0;i<Maxsize;i++){//循环遍历该顺序表
L->data[i]=0;//将每个数据元素置为0,初始化
}
L->length=0;//将顺序表长度置为0
}
void AddList(SqList *L){//给该顺序表添加元素
int x = 1;
int helfsize = Maxsize/2;//初始赋值长度为表总长度的一半
for(int i=0;i<helfsize;i++){
L->data[i] = x;//将x的值赋给顺序表该位置的数据元素
x++;//增加x的值
L->length++;//增加顺序表表长
}
}
bool InsertList(SqList *L){
int inputPosition = 0;//定义记录插入位置并初始化
int inputNum = 0;//定义记录插入数据元素的值并初始化
printf("请输入要插入的位置:");
scanf("%d",&inputPosition);//获取插入位置
printf("请输入要插入的内容:");
scanf("%d",&inputNum);//获取插入内容
if(inputPosition>L->length||inputPosition<1){
//条件判断一:该插入位置不能大于现在顺序表的总长
//(提问为什么不能插入到超过总长的地方?因为顺序表是线性存储的,其数据元素逻辑相邻,并且存储相邻)
//条件判断二:插入位置不能小于最初位置
return false;
}
if(L->length>=Maxsize){
//条件判断三:该顺序表是否存满
return false;
}
for(int i = L->length;i>=inputPosition;i--){//执行插入操作 :循环将要插入位置之后的元素全部后移一位
L->data[i] = L->data[i-1];//将顺序表最后一个位置的数据元素值放入下一个位置
//请注意位序和数组下标的关系
//该处造成的时间复杂度为O(n)
}
L->data[inputPosition-1]=inputNum;//将插入值赋给要插入的位置
L->length++;//顺序表长度+1
return true;
}
void ShowList(SqList L){//显示该顺序表元素 (直接遍历显示所有元素)
for(int i=0;i<L.length;i++){
printf("%d\n",L.data[i]);
}
}
bool GetElem(SqList L){//按位查找
int ElemPosition = 0;//定义记录查找的位置并初始化
printf("请输入要查找的位置:");
scanf("%d",&ElemPosition);//获取查找位置
//感觉将输入输出这部分也封装一下会很方便使用
if(ElemPosition>L.length||ElemPosition<1){
//判断输入是否合法
return false;
}
int Elemdata = L.data[ElemPosition-1];//顺序表的存储结构是顺序存储,其优点为随机存储,时间复杂度为O(1);
printf("%d位置的元素值为%d\n",ElemPosition,Elemdata);
return true;
}
bool LocateElem(SqList L){//按值查找
int ElemData = 0;//定义记录查找的值并初始化
printf("请输入要查找的数据元素:");
scanf("%d",&ElemData);//获取查找位置
for(int i=0;i<L.length;i++){//按值查找无法发挥顺序表随机存储的优势
if(L.data[i]==ElemData){
printf("要查找的值为%d,其位置为%d\n",ElemData,i+1);
//按值查找的平均时间复杂度为O(n)
return true;
}
}
printf("没有找到该值!\n");
return true;
}
bool DelList(SqList *L,int *deldata){//删除操作
int DelPosition = 0;//定义记录要删除数据元素的位置并初始化
printf("请输入要删除数据元素的位置:");
scanf("%d",&DelPosition);//获取查找位置
if(DelPosition>L->length||DelPosition<1){
//判断输入是否合法
return false;
}
*deldata = L->data[DelPosition-1];//先将要删除的值存储一下
for(int i =DelPosition;i<L->length;i++){//从删除点开始,将后一个元素迁移,一直到将最后一个元素都向前移动一位为止
L->data[i-1] = L->data[i];//将后一个元素前移
}
L->length--;//顺序表长度-1
return true;
}
void displayMenu(){
int option = 0;
bool flag =true;
SqList L;//调用结构体类型创建一个静态数组线性表
InitList(&L);//初始化线性表
AddList(&L);//为顺序表表添加一些初始元素(占顺序表的一半)
while (flag)
{
printf("----基于静态数组实现顺序表----\n");
printf("1.初始化顺序表\n");
printf("2.查看顺序表元素\n");
printf("3.插入元素\n");
printf("4.按位查找\n");
printf("5.按值查找\n");
printf("6.删除元素\n");
printf("7.结束\n");
printf("请输入要进行操作的序号:\n");
scanf("%d",&option);
printf("------------------------------\n");
if(option==1){
InitList(&L);//初始化线性表
AddList(&L);//为顺序表表添加一些初始元素(占顺序表的一半)
ShowList(L);//将顺序表表中的元素全部展示
}else if(option==2){
ShowList(L);//将顺序表表中的元素全部展示
}else if(option==3){
InsertList(&L);//向顺序表中插入元素(按位插入)
ShowList(L);//将顺序表表中的元素全部展示
}else if(option==4){
GetElem(L);//按位查找(请思考这里为什么使用的不是&L而是L? 因为查找不需要修改数据元素)
}else if(option==5){
LocateElem(L);//按值查找
}else if(option==6){
int deldata = 0;//要删除的数据元素的值
DelList(&L,&deldata);//删除操作(按位)
ShowList(L);//将顺序表表中的元素全部展示
}
if(option==7){
exit(0);
}
}
}
int main(){
displayMenu();
// SqList L;//调用结构体类型创建一个静态数组线性表
// InitList(&L);//初始化线性表
// AddList(&L);//为顺序表表添加一些初始元素(占顺序表的一半)
// ShowList(L);//将顺序表表中的元素全部展示
// InsertList(&L);//向顺序表中插入元素(按位插入)
// ShowList(L);//将顺序表表中的元素全部展示
// GetElem(L);//按位查找(请思考这里为什么使用的不是&L而是L? 因为查找不需要修改数据元素)
// LocateElem(L);//按值查找
// int deldata = 0;//要删除的数据元素的值
// DelList(&L,&deldata);//删除操作(按位)
// ShowList(L);//将顺序表表中的元素全部展示
return 0;
}