c++ 顺序表 实现 可动态分配内存

c++ 顺序表 实现 可动态分配内存

有的步骤可能重复,也可以将有的步骤封装,可能会更简洁

如果那一步有问题(出现bug) ,或者那一步太繁琐,希望大神指出,十分感谢
或者 有哪些步骤 看不懂,欢迎来找我交流,我们共同进步

#include<stdio.h>
#include<iostream>
#include<memory>  //sh
using namespace std;
constexpr int MAXSIZE = 10;

struct seqList
{
	int date[MAXSIZE];
	int List_size;  //数据元素个数

	int* date_two;   //用于扩展 数据元素 在超过下标后
	int  Two_Size;   //用于记录在堆区 的元素的个数 
};

//如果是 非 内置数据类型 就需要提供 每个数据元素 的 初始化方式 
//如果是 则都符一个除值
//初始化 该顺序表   初始化 为 空表
void init_Seq_List(seqList&  L)
{
	L.List_size = 0;    //数据元素个数为零   
	L.date_two = NULL;
	L.Two_Size = 0;
	//遍历
	for (int i = 0; i < MAXSIZE; i++)
		L.date[i] = 0;
		
	cout << "初始化成功" << endl;
}

//判断是否越界
bool Cross_Size(seqList& L)
{
	if (L.List_size < MAXSIZE)
		return true;
	else
		return false;
}

bool Freed(seqList& L);
//尾部插入
bool Tail_Insert_List(seqList& L,int i)
{
	if (Cross_Size(L))
	{	
		L.date[(++L.List_size) - 1] = i;
		cout << "插入成功" << endl;
		return true;
	}
	else if(!Cross_Size(L)) {   
		
		if (L.date_two == NULL)
		{
			L.Two_Size++;
			L.date_two = new int(i);  //多开辟两个空间
		}
		else {
			L.Two_Size++;
			int* ptr = new int[L.Two_Size];
			for (int j = 0; j < L.Two_Size-1; j++)  //将date_two 里边的数据复制一份 给 ptr
				ptr[j] =L.date_two[j];
			ptr[L.Two_Size - 1] = i;
			//释放date_two 里边的数据,
			int* p = L.date_two;
			delete[] p;
			p = NULL;
			L.date_two = NULL;		
			/*
					//delete[] L.date_two;
					//Freed(L);  
					这样直接释放释放原来堆区开辟的内存 会导致 程序直接崩溃
					崩溃原因是 继续使用了 已经 delete 的指针

			*/
			L.date_two = ptr;
			cout << "插入堆区数据成功" << endl;
			return true;
		}
	}
	
	return false;
}

//插入 数据元素  在指定位置插入
/*
	思路:
		两种情况:
			1)插入到数组 date 中
				两种情况:
					1> 插入后顺序表的元素 仍然 小于等于 MAXSIZE
					2> 插入后顺序表的元素个数 大于 MAXSIZE(这是 数组的最大承载量)
					
			2)插入到堆区开辟的空间
*/

bool Insert_Date(seqList& L,int index,int date)    //插入位置:index ,插入对象: date 
{
	
	// 1)插入到数组 date 中
	if (index >= 0 && index <= L.List_size-1 ) //这个情况是插入到数组中
	{
		//1> 插入后顺序表的元素 仍然 小于等于 MAXSIZE
		if (L.List_size < MAXSIZE)
		{
			//首先将顺序表长度加一
			L.List_size++;
			//然后将要插入的数据元素的位置的后边的元素都往后挪
			for (int i = L.List_size - 1; i >= index; i--)
				L.date[i] = L.date[i - 1];
			L.date[index] = date;
			cout << "插入成功" << endl;
			return true;
		}
		//2 > 插入后顺序表的元素个数 大于 MAXSIZE
		else if(L.List_size == MAXSIZE )   //会让原本 在date数组中的数据元素 被挤出去 到 堆区date_two
		{
			//先判断 Two_Size 是否为 0,
			//如果是0 则 直接 尾插
			if (L.date_two == 0)
				Tail_Insert_List(L, L.date[L.List_size - 1]);
			else
			{
				L.Two_Size++;//堆区数据 个数增加
				int* ptr = new int[L.Two_Size];
				for (int j = 0; j < L.Two_Size - 1; j++)  
					ptr[j + 1] = L.date_two[j];
				ptr[0] = L.date[L.List_size - 1];
				for (int i = L.List_size - 1; i > index; i--)
					L.date[i] = L.date[i - 1];
				L.date[index] = date;
				//释放date_two 里边的数据,
				int* p = L.date_two;
				delete[] p;
				p = NULL;
				L.date_two = NULL;

				L.date_two = ptr;
			}
			return true;
		}
	}
	//2)插入到堆区开辟的空间
	else if (index >=L.List_size  && index <= L.List_size + L.Two_Size)//插入到 --date_two  
	{
		L.Two_Size++;
		int* ptr = new int[L.Two_Size];
		//复制index 之前的元素
		for (int i = index-L.List_size; i >= 0; i--)
			ptr[i] = L.date_two[i];
		//复制index 之后的元素
		for (int i = L.Two_Size - 1; i > index-L.List_size; i--)
			ptr[i] = L.date_two[i - 1];
		ptr[index-L.List_size] = date;
		
		int* p = L.date_two;
		delete[] p;
		p = NULL;
		L.date_two = NULL;

		L.date_two = ptr;
		return true;
	}
	else
		cout << "插入位置不在可插入范围内,插入失败" << endl;
	return false;
}

