顺序表(c++)

顺序表(c++)

1.构建一个顺序表

1.1结构定义

1.顺序表也就是一片连续的内存空间,包括了总大小,当前顺序表中的个数,以及小格子要存储的数据类型
2.这一片内存空间中又开辟了n(可以自己指定)个小空间
3.每一个小空间中包含了这个空间所存储的值

typedef struct RankList{
    int* data;  // 是顺序表中小格子里存储的内容,在此全部为Int类型,因为顺序表是连续的存储空间,所以只要传入一个首地址即可,使用指针
    int length; //当前顺序表的长度
    int max_size; // 可存储的最大长度
}RankList;  // 最后是命名,前面struct后面加不加都可以,我习惯加上

在这里插入图片描述

1.2 初始化

​ 1.上面仅仅只是一个定义,并没有什么实质性的动作

​ 2.这一步就是在内存中申请空间,并返回空间的首地址

​ 3.并对结构定义中的当前顺序表的长度进行初始化为0,最大长度为100

在这里插入图片描述

int init_list(RankList &ran,int n){  //传入的是顺序表的引用和顺序表的最大长度,传入引用表示直接操作真实的顺序表
    ran.data = new int[n]; // 这句话的意思是在堆区开辟一个大小为[(int所占空间)*n]大小的空间,并返回开辟空间的头部,new表示的是在堆区开辟空间,利用new创建的数据,会返回该数据对应的类型的指针
    if(!ran.data)  return -1;  // 表示的是如果开辟完后首地址为空时,表示开辟失败,返回-1
    ran.length = 0;
    ran.max_size = n;  //初始化
    return 0;
} // 初始化表示已经在内存中开辟了一个空的顺序表
1.3 销毁

在这里插入图片描述

​ 因为是在堆区开辟的内存,在堆区的空间是要由自己手动释放的

void clear(RankList &ran){
    if(ran.data){
        delete[] ran.data;  //删除堆区数组的格式,delete[] arr; 其中arr是开辟时接收返回的指针的变量
    }
}
1.4结构操作

​ 只有最基础的插入和删除操作

1.4.1 插入

在这里插入图片描述

​ 1.插入,顾名思义表示的格式是在顺序表的某个位置,插入某一个值,所以传入的参数有三个

​ 2.插入条件,插入时要先判断插入的位置是否合法,前提是允许插在顺序表的头部和尾部

​ 2.1 插入的位置(index)不能小于0,索引是从0开始的

​ 2.2 插入的位置不能大于目前顺序表的长度,但可以等于(相当于插在尾部)

​ 2.3 还要判断插入时目前长度是否大于顺序表的最大长度

	3. 具体操作,从要插入的索引开始,其后的所有元素全部向后移动一位,并要注意只能从后向前进行移动
	4. 插入一次后顺序表的长度就加1
int insert(RankList &ran,int index,int val){
    if(index<0 || index>ran.length) return -1;  // 返回-1表示不合法
    if(ran.length == ran.max_size)  return -1;  // 若当前长度等于最大长度是就不再允许插入
    /*
    接下来是插入的具体操作:
    	使用一个for循环从最后面开始倒着进行循环,还没有进行插入操作时的最后一个元素的值的索引是ran.length-1,所以插入后的最后一个元素的索引就是ran.length,所以令i = ran.length,一直循环到最后i = index+1 ,就可以将index之后的所有值向后移动了一个单位
    */
    for(int i=ran.length; i>index; i--){
        ran.data[i] = ran.data[i-1];
    }
    ran.data[index] = val; //循环向后移动完成之后,此时索引为传入的index的地方就相当于空了出来,就可以直接赋值了
    ran.length++;  // 别忘了长度要加1
    return 0;
}
1.4.2 删除

​ 1.与插入进行比较呢删除是比较容易的,只需传入要操作的顺序表和要删除的索引值即可

​ 2.同样也要判断传进来的索引值是否合法,大致与插入相同

​ 3.删除顺序表中的某一个值,其他的值也要跟着移动才行,此时移动是向前的,所以此次循环是由前向后进行循环的

在这里插入图片描述

int delete_list(RankList &ran,int index){
	if(index < 0 ||index>= ran.length) return -1;  //注意,此时index 不能等于顺序表的长度,如果等于就不合法
	for(int i=index;i< ran.length-1;i++){ // 重点理解为什么i<ran.length-1 ,因为向前移动时的最后一步操作一定是
//ran.data[ran.length-2] = ran.data[ran.length-1],所以i最后等于ran.length-2时已经完成了循环操作,所以i<ran.length-1
		ran.data[i] = ran.data[i+1];
	}
	ran.length--; // 别忘了长度要减1
	return 0;
}
1.5进行展示

