线性表的顺序表示和实现
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种表示也称作线性表的顺序存储结构或者顺序映像。通常,称这种存储结构的线性表为顺序表。其特点是,逻辑上相邻的数据元素,其物理次序也是相邻的。
假设线性表的每个元素需占用L个存储单元,并以所占的第一个单元的存储地址作为数据元素的存储起始位置。则线性表中第i+1个数据存储位置LOC(ai+1)和第i个数据元素的存储位置LOC(ai)之间满足下列关系式:
LOC(ai+1)=LOC(ai)+L
一般来说,线性表的第i个数据元素ai的存储位置为:LOC(ai)=LOC(ai)+(i - 1)*L,式中,LOC(ai)是线性表的第一个数据元素a1的存储位置,通常称为线性表的起始位置或基地址,表中相邻的元素ai和ai+1的存储位置LOC(ai)和LOC(ai+1)是相邻的。每一个数据元素的存储位置都和线性表的起始位置相差一个常数,这个常数和数据元素在线性表中的位序成正比。
由此,只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。
代码部分:
首先定义一个结构体用来表示线性表
#define MAXSIZE 100 //最大长度 typedef struct //线性表的结构体 { ElemType *elem; //线性表 int lenth; //已存线性表长度 int listsize; //线性表总长度 }Sqlist;
初始化线性表,利用malloc函数动态申请分配内存,并设置了线性表长度为0和最大长度为100
int InitList(Sqlist &L) //初始化线性表 { L.elem = (ElemType *)malloc(100*sizeof(ElemType)); //动态分配线性表长度 if(!L.elem) //若未申请成功,则返回失败 { return ERROR; } L.lenth = 0; //若申请成功,输出线性表长度和总长度 L.listsize = 100; }
下面这个函数用来取某个元素,首先我们要取的那个数的下标判断是否越界,越界就返回错误,没越界的话,就将L.elem[i - 1]的值赋给e,为什么是i - 1呢?因为数组的下标是从0开始。
ElemType Getelem(Sqlist L,int i,ElemType &e) //取元素 { if(i < 1||i > L.lenth) //若越界,则返回错误 { return ERROR; } e = L.elem[i - 1]; //将取得的值赋给e return e; }
下面这个函数是用来插入元素的,首先判断我们要插入的位置是否合理,如果小于1或者大于线性表的最大长度,就无法插入,同时呢,要判断线性表是否存满,已存满的话也是没办法再存了的。上述情况都没有的话,就可以插了,首先将线性表的最后一位下标得到,开始从最后一位,往后移一位,当移到我们要插入元素的那个地方后,将e赋值到这个位置即可,同时呢,线性表的长度也要自增1。
ElemType Insertelem(Sqlist &L,int i,ElemType e) //插入元素 { if(i < 1||i > L.lenth + 1) //判断是否越界 { return ERROR; } if(L.lenth == 100) //判断线性表是否已满 { return ERROR; } for(int j = L.lenth - 1;j >= i - 1;j--) //从最后一位开始,向后移动 { L.elem[j + 1] = L.elem[j]; } L.elem[i - 1] = e; //插入 ++L.lenth; //线性表长度自增 return OK; }
下面这个函数是用来寻找某个元素的,这个比较容易实现,只需遍历线性表,找到相等的值之后,就返回下标。
int Findelem(Sqlist L,ElemType elem) //寻找某个元素 { for(int i = 0;i < L.lenth;i++) //遍历线性表,若成功则返回下标 { if(elem == L.elem[i]) { return (i+1); } } return ERROR; //未找到,返回失败 }
这个函数用来输出线性表,只需一个for循环遍历线性表即可。
void PrintList(Sqlist L) //遍历线性表,输出线性表每个元素 { for(int i = 0;i < L.lenth;i++) { cout<<L.elem[i]; if(i != L.lenth - 1) { cout<<"-->"; } } cout<<endl; }
下面这个函数用来删除某个位置的元素,首先,老规矩,判断是否越界,然后将位置赋给j,再将后面的元素都前移一位。
int Delelem(Sqlist &L,int i) //删除某个元素 { if(i < 1|| i > L.lenth + 1) //判断是否越界 { return ERROR; } for(int j = i - 1;j < L.lenth;j++) //将该元素后面的元素诸位前移一位 { L.elem[j] = L.elem[j + 1]; } L.lenth--; //长度减一 }
这里我直接做了一个小小的功能程序,里面可以通过菜单分别执行上面的几个函数。
#include <iostream> using namespace std; #include <stdio.h> #include<malloc.h> //动态分配内存的头文件 #define OK 1 //成功 #define ERROR 0 //失败 #define ElemType int //元素类型 #define MAXSIZE 100 //最大长度 typedef struct //线性表的结构体 { ElemType *elem; //线性表 int lenth; //已存线性表长度 int listsize; //线性表总长度 }Sqlist; int InitList(Sqlist &L) //初始化线性表 { L.elem = (ElemType *)malloc(100*sizeof(ElemType)); //动态分配线性表长度 if(!L.elem) //若未申请成功,则返回失败 { return ERROR; } L.lenth = 0; //若申请成功,输出线性表长度和总长度 L.listsize = 100; } ElemType Getelem(Sqlist L,int i,ElemType &e) //取元素 { if(i < 1||i > L.lenth) //若越界,则返回错误 { return ERROR; } e = L.elem[i - 1]; //将取得的值赋给e return e; } ElemType Insertelem(Sqlist &L,int i,ElemType e) //插入元素 { if(i < 1||i > L.lenth + 1) //判断是否越界 { return ERROR; } if(L.lenth == 100) //判断线性表是否已满 { return ERROR; } for(int j = L.lenth - 1;j >= i - 1;j--) //从最后一位开始,向后移动 { L.elem[j + 1] = L.elem[j]; } L.elem[i - 1] = e; //插入 ++L.lenth; //线性表长度自增 return OK; } int Findelem(Sqlist L,ElemType elem) //寻找某个元素 { for(int i = 0;i < L.lenth;i++) //遍历线性表,若成功则返回下标 { if(elem == L.elem[i]) { return (i+1); } } return ERROR; //未找到,返回失败 } void PrintList(Sqlist L) //遍历线性表,输出线性表每个元素 { for(int i = 0;i < L.lenth;i++) { cout<<L.elem[i]; if(i != L.lenth - 1) { cout<<"-->"; } } cout<<endl; } int Delelem(Sqlist &L,int i) //删除某个元素 { if(i < 1|| i > L.lenth + 1) //判断是否越界 { return ERROR; } for(int j = i - 1;j < L.lenth;j++) //将该元素后面的元素诸位前移一位 { L.elem[j] = L.elem[j + 1]; } L.lenth--; //长度减一 } void Menu() //菜单函数 { cout<<"<<<<<<<<<<<<<<<<<<菜单>>>>>>>>>>>>>>>>>>"<<endl; cout<<"1.初始化线性表"<<endl; cout<<"2.取出线性表中的某个数"<<endl; cout<<"3.在线性表的某个位置插入元素"<<endl; cout<<"4.在线性表中寻找某个元素"<<endl; cout<<"5.删除某个元素"<<endl; cout<<"6.输出线性表"<<endl; cout<<"7.菜单"<<endl; cout<<"输入对应选项,执行对应操作"<<endl; cout<<"初始线性表:"; } int main() { int choose; //元素位置序号 ElemType ea; //定义一个元素 Sqlist La; //定义一个线性表 InitList(La); //初始化线性表 Menu(); //输出菜单 for(int i;i <= 10;i++) //用插入线性表函数给链表赋初值 { Insertelem(La,i,i); } PrintList(La); //输出初始线性表 while(cin>>choose) //循环执行,选择对应的选项,执行对应的操作 { switch(choose) { case 1: { InitList(La); cout<<"初始化线性表之后,线性表为空,请重新插入元素之后再进行操作"<<endl; int i,j; cout<<"输入你要插入得位置和要插入的数:"; cin>>i>>j; Insertelem(La,i,j); cout<<"插入成功!"<<endl; break; } case 2: { int i; cout<<"输入你要取得元素序号:"; cin>>i; cout<<Getelem(La,i,ea)<<endl; break; } case 3: { int i,j; cout<<"输入你要插入得位置和要插入的数:"; cin>>i>>j; Insertelem(La,i,j); cout<<"插入成功!"<<endl; break; } case 4: { int pos,i; cout<<"输入你要寻找的元素值:"; cin>>i; pos = Findelem(La,i); cout<<pos<<endl; break; } case 5: { int i; cout<<"请输入你要删除元素的下标:"; cin>>i; Delelem(La,i); cout<<"删除成功!"<<endl; PrintList(La); break; } case 6:PrintList(La);break; case 7:Menu();break; default:cout<<"输入有误,请重新输入"<<endl; } } return 0; }
运行结果:
大家有什么不懂的可以通过QQ(1033278524)来问我,码字不易,希望大家能给我一个赞,支持一下,谢谢