数据结构-动态数组

数据结构-动态数组

在C中所有的数组大小都是固定的,在未知数据大小的情况下不方便提前设置数组大小,所以采用一种动态数组的方式;
个人感觉:所谓动态数组便是使用2级指针,并且使用这个2级指针所存储的空间充当数组去存储数据的指针,并且不断的申请与析构,拷贝复制去满足存储未知的数据;
先上使用C++封装的动态数组代码
头文件:

class DynamicClass
{
public:
	DynamicClass();
	~DynamicClass();
	//创建动态数组  参数为需要传入的动态数组大小
	void CreateDyanmicVec( int dynamicMaxSize);
	//添加数据, 参数为数据和位置
	void PushBackDynamicVec(void * data,int pos);
	//遍历数组,传入一个函数指针,交由别处针对数据进行打印验证
	void ErgodicityDynamicVec(void(*CountData)(void * data));
	//按照位置删除数据
	void EraseDynamicVec(int pos);
	//按照数据删除数据,提供函数指针交由别处判断两组数据是否相等
	void EraseDynamicVec(void * Data, bool(*EqualityData)(void * data, void * data2));
	//清理动态数组,这个位置如果该类对象声明的时候完成的是深拷贝,则可以写入到析构函数中等待最后在进行析构,这里有些懒,也为了方便步骤,没有进行深拷贝的构造函数,单独写在了这个位置
	void ClearDynamicVec();
private:
	//动态数组
	void ** _DynamicVec;
	//数组最大值
	int _DynamicVecMaxSize;
	//当前数组位置
	int _DynamicVecPos;

};

CPP:

#include "DynamicClass.h"
#include <stdlib.h>
#include <wchar.h>
DynamicClass::DynamicClass()
{
	_DynamicVec =0;
	_DynamicVecMaxSize = 0;
	_DynamicVecPos = 0;
}


DynamicClass::~DynamicClass()
{

}

void DynamicClass::CreateDyanmicVec(int dynamicMaxSize)
{
	if (dynamicMaxSize == 0)
	{
		return;
	}
	void ** Vec = static_cast<void **>(malloc(sizeof(void *)*dynamicMaxSize));
	if (Vec)
	{
		_DynamicVec = Vec;
		_DynamicVecMaxSize = dynamicMaxSize;
	
	}
	
}

void DynamicClass::PushBackDynamicVec(void * data, int pos)
{
	//如果数据为空则推出
	if (data == NULL)
	{
		return;
	}
	//如果数组为空则推出
	if (_DynamicVec == NULL)
	{
		return;
	}
	//存储是否已经为最后一位,如果已经存储到数组的最大个数,则证明需要开辟空间
	if (_DynamicVecMaxSize <= _DynamicVecPos)
	{
		int DynamicVecMaxSize = _DynamicVecMaxSize * 2;
		void ** D = static_cast<void **>(malloc(sizeof(void*)*DynamicVecMaxSize));
		if (D)
		{
			_DynamicVecMaxSize = DynamicVecMaxSize;
			memcpy(D,_DynamicVec,sizeof(void *)*_DynamicVecPos);
			free(_DynamicVec);
			_DynamicVec = D;
		}
	}
	//如果数组为空则推出
	if (_DynamicVec == NULL)
	{
		return;
	}
	//数据存储位置检查 如果大于当前存储位置的最大值并且小于当前数组的最大值,则末端插入
	if (pos>_DynamicVecPos&&pos<_DynamicVecMaxSize)
	{
		pos = _DynamicVecPos + 1;
	}
	//从末端开始后移,直至后移到pos位置空出
	for (int i = _DynamicVecPos-1; i >= pos; i--)
	{
		_DynamicVec[i + 1] = _DynamicVec[i];
	}

#if 1
	_DynamicVec[pos] = data;
#else
	//此处原本想要考虑一种可以存储局部变量的方法,但暂时未想到解决办法
	memcpy(_DynamicVec[pos], data, sizeof(data));
#endif


	_DynamicVecPos = _DynamicVecPos + 1;
}

void DynamicClass::ErgodicityDynamicVec(void(*CountData)(void * data))
{
	//从末端开始后移,直至后移到pos位置空出
	for (int i = 0; i < _DynamicVecPos; i++)
	{
		void * CData = _DynamicVec[i];
		CountData(CData);
	}

}

