学习笔记:1.顺序表的实现和代码

顺序表

前言

自己学习数据结构的笔记,看的是王道的视频,自己写了源代码在最下面,有详细的注释,可以直接跑。(要保存成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"); 
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值