数据结构之顺序列表(支持堆对象元素)(C++)

 

一、顺序列表 类模板实现

    1.以一维指针数组实现,存放对象元素;

    2.实现了动态内存分配;

        (注:更改了 void ObjArrayList<ElemType>::_AllocSpace(int size, int type) 函数的内存分配实现

                   将 malloc 和 realloc 替换成了 new 实现,使销毁对象数组内存时 delete 与 new 配对使用)

    3.实现了对象类的字符串输出(重载输出操作符)

//文件名:"ObjArrayList.h"
#pragma once
#ifndef ObjArrayList_H_
#define ObjArrayList_H_
#include <iostream>
using namespace std;

/*
.	对象顺序列表类 模板实现
*/
template <typename ElemType>
class ObjArrayList
{
private:
	ElemType **arr;	//指针的指针,一维列表指针
	int length;	//列表长度
	int size;	//列表大小
	const int DEFAULT_LENGTH = 10;	//默认长度
	const int INCREMENT_STEP = 10;	//增长步长
	void _AllocSpace(int size = 0, int type = 0);	//分配内存空间	0|malloc  1|realloc
	bool _IsFull();	//判断列表是否满
public:
	ObjArrayList();	//无参构造
	ObjArrayList(int m);	//有参构造
	~ObjArrayList();	//析构函数
	int Length();	//获取列表长度
	int Size();	//获取列表大小
	void Add(ElemType *e);	//顺序增加一个元素
	void Add(int i, ElemType *e);	//指定位置增加一个元素
	ElemType *Get(int i);	//获取指定位置元素
	friend ostream & operator << (ostream &out, ObjArrayList<ElemType> *list)
	{
		/*
		.	友元函数:重载输出操作符
		*/
		cout << "The List is : ";
		for (int i = 0; i < list->Length(); i++)
		{
			cout << i << "_";
			if (list->Get(i) != NULL)
				cout << list->Get(i);
			else
				cout << "(NULL) ";
			if (i != list->Length() - 1)
				cout << ",";
			if (i % 10 == 9)
				cout << endl;
		}
		return out;
	}
};

template <typename ElemType>
ObjArrayList<ElemType>::ObjArrayList()
{
	/*
	.	无参构造
	*/
	_AllocSpace(this->DEFAULT_LENGTH, 0);	//申请指针列表表空间:默认大小
	this->length = 0;
	this->size = this->DEFAULT_LENGTH;
}

template <typename ElemType>
ObjArrayList<ElemType>::ObjArrayList(int m)
{
	/*
	.	有参构造
	*/
	_AllocSpace(m, 0);	//申请指针列表表空间:m 大小
	this->length = 0;
	this->size = m;
}

template <typename ElemType>
ObjArrayList<ElemType>::~ObjArrayList()
{
	/*
	.	析构函数:销毁对象列表(同时销毁元素内存)
	*/
	if (this->arr == NULL)
	{
		return;
	}
	for (int i = 0; i < this->size; i++)
	{
		delete *(this->arr + i);
	}
	delete[] this->arr;
}

template <typename ElemType>
void ObjArrayList<ElemType>::_AllocSpace(int size, int type)
{
	/*
	.	分配内存空间
	.	参数: 
	.	int size: 列表大小(元素个数)
	.	int type: 0|malloc  1|realloc
	*/
	//新分配的内存起始地址索引
	int start = 0;
	//临时对象数组指针
	ElemType** p = NULL;
	//1.首次分配内存
	if (type == 0)
	{
		//this->arr = (ElemType **)malloc(size * sizeof(ElemType *));
		this->arr = new ElemType*[size];	//参考指针数组,保持 new 与 delete 配对
	}
	//2.重新分配内存
	else if (type == 1)
	{
		//this->arr = (ElemType **)realloc(this->arr, size * sizeof(ElemType *));
		//将原对象数组元素赋值到新数组中,并删除原数组
		p = this->arr;
		this->arr = new ElemType*[size];
		//1.迁移。注此时 this->size 还是原来的大小
		for (int i = 0; i < this->size; i++) {
			this->arr[i] = p[i];
		}
		//2.销毁原数组
		delete[] p;
		//空位起始地址
		start = this->length;
	}
	//3.初始化新分配内存元素为 NULL
	for (int i = start;	i < size; i++)
	{
		*(this->arr + i) = NULL;
	}
}

