数据结构—顺序表的操作及实现(C/C++)
文章目录
1.0初始化定义
#include<stdio.h>
#include<malloc.h>
#define MAXSIZE 100 //定义数组的最大长度
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int ElemType; // 自己定义的类型
typedef int status; // 上同
1.1顺序表的定义
typedef struct
{
ElemType* elem; //基地址
int length; //一维数组长度
}sqlist; //顺序表的定义 顺序表用sqlist表示
1.2顺序表的初始化(构造一个空的顺序表)
1.用C语言的一维数组实现,这里采用动态分配的一维数组,在初始化时用函数malloc()为顺序表分配一个基本容量。
status InitList(sqlist &L)
{
L.elem = (ElemType*)malloc(sizeof(ElemType)); //给基地址分配空间
if(!L.elem)
{
return (OVERFLOW); //如果存储空间分配失败,返回-1
}
L.length = 0; //初始化数组长度为0
return OK;
}
1.3顺序表的创建
status createlist(sqlist *L)
{
int n;
printf("请输入要输入元素的个数:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
printf("请输入第%d个元素:", (i + 1)); //因为循环从0开始,所以i从i+1开始
scanf("%d", &(L->elem[i]));
L->length++; //每存一个数,数组长度+1
}
return OK;
}
1.4顺序表的取值
status GetElem(sqlist *L,int i,ElemType &e)
{
if(i<1||i>L->length)
{
return ERROR;
}
else
{
e = L->elem[i - 1]; //通过e返回第i个元素的值
return OK;
}
}
1.5顺序表的查找
status LocateElem(sqlist *L,ElemType e)
{
//遍历数组元素 判断条件成立
int i;
for(i=0;i<L->length;i++)
{
if(L->elem[i]==e)
{
return printf("元素的位置为:%d",i+1);//因为循环从0开始,所以i从i+1开始
}
}
printf("\n");
return OK;
}
1.6顺序表的插入
status ListInsert(sqlist *L,int i,ElemType e)
{
int j;
if(i<1|| i>L->length+1) //如果插入位置小于1或长度大于length+1,则返回错误
{
return ERROR;
}
if(L->length==MAXSIZE) //判断数组长度,如果数组长度=最大设定长度,返回错误
{
return ERROR;
}
for(j=L->length-1;j>=i-1;j--) //元素从最后面一个元素到当前i-1的位置
{
L->elem[j + 1] = L->elem[j];//将线性表的第i个元素和它后面的所有元素均向后移动一个位置
}
L->elem[i - 1] = e; //空出来的位置,即为插入位置,给插入位置赋值
L->length++; //插入数组后长度+1
return OK;
}
1.7顺序表的删除
status ListDelete(sqlist *L,int i)
{
int j;
if(i<1||i>L->length) //判断删除位置是否合理,如果小于1或大于数组的长度
{
return ERROR; //返回错误
}
for(j=i;j<L->length;j++) //删除i位置,从当前i位置开始,后面的元素全部往前移动一位
{
L->elem[j - 1] = L->elem[j]; //全部往前移动一位
}
L->length--; //删除数组长度-1
return OK;
}
1.8C完整代码如下:
#include<stdio.h>
#include<malloc.h>
#define MAXSIZE 100 //定义数组的最大长度
#define OK 1
#define OVERFLOW -1
#define ERROR -1
typedef int ElemType; // 自己定义的类型
typedef int status; // 上同
//顺序表的定义 顺序表用sqlist表示
typedef struct
{
ElemType* elem; //基地址
int length; //一维数组长度
}sqlist;
//顺序表的初始化
status InitList(sqlist &L)
{
L.elem = (ElemType*)malloc(sizeof(ElemType)); //给基地址分配空间
if(!L.elem)
{
return (OVERFLOW); //如果 存储空间分配失败,返回-1
}
L.length = 0; //初始化数组长度为0
return OK;
}
//创建顺序表
status createlist(sqlist *L)
{
int n;
printf("请输入要输入元素的个数:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
printf("请输入第%d个元素:", (i + 1)); //因为循环从0开始,所以i从i+1开始
scanf("%d", &(L->elem[i]));
L->length++; //每存一个数,数组长度+1
}
return OK;
}
//顺序表的取值
status GetElem(sqlist *L,int i,ElemType &e)
{
if(i<1||i>L->length)
{
return ERROR;
}
else
{
e = L->elem[i - 1]; //通过e返回第i个元素的值
return OK;
}
}
//顺序表的查找
status LocateElem(sqlist *L,ElemType e)
{
//遍历数组元素 判断条件成立
int i;
for(i=0;i<L->length;i++)
{
if(L->elem[i]==e)
{
return printf("元素的位置为:%d",i+1);//因为循环从0开始,所以i从i+1开始
}
}
printf("\n");
return OK;
}
//顺序表的插入操作
status ListInsert(sqlist *L,int i,ElemType e)
{
int j;
if(i<1|| i>L->length+1) //如果插入位置小于1或长度大于length+1,则返回错误
{
return ERROR;
}
if(L->length==MAXSIZE) //判断数组长度,如果数组长度=最大设定长度,返回错误
{
return ERROR;
}
for(j=L->length-1;j>=i-1;j--) //元素从最后面一个元素到当前i-1的位置
{
L->elem[j + 1] = L->elem[j];//最后面一个元素到当前i-1的位置全部往后移动一位
}
L->elem[i - 1] = e; //空出来的位置,即为插入位置,给插入位置赋值
L->length++; //插入数组后长度+1
return OK;
}
//顺序表的删除操作
status ListDelete(sqlist *L,int i)
{
int j;
if(i<1||i>L->length) //判断删除位置是否合理,如果小于1或大于数组的长度
{
return ERROR; //返回错误
}
for(j=i;j<L->length;j++) //删除i位置,从当前i位置开始,后面的元素全部往前移动一位
{
L->elem[j - 1] = L->elem[j]; //全部往前移动一位
}
L->length--; //删除数组长度-1
return OK;
}
//打印顺序表
int print(sqlist* L)
{
int i;
printf("顺序表为:");
for( i=0;i<L->length;i++) //循环遍访问数组每一个元素
{
printf("%3d", L->elem[i]);
}
printf("\n");
return OK;
}
//主函数如下
int main()
{
int n,m,t,k;
sqlist L; //声明顺序表L
InitList(L); //初始化
createlist(&L);//创建顺序表
printf("\n");
print(&L);
printf("\n");
printf("请输入需要查找的元素:");
scanf("%d",&n);
LocateElem(&L,n);
printf("\n");
printf("请输入需要插入的位置:");
scanf("%d",&m);
printf("请输入需要插入元素的值:");
scanf("%d",&t);
ListInsert(&L,m,t);
printf("插入后的顺序表为:\n");
print(&L);
printf("请输入需要删除元素的位置:");
scanf("%d",&k);
ListDelete(&L,k);
printf("删除后的顺序表为:\n");
print(&L);
return 0;
}
1.8C++完整代码如下:
#include<iostream>
#include<stdlib.h>
#define MAXSIZE 100 //定义数组的最大长度
#define OK 1
#define OVERFLOW -1
#define ERROR -1
using namespace std;
typedef int ElemType; // 自己定义的类型
typedef int status; // 上同
//顺序表的定义 顺序表用sqlist表示
typedef struct
{
ElemType* elem; //基地址
int length; //一维数组长度
}sqlist;
//顺序表的初始化
status InitList(sqlist &L)
{
L.elem = new ElemType; //给基地址分配空间
if(!L.elem)
{
return (OVERFLOW); //如果 存储空间分配失败,返回-1
}
L.length = 0; //初始化数组长度为0
return OK;
}
//创建顺序表
status createlist(sqlist *L)
{
int n;
cout<<"请输入要输入元素的个数:";
cin>>n;
for (int i = 0; i < n; i++)
{
cout<<"请输入第"<<i+1<<"个元素"; //因为循环从0开始,所以i从i+1开始
cin>>L->elem[i];
L->length++; //每存一个数,数组长度+1
}
return OK;
}
//顺序表的取值
status GetElem(sqlist *L,int i,ElemType &e)
{
if(i<1||i>L->length)
{
return ERROR;
}
else
{
e = L->elem[i - 1]; //通过e返回第i个元素的值
return OK;
}
}
//顺序表的查找
status LocateElem(sqlist *L,ElemType e)
{
//遍历数组元素 判断条件成立
int i;
for(i=0;i<L->length;i++)
{
if(L->elem[i]==e)
{
cout<<"元素的位置为:"<<i+1<<endl;//因为循环从0开始,所以i从i+1开始
return OK;
}
}
cout<<endl;
return OK;
}
//顺序表的插入操作
status ListInsert(sqlist *L,int i,ElemType e)
{
int j;
if(i<1|| i>L->length+1) //如果插入位置小于1或长度大于length+1,则返回错误
{
return ERROR;
}
if(L->length==MAXSIZE) //判断数组长度,如果数组长度=最大设定长度,返回错误
{
return ERROR;
}
for(j=L->length-1;j>=i-1;j--) //元素从最后面一个元素到当前i-1的位置
{
L->elem[j + 1] = L->elem[j];//最后面一个元素到当前i-1的位置全部往后移动一位
}
L->elem[i - 1] = e; //空出来的位置,即为插入位置,给插入位置赋值
L->length++; //插入数组后长度+1
return OK;
}
//顺序表的删除操作
status ListDelete(sqlist *L,int i)
{
int j;
if(i<1||i>L->length) //判断删除位置是否合理,如果小于1或大于数组的长度
{
return ERROR; //返回错误
}
for(j=i;j<L->length;j++) //删除i位置,从当前i位置开始,后面的元素全部往前移动一位
{
L->elem[j - 1] = L->elem[j]; //全部往前移动一位
}
L->length--; //删除数组长度-1
return OK;
}
//打印顺序表
int print(sqlist* L)
{
cout<<"顺序表为:";
for(int i=0;i<L->length;i++) //循环遍访问数组每一个元素
{
cout<<L->elem[i]<<"\40";
}
cout<<endl;
return OK;
}
//主函数如下
int main()
{
int n,m,t,k;
sqlist L; //声明顺序表L
InitList(L); //初始化
createlist(&L);//创建顺序表
cout<<endl;
print(&L);
cout<<endl;
cout<<"请输入需要查找的元素:";
cin>>n;
LocateElem(&L,n);
cout<<endl;
cout<<"请输入需要插入的位置:";
cin>>m;
cout<<"请输入需要插入元素的值:";
cin>>t;
ListInsert(&L,m,t);
cout<<"插入后的顺序表为:";
print(&L);
cout<<"请输入需要删除元素的位置:";
cin>>k;
ListDelete(&L,k);
cout<<endl;
cout<<"删除后的顺序表为:";
print(&L);
return 0;
}
1.9运行截图:
主函数也可调整为switch结构,读者可自行尝试。
2.0参考书籍
《数据结构》(C语言版)(第2版)—严蔚敏 李冬梅 吴伟民 编著
2.1总结
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,顺序表可以随机存取表中任一元素,逻辑上相邻的元素,它们物理地址相邻,实现元素的随机存取。
顺序表缺点:做插入或删除时候,需要移动大量的元素,由于数组有长度相对固定的静态特征,当表中数据元素个数较多且变化较大时候,操作过程复杂,导致存储空间浪费。
第一次写博客,最后文章如果有写得不对的地方,请大家多多指正!