一、线性表
线性表的顺序存储结构又称为顺序表,它是用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。
注:线性表从1开始,而数组从0开始。
数组大小有两种方式指定,一是静态分配,二是动态扩展。
优点:随机访问特性,查找O(1)时间,存储密度高;逻辑上相邻的元素,物理上也相邻;
缺点:插入删除需移动大量元素。
顺序表相关的操作跟数组有关,一般都是移动数组元素。
二、线性表的代码
1、线性表的静态分配
#define MAXSIZE 10 //线性表的最大长度
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE]; //线性表的元素
int length; //线性表的当前长度
}SqList; //线性表的类型定义
2、线性表的动态分配
#define InitSize 10 //线性表长度的初始定义
typedef int ElemType;
typedef struct{
ElemType *data; //指示动态分配数组的指针
int length,MaxSize; //线性表的当前个数和最大容量
}SqList; //线性表的类型定义
初始动态分配语句
C语言
L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize);
C++
L.data = new ElemType[InitSize];
3、线性表的基本操作的实现
1、插入操作
//插入
bool ListInsert(SqList &L,int i,ElemType value){
if(i<1 || i>L.length+1){ //判断i的范围是否有效
return false;
}
if(L.length>=MAXSIZE){ //当前储存空间已满,不能插入
return false;
}
for(int j = L.length;j>=i;j--){ //将第i个元素及以后的元素后移
L.data[j] = L.data[j-1];
}
L.data[i-1] = value; //在i位置放入e
L.length++; //线性表长度加1
return true;
}
2、删除操作
//删除
bool ListDelete(SqList &L,int i,ElemType &e){
if(i<1 || i>L.length){ //判断i的范围是否有效
return false;
}
e = L.data[i-1]; //将被删除的元素赋值给e
for(int j = i;j<L.length;j++){ //将第i个元素及以后的元素前移
L.data[j-1] = L.data[j];
}
L.length--; //线性表长度减1
return true;
}
3、按值查找(顺序查找)
int LocateElem(SqList L,ElemType e){
int i;
for(i=0;i<L.length;i++){
if(L.data[i] == e){
return i+1; //下标为i的元素值等于e,返回其序号i+1
}
}
return 0; //退出循环,说明查找失败
}
4、按序号查找
int LocateElem2(SqList &L,int i){
if(i<1||i>L.length){ //判断i的范围是否有效
return 0;
}
ElemType e = L.data[i-1]; //直接返回数据
return e;
}
5、输出线性表
void PrintList(SqList &L){
for(int i=0;i<L.length;i++){
cout<<L.data[i]<<" ";
}
cout<<endl;
}
6、主程序
int main(){
SqList L; //定义线性表
bool res; //返回结果值
ElemType del; //返回删除元素
L.data[0]=1; //数组初始化
L.data[1]=2;
L.data[2]=3;
L.length=3;
//输出数组
PrintList(L);
//在第二个位置插入值
res = ListInsert(L,2,20);
if(res){
cout<<"插入成功"<<endl;
PrintList(L);
}else{
cout<<"插入失败"<<endl;
PrintList(L);
}
//按值查找
cout<<"数组值为1所在位置为:";
cout<<LocateElem(L, 1)<<endl;
//按序号查找
cout<<"数组第一个元素为:";
cout<<LocateElem2(L, 1)<<endl;
//删除数组第二个元素
res = ListDelete(L,2,del);
if(res){
cout<<"删除成功"<<endl;
cout<<"删除元素为:"<<del<<endl;
PrintList(L);
}else{
cout<<"删除失败"<<endl;
PrintList(L);
}
return 0;
}
三、全部代码
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
#define MAXSIZE 10
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int length;
}SqList;
//插入
bool ListInsert(SqList &L,int i,ElemType value){
if(i<1 || i>L.length+1){ //判断i的范围是否有效
return false;
}
if(L.length>=MAXSIZE){ //当前储存空间已满,不能插入
return false;
}
for(int j = L.length;j>=i;j--){ //将第i个元素及以后的元素后移
L.data[j] = L.data[j-1];
}
L.data[i-1] = value; //在i位置放入e
L.length++; //线性表长度加1
return true;
}
//删除
bool ListDelete(SqList &L,int i,ElemType &e){
if(i<1 || i>L.length){ //判断i的范围是否有效
return false;
}
e = L.data[i-1]; //将被删除的元素赋值给e
for(int j = i;j<L.length;j++){ //将第i个元素及以后的元素前移
L.data[j-1] = L.data[j];
}
L.length--; //线性表长度减1
return true;
}
//按值查找
int LocateElem(SqList L,ElemType e){
int i;
for(i=0;i<L.length;i++){
if(L.data[i] == e){
return i+1; //下标为i的元素值等于e,返回其序号i+1
}
}
return 0; //退出循环,说明查找失败
}
//按位查找
int LocateElem2(SqList &L,int i){
if(i<1||i>L.length){ //判断i的范围是否有效
return 0;
}
ElemType e = L.data[i-1]; //直接返回数据
return e;
}
//打印
void PrintList(SqList &L){
for(int i=0;i<L.length;i++){
cout<<L.data[i]<<" ";
}
cout<<endl;
}
int main(){
SqList L; //定义线性表
bool res; //返回结果值
ElemType del; //返回删除元素
L.data[0]=1; //数组初始化
L.data[1]=2;
L.data[2]=3;
L.length=3;
//输出数组
PrintList(L);
//在第二个位置插入值
res = ListInsert(L,2,20);
if(res){
cout<<"插入成功"<<endl;
PrintList(L);
}else{
cout<<"插入失败"<<endl;
PrintList(L);
}
//按值查找
cout<<"数组值为1所在位置为:";
cout<<LocateElem(L, 1)<<endl;
//按序号查找
cout<<"数组第一个元素为:";
cout<<LocateElem2(L, 1)<<endl;
//删除数组第二个元素
res = ListDelete(L,2,del);
if(res){
cout<<"删除成功"<<endl;
cout<<"删除元素为:"<<del<<endl;
PrintList(L);
}else{
cout<<"删除失败"<<endl;
PrintList(L);
}
return 0;
}