template <typename ElemType>
int ObjArrayList<ElemType>::Length()
{
	/*
	.	获取列表长度
	*/
	return this->length;
}

template <typename ElemType>
int ObjArrayList<ElemType>::Size()
{
	/*
	.	获取列表大小
	*/
	return this->size;
}

template <typename ElemType>
void ObjArrayList<ElemType>::Add(ElemType *e)
{
	/*
	.	顺序增加一个元素
	*/
	//重新分配空间大小
	int resize = 0;
	if (_IsFull())
	{
		//顺序增加一个默认步长大小的内存空间
		resize = this->size + this->INCREMENT_STEP;
		_AllocSpace(resize, 1);
		this->size = resize;
	}
	*(this->arr + this->length) = e;
	this->length++;
}

template <typename ElemType>
void ObjArrayList<ElemType>::Add(int i, ElemType *e)
{
	/*
	.	指定位置增加一个元素
	*/
	//重新分配空间大小
	int resize = 0;
	ElemType *p = NULL;
	//1.位置 i 在已有列表长度内
	if (i <= this->length - 1)
	{
		//若 i 位置已有元素,先销毁原数据内存,再添加新元素
		p = *(this->arr + i);
		if (p != NULL)
			delete p;
		*(this->arr + i) = e;
	}
	//2.位置 i 在已有列表长度外,但还在列表大小范围内
	else if (i <= this->size - 1)
	{
		*(this->arr + i) = e;
		this->length = i + 1;
	}
	//3.位置 i 在超出列表大小,需重新分配内存
	else
	{
		//按 内存增长步长的整数倍, 增加一段新内存
		resize = ((i + 1) / this->INCREMENT_STEP + 1) * this->INCREMENT_STEP;
		_AllocSpace(resize, 1);
		this->size = resize;
		*(this->arr + i) = e;
		this->length = i + 1;
	}
	
}

template <typename ElemType>
ElemType *ObjArrayList<ElemType>::Get(int i)
{
	/*
	.	获取指定位置元素
	*/
	return *(this->arr + i);
}

template <typename ElemType>
bool ObjArrayList<ElemType>::_IsFull()
{
	/*
	.	判断列表是否满
	*/
	return this->length == this->size ? true : false;
}

#endif // !ObjArrayList_H_

 

 

//文件名:"ObjArrayList_Test.cpp"
#include "stdafx.h"
#include <iostream>
#include "ObjArrayList.h"
using namespace std;

//元素
struct Element
{
	char a;
	int b;
public:
	friend ostream & operator <<(ostream& out, Element *p)
	{
		/*
		.	友元函数重载输出操作符,实现对象输出
		*/
		out << "(" << p->a << "," << p->b << ") ";
		return out;
	}
};

int main()
{
	//1.测试对象输出
	cout << "------------------------------------------------" << endl;
	Element *e = new Element{ 'A',1 };
	cout << "对象:" << e << endl;
	//2.测试 对象顺序表 
	cout << endl << "------------------------------------------------" << endl;
	//2.1.列表大小 15 内 增加元素测试
	ObjArrayList<Element> *list = new ObjArrayList<Element>(15);
	list->Add(0, new Element{ 'A',1 });
	list->Add(1, new Element{ 'B',2 });
	list->Add(2, new Element{ 'C',3 });
	list->Add(3, NULL);
	list->Add(4, NULL);
	list->Add(5, new Element{ 'D',4 });
	list->Add(6, new Element{ 'E',5 });
	list->Add(7, NULL);
	list->Add(8, new Element{ 'G',7 });
	list->Add(9, NULL);
	list->Add(10, NULL);
	list->Add(11, new Element{ 'F',6 });
	list->Add(12, NULL);
	list->Add(13, NULL);
	list->Add(14, NULL);
	cout << "数据元素 0:" << list->Get(0) << endl;
	cout << "列表长度:" << list->Length() << " ;列表大小:" << list->Size() << endl;
	cout << "列表输出:" << list << endl;	//测试 对象表 输出
	//2.2.列表大小 15 外 扩展测试
	list->Add(31, NULL);
	list->Add(30, new Element{ 'M',6 });
	cout << "列表长度:" << list->Length() << " ;列表大小:" << list->Size() << endl;
	cout << "列表输出:" << list << endl;	//测试 对象表 输出
	
        delete list;

	return 0;
}

 

 

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值