void DynamicClass::EraseDynamicVec(int pos)
{
	//如果数组为空则推出
	if (_DynamicVec == NULL)
	{
		return;
	}
	//如果大于当前存储值则退出
	if (pos>_DynamicVecPos)
	{
		return;
	}
	//从pos位置开始,向前覆盖,此处不可以析构,因为空间在数组中
	for (int i = pos; i < _DynamicVecPos; i++)
	{
		_DynamicVec[i] = _DynamicVec[i + 1];
	}
	_DynamicVecPos = _DynamicVecPos - 1;
}

void DynamicClass::EraseDynamicVec(void * Data, bool(*EqualityData)(void * data, void * data2))
{
	//如果数组为空则推出
	if (_DynamicVec == NULL)
	{
		return;
	}
	if (Data == NULL)
	{
		return;
	}
	for (int i = 0; i < _DynamicVecPos;i++)
	{
		if (EqualityData(_DynamicVec[i],Data))
		{
			EraseDynamicVec(i);
			return;
		}
	}
}

void DynamicClass::ClearDynamicVec()
{
	if (_DynamicVec)
	{
		free(_DynamicVec);
		_DynamicVec = NULL;
	}
}

在上测试数据:

#pragma once
#include <iostream>
#include <string>
class DynamicTextStr
{
public:
	DynamicTextStr();
	DynamicTextStr(std::string Name, int Number);
	~DynamicTextStr();

	static void CountData(void * data);
	static bool EqualityData(void * data, void * data2);
	std::string _Name;
	int _Number;

};


测试数据类实现

#include "DynamicTextStr.h"


DynamicTextStr::DynamicTextStr()
{
}


DynamicTextStr::DynamicTextStr(std::string Name, int Number)
{
	_Name = Name;
	_Number = Number;
}

DynamicTextStr::~DynamicTextStr()
{
}

void DynamicTextStr::CountData(void * data)
{
	if (DynamicTextStr *TextStr = static_cast<DynamicTextStr *>(data))
	{
		std::cout << "Name :" << TextStr->_Name << "  Number :" << TextStr->_Number << std::endl;
	}
}

bool DynamicTextStr::EqualityData(void * data, void * data2)
{
	if (DynamicTextStr *TextStr = static_cast<DynamicTextStr *>(data))
	{
		if (DynamicTextStr *TextStr1 = static_cast<DynamicTextStr *>(data2))
		{
			if (TextStr->_Name == TextStr1->_Name)
			{
				if (TextStr->_Number == TextStr1->_Number)
				{

					return true;
				}

			}
		}
	}
	return false;
}

main函数


#include <QtCore/QCoreApplication>
#include "DynamicClass.h"
#include "DynamicTextStr.h"

int main(int argc, char *argv[])
{
	
	


	DynamicClass TextClass;
	//先设置为三个,方便测试第四个的数据添加
	TextClass.CreateDyanmicVec(3);
	DynamicTextStr Str1 = DynamicTextStr("张三", 13);
	DynamicTextStr Str2 = DynamicTextStr("李四", 14);

	DynamicTextStr Str3 = DynamicTextStr("王五", 15);
	DynamicTextStr Str4 = DynamicTextStr("麻溜", 16);
	TextClass.PushBackDynamicVec(&Str1, 0);
	TextClass.PushBackDynamicVec(&Str2, 0);
	TextClass.PushBackDynamicVec(&Str3, 0);
	TextClass.PushBackDynamicVec(&Str4, 0);

	TextClass.ErgodicityDynamicVec(DynamicTextStr::CountData);
	std::cout << "------------------------ " << std::endl;
	TextClass.EraseDynamicVec(0);
	TextClass.EraseDynamicVec(&Str2, DynamicTextStr::EqualityData);
	TextClass.ErgodicityDynamicVec(DynamicTextStr::CountData);
	std::cout << "------------------------ " << std::endl;
	TextClass.ClearDynamicVec();

}

运行结果
在这里插入图片描述
补充:
动态数组用于C++实现,仔细观察main函数以发现必须使得所存储的数据为全局变量,对象存储后不可以发生析构,否则在打印的时候会出现问题;
所以可以进行一些优化与完善;当然在已知数据类型的情况下可以完善并且解决,但在未知的情况下,就需要与其他相互配合了;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值