顺序表
前言
自己学习数据结构的笔记,看的是王道的视频,自己写了源代码在最下面,有详细的注释,可以直接跑。(要保存成c++文件)
一、顺序表的定义
1.静态分配
使用数组存储线性表中的元素,当线性表满后,无法扩充大小
#define MaxSize 10 //定义线性表的最大长度
typedef struct{
int data[MaxSize]; //用静态数组存放数据元素
int length; //顺序表的当前长度
}SqList;
2.动态分配
使用malloc函数动态分配内存空间
#define InitSize //表初始长度
typedef struct{
int *data; //动态分配数组的指针
int length; //顺序表当前长度
int Maxsize; //顺序表的最大容量
}SqList;
L.data = (int *)malloc(sizeof(int));//动态开辟内存空间
增加动态数组的长度
void IncreaseSize(SqList &L,int len){
//1.扩大线性表容量
int *p = L.data; //将data指针的值赋给p,两者指向相同位置
L.data = (int *)malloc((L.Maxsize + len)*sizeof(int)); //开辟新的内存空间,并让data指针指向该区域
//2.将原来的数据复制到新的内存空间
for(int i=0;i<L.length,i++)
L.data[i] = p[i];
//3.顺序表最大长度增加len
L.Maxsize = L.Maxsize + len;
//4.释放原来的内存空间
free(p)
}
二、顺序表的插入和删除
1.插入操作
//在位序i的位置插入元素e
bool ListInsert(SqList &L ,int i,int e){
//1.判断插入位置i是否合法
if(i>(L.length+1) || i<1){
printf("元素%d插入失败!\n",e);
return false;
}
//2.判断线性表是否已满
if(L.length >= L.Maxsize){
printf("元素%d插入失败!\n",e);
return false;
}
//3.进行插入操作
for(int j = L.length;j >= i;j--)
L.data[j] = L.data[j-1];
//4.i后元素后移一位
L.data[i-1] = e;
//5.线性表表长加一
L.length++;
printf("元素%d插入成功\n",e);
return true;
}
2.删除操作
//删除位序i个位置上的元素,并用e返回被删除的值
bool ListDelete(SqList &L ,int i,int &e)
{
//1.判断i的值是否合法
if(i>L.length || i<1){
printf("删除失败!\n");
return false;
}
//2.用e接收被删除元素的值
e = L.data[i-1];
//3.进行删除操作,使位序i后的元素前移一位
for(int j = i;j < L.length-1;j++)
L.data[j-1] = L.data[j];
//4.线性表表长减一
L.length--;
printf("元素%d删除成功!",e);
return true;
}
三、顺序表的查找
1.按值查找
//按值查找,找到第一个值为e的元素,并返回其位序
int LocateElem(SqList L,int e){
//循环查找
for(int i = 0;i < L.length;i++){
if(L.data[i] == e)
return i+1;
}
return 0;
}
2.按位查找
//按位查找,返回位序i的元素的值
int GetElem(SqList L,int i)
{
//1.判断i的值是否合法
if((i>((L.length)+1) || i<1)){
printf("返回失败!\n");
return -1;
}
//2.返回位序为i的元素的值
return L.data[i-1];
}
四、顺序表的特点
1.随机存取:可以通过首地址和元素序号在O(1)的时间复杂度内找到指定的元素。
2.存储密度高,每个节点只存储数据元素。
3.拓展容量不方便。
4.进行插入删除操作不方便,需要移动大量元素。
五、注意事项
1.对参数的修改结果需要返回时使用引用类型&。
2.用malloc函数开辟动态内存空间时需要强制类型转换。
3.初始化线性表是为了防止内存中遗留的脏数据。
4.C语言中,不能直接使用"=="来判断两个结构体相等。
六、源代码
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
/*静态分配
#define MaxSize 10
typedef struct{
int data[MaxSize];
int length;
}SqList;
*/
//动态分配
typedef struct{
int *data; //动态分配数组的指针
int length; //顺序表当前长度
int Maxsize; //顺序表的最大容量
}SqList;
//函数声明
void InitList(SqList &L); //顺序表初始化
void IncreaseSize(SqList &L,int len); //增加动态数组的长度
bool ListEmpty(SqList L); //判空
bool ListInsert(SqList &L,int i,int e); //插入操作
bool ListDelete(SqList &L,int i,int &e); //删除操作
int ListLength(SqList L); //求顺序表表长
int GetElem(SqList L,int i); //按位查找
int LocateElem(SqList L,int e); //按值查找
void ListTraverse(SqList L); //遍历顺序表
//
//主函数
int main(){
SqList L;
InitList(L);
ListInsert(L,1,1);
ListInsert(L,2,2);
ListInsert(L,3,3);
ListInsert(L,4,4);
ListInsert(L,5,5);
ListTraverse(L);
int val = 0;//接收删除操作的返回值
ListDelete(L,3,val);
ListLength(L);
ListTraverse(L);
GetElem(L,5);
printf("按位查找的结果为:%d",LocateElem(L,4));
return 0;
}
//初始化顺序表
void InitList(SqList &L){
//1.输入顺序表大小
int num;
printf("请输入顺序表存储容量: ");
scanf("%d",&num);
//2.为顺序表动态开辟内存空间;
L.data=(int *)malloc(num*sizeof(int));
//3.初始化操作
L.length = 0;
L.Maxsize = num;
printf("顺序表创建成功!\n");
return;
}
//增加动态数组的长度
void IncreaseSize(SqList &L,int len){
//1.扩大顺序表容量
int *p = L.data; //创建p指针指向L
L.data = (int *)malloc((L.Maxsize + len)*sizeof(int)); //开辟新的内存空间
//2.将原来的数据复制到新的内存空间
for(int i=0;i<L.length;i++)
L.data[i] = p[i];
//3.顺序表最大长度增加len
L.Maxsize = L.Maxsize + len;
//4.释放原来的内存空间
free(p);
return;
}
//判断顺序表是否为空
bool ListEmpty(SqList L){
if(L.length==0){
printf("顺序表为空\n");
return true;
}
else{
printf("顺序表不为空\n");
return false;
}
}
//返回L中数据元素的个数
int ListLength(SqList L){
printf("线性表表长为:%d\n",L.length);
return (L.length);
}
//在位序i的位置插入元素e
bool ListInsert(SqList &L ,int i,int e){
//1.判断插入位置i是否合法
if(i>(L.length+1) || i<1){
printf("位序不合法,元素%d插入失败!\n",e);
return false;
}
//2.判断顺序表是否已满
if(L.length >= L.Maxsize){
printf("顺序表已满,元素%d插入失败!\n",e);
return false;
}
//3.进行插入操作
for(int j = L.length;j >= i;j--)
L.data[j] = L.data[j-1];
//4.i后元素后移一位
L.data[i-1] = e;
//5.顺序表表长加一
L.length++;
printf("元素%d插入成功\n",e);
return true;
}
//删除位序i位置上的元素,并用e返回被删除的值
bool ListDelete(SqList &L ,int i,int &e)
{
//1.判断i的值是否合法
if(i>L.length || i<1){
printf("删除失败!\n");
return false;
}
//2.用e接收被删除元素的值
e = L.data[i-1];
//3.进行删除操作,使位序i后的元素前移一位
for(int j = i;j < L.length;j++)
L.data[j-1] = L.data[j];
//4.顺序表表长减一
L.length--;
printf("已删除位序为%d的元素,删除元素的值为:%d\n",i,e);
return true;
}
//按位查找,返回位序i的元素的值
int GetElem(SqList L,int i){
//1.判断i的值是否合法
if((i>((L.length)+1) || i<1)){
printf("返回失败!\n");
return -1;
}
//2.返回位序为i的元素的值
printf("按位查找结果为:%d\n",L.data[i-1]);
return L.data[i-1];
}
//按值查找,找到第一个值为e的元素,并返回其位序
int LocateElem(SqList L,int e){
//循环查找
for( int i = 0;i < L.length;i++){
if(L.data[i] == e)
return i+1;
}
return -1;
}
//顺序表的遍历
void ListTraverse(SqList L){
printf("================\n");
printf("顺序表的遍历结果为:\n");
for(int i=0; i<L.length;i++)
printf("%d ",L.data[i]);
printf("\n");
ListLength(L);
printf("================\n");
}