//索引 函数      
void Check_Date(seqList& L, int index)
{
	if (index >= 0 && index <= L.List_size - 1)  //索引栈区的元素 
		cout << "Date[" << index << "] = " << L.date[index] << endl;
	else if (index >= L.List_size && index <= L.Two_Size+L.List_size-1)  //索引堆区的元素
		cout << "Date[" << index << "] = " << L.date_two[index - L.List_size] << endl;
	else
		cout << "索引值无效" << endl;
}

//删除 数据元素 
/*
	两种情况 
	1、删除的是数组 中的元素 
		两种情况:
			1)堆区数据为空
			2)堆区数据不为空
				先移动 栈取数据 在挪动 堆区数据
	2、删除 的堆区数据
	3、索引值 越界 
*/

void Delete_Date(seqList& L,int index) //索引 删除的 元素:index
{
	int a = 0;
	//1、删除的是数组 中的元素
	if (index >= 0 && index <= L.List_size - 1)//删除  栈区 数组 
	{
		//1)堆区数据为空
		if (L.Two_Size == 0)  //通过
		{
			for (int i = index; i <= L.List_size - 2; i++)
				L.date[i] = L.date[i + 1];
			L.List_size--;
		}
		//2)堆区数据不为空
		else{					   
			//移动 栈区数据
			for (int i = index; i <= L.List_size - 2; i++)
				L.date[i] = L.date[i + 1];
			//将堆区第一个数据 补上来
			L.date[L.List_size - 1] = L.date_two[0];
			for (int i = 0; i < L.Two_Size - 1; i++)
				L.date_two[i] = L.date_two[i + 1];
			L.Two_Size--;
		}
	}
	
	//2、删除 的堆区数据           
	else if (index >= L.List_size && index <= L.List_size + L.Two_Size - 1)
	{
		for(int i= index - L.List_size ; i < L.Two_Size-1 ; i++ )
			L.date_two[i] = L.date_two[i + 1];
		L.Two_Size--;
	}
	//3、索引值越界 
	else {
		cout << "索引无效,删除失败 " << endl;
	}
	
}
//修改顺序表的值
bool Revise_Date(seqList& L,int index,int date)
{
	if (index >= 0 && index <= L.List_size - 1)
	{
		L.date[index] = date;
		return true;
	}
	else if (index >= L.List_size && index <= L.List_size + L.Two_Size - 1)
	{
		L.date_two[index - L.List_size] = date;
		return true;
	}
	else
	{
		cout << "索引值错误,修改失败" << endl;
		return false;
	}
}
//显示顺序表的所有元素
void Show_List(seqList& L)
{
	for (int i = 0; i < L.List_size+L.Two_Size; i++)
		Check_Date(L, i);
	cout << "顺序表的元素个数:" << L.List_size+L.Two_Size << endl;
}
//显示该顺序表的最大数据容纳数
void Show_Max_size()
{
	cout << "该顺序表最大可承载的数据元素数:" << MAXSIZE << endl;
}

//释放在堆区开辟的空间
bool Freed(seqList& L)
{
	if (L.date_two == NULL)
	{
		cout << "并没有在堆区开辟空间,所以释放失败" << endl;
		return false;
	}
	delete[] L.date_two;
	L.date_two = NULL;
	return true;
}

int main()
{
	seqList L ;    
	init_Seq_List(L);
	Tail_Insert_List(L, 1);
	Tail_Insert_List(L, 2);
	Tail_Insert_List(L, 3);
	Tail_Insert_List(L, 4);
	Insert_Date(L, 0, 1000);
	Tail_Insert_List(L, 5);
	
	Tail_Insert_List(L, 6);
	Tail_Insert_List(L, 7);
	Tail_Insert_List(L, 8);
	Tail_Insert_List(L, 9);
	Tail_Insert_List(L, 10);  
	
	Tail_Insert_List(L, 11); 
	Insert_Date(L, 4, 1000);//插入到顺序表的 第五个

	Delete_Date(L, 0);   
	Delete_Date(L, 9);
	
	Revise_Date(L, 4, 5);
	/*Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);

	Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);
	Tail_Insert_List(L, 10000);

	Tail_Insert_List(L, 10000);
	Insert_Date(L, 10, 1);
	Insert_Date(L, 10, 2);
	Insert_Date(L, 20, 3);
	Tail_Insert_List(L, 10000);
	Insert_Date(L, 23, 3);
	Delete_Date(L, 0);*/
	
	Show_List(L);
	Freed(L);   //释放在堆区 开辟的 内存 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奥特神龟3.1.4

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值