​ 展示就非常简单了,仅仅一个for循环就可以搞定

void display(RankList ran){
	cout<<"rand1["<<ran.length<<"]"<<": ";
	for(int i=0;i<ran.length;i++){
		cout<<ran.data[i]<<" ";
	}
	cout<<endl;
} // 输出的格式为 (顺序表的名称[长度]:后面是用空格分开的值)
1.6测试

在main函数里进行批量的插入与删除,进行测试

在这里插入图片描述

#define MAX_SIZE 30 
int main(){
	RankList ran1;  //定义一个顺序表变量 
	init_list(ran1,MAX_SIZE); //进行初始化,创建一个可存放自定义数据类型个数为30的空顺序表 
	srand(time(0)); //用于刷新数据
	cout<<"start:"<<endl; 
	for(int i=0;i<MAX_SIZE;i++){
		int ind = rand() % (ran1.length + 1);  //产生的索引值是对(目前所存顺序表长度+1)进行取余,是因为插入时可以为长度,同时也避免当长度为0
		//时报错的问题  
		int val = rand() % 100; // 插入的值为100以内 
		int op = rand() % 4; // 这个是用于判断是插入还是删除操作
		switch(op){
			//意思就是当op = 0,1,2 时进行插入操作,当op = 3时进行删除操作 ,这样插入的概率就为3/4,删除的概率为1/4 
			case 0: {

					cout<<"插入 "<<val<<" 在 "<<"index = "<<ind<<endl;
					insert(ran1,ind,val); 
					break;
			}
			case 1: {
					cout<<"插入 "<<val<<" 在 "<<"index = "<<ind<<endl;
					insert(ran1,ind,val); 
					break;
			}
			case 2: {
					cout<<"插入 "<<val<<" 在 "<<"index = "<<ind<<endl;
					insert(ran1,ind,val); 
					break;
			}
			case 3: {
				cout<<"删除 index = "<<ind<<endl;
				delete_list(ran1,ind);
				break;
			}
		} 

		display(ran1); //每进行一次操作都展示一次 
	}

	return 0;
}

1.7 测试结果

仅仅只是截取了一部分测试结果,这样展示出来时没有错误的
在这里插入图片描述

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
用模板方式实现顺序的合并 #include "stdafx.h" #include #define MaxSize 100 template class SeqList { private: T * Mylist; int ListMaxSize; int Length; public: SeqList(int ListMaxSize=MaxSize); //构造函数 ~SeqList(void);// 析构函数 bool SLIsEmpty(void); // 判断是否为空 bool SLIsFull(void);//判断是否满 int ListLength(void){return Length;}//求长度 T SLGetElem(int i); // 取得第i个元素的值 int SLFind(T & x,int index); //查找值为x的结点 bool SLInsert(int i,T & x); // 在的第i个位置插入新结点 bool SLDelete(int i); // 删除的第i个位置的结点 void CreateList(int num);// 创建一个包含num个元素的顺序 void SLPrint(); //输出全体元素 }; template SeqList ::SeqList(int listMaxSize) //初始化顺序 { if(listMaxSize>0){ ListMaxSize=listMaxSize; Length=0; Mylist=new T [ListMaxSize]; // 创建连续的空间 } } template SeqList ::~SeqList(void) { delete [] Mylist;//删除,释放空间 } template void SeqList ::CreateList(int num) { T x; Length=0; cout << "请输入"<<num<<"个整数数据元素以创建一个线性"<<endl; for (int i=0;i>x; Mylist[i]=x; Length++; } } template bool SeqList ::SLIsEmpty(void) // 判断是否为空 { return (Length<=0)?true:false; //空则返回真(true),否则返回假(false) } template bool SeqList ::SLIsFull(void)//判断是否满 { return(Length>=ListMaxSize)?true:false; //满则返回真(true),否则返回假(false) } template T SeqList ::SLGetElem(int i) // 取得第i个元素的值 { return(iLength-1)?-1:Mylist[i]; } template int SeqList ::SLFind(T & x,int index) //查找值为x的结点 { for(int i=0;i<index;i++) if(Mylist[i]==x) return i+1; return -1;//没有找到给定元素 } template bool SeqList ::SLInsert(int i,T & x) // 在的第i个位置插入新结点 { if(iLength) {cout <<"参数i不合理!" <<endl; return false;} else if(Length==ListMaxSize) {cout<< "已满,无法插入!"<i;j--) Mylist[j]=Mylist[j-1]; Mylist[j]=x; Length++; return true; } } template <clas
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值