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;
}