使用C++面向对象思想,分别用数组和链栈实现数据结构增删改查和排序(数组篇)。

该文描述了一个C++的面向对象项目,目标是创建一个可动态修改的容器,支持添加、删除、修改和获取元素等操作。项目通过接口类`QFMutableContainer`为数组和双链表版本的容器提供统一的API,`QFMutableArray`实现了基于数组的容器,提供了如添加、删除、排序等方法。文章还展示了`QFMutableArray`类的部分实现代码及其在主函数中的测试用例。
摘要由CSDN通过智能技术生成


/*
面向对象项目:
项目目标:
实现动态可变的数据容器。

项目描述:
我们希望能够做一个能动态修改的容器,可以通过随时添加元素,随时删除元素,达到使用时的灵活性。
我们将结合已经学习到的C++的面向对象的知识,结合一部分的数据结构,实现自己的数据容器。

项目目标:
1、添加元素(末尾添加,指定下标添加)
2、删除元素(按照下标删除、按照元素删除、清空)
3、修改元素(按照下标修改)
4、获取元素(按照下标获取)
5、元素排序
6、元素下标查找
7、将容器中的元素拼接为字符串返回

项目分析:
我们将使用两个版本的可变容器:数组版、双链表版。
这两个版本的数据容器,需要以相同的方式提供数据的访问操作,
在这里,我们使用接口类的方式来完成。
*/

1.定义类模板容器,"QFMutableContainer.h"文件。

#pragma once
using namespace std;

//为了能够容纳各种数据类型的元素。将这个类定义为模板类
template<typename E>
//这个类只是为了给数组和链表版本的容器提供统一的接口,因此,这个类可以直接做成接口类
class QFMutableContainer {
public:
	//在末尾添加一个元素
	virtual void add(E ele) = 0;
	//在指定的下标位插入一个元素
	virtual E add(int index, E ele) = 0;
	//按照指定的下标删除元素
	virtual E remove(int index) = 0;
	//按照元素进行删除
	virtual bool removeElement(E ele) = 0;
	//清空容器
	virtual void clear() = 0;
	//通过下标修改元素
	virtual E set(int index, E ele) = 0;
	//通过下标获取元素
	virtual E get(int index) = 0;
	//排序
	virtual void sort() = 0;
	//查找元素出现的下标
	virtual int index(E ele) = 0;
	//将容器中的元素拼接成字符串
	virtual string str() = 0;
	//返回容器中元素得分数量
	virtual int length() = 0;
};

2.定义数组类,"QFMutableArray.hpp"文件。

#pragma once
#pragma once
#include <iostream>
#include <sstream>
#include "QFMutableContainer.h"

using namespace std;

template<typename E>
class QFMutableArray :public QFMutableContainer<E> {
private:
	E* array; //用来存储数据的容器
	int len; //元素的数量
public:
	QFMutableArray();
	//在末尾添加一个元素
	void add(E ele) override;
	//在指定的下标位插入一个元素
	E add(int index, E ele) override;
	//按照指定的下标删除元素
	E remove(int index) override;
	//按照元素进行删除
	bool removeElement(E ele) override;
	//清空容器
	void clear() override;
	//通过下标修改元素
	E set(int index, E ele) override;
	//通过下标获取元素
	E get(int index) override;
	//排序
	void sort() override;
	//查找元素出现的下标
	int index(E ele) override;
	//将容器中的元素拼接成字符串
	string str() override;
	//返回容器中元素得分数量
	int length() override;

	/*~QFMutableArray() override;*/
	~QFMutableArray();
};

template<typename E>
inline QFMutableArray<E>::QFMutableArray()
{
	array = new E[0];
	len = 0;
}


template<typename E>
inline void QFMutableArray<E>::add(E ele)
{
	//添加的思想:
	//1.创建一个新的数组,长度为原数组的长度加一。
	E* tmp = new E[len + 1];
	//2.将原数组中的元素依次拷贝到新的数组中。
	for (int i = 0; i < len; i++) {
		tmp[i] = array[i];
	}
	//3.把本次需要添加的元素放入新数组的最后一位。
	tmp[len] = ele;
	//4.修改元素的数量。
	len++;
	//5.修改array指针的指向,使其指向新的数组。
	delete array;
	array = tmp;
}

template<typename E>
inline E QFMutableArray<E>::add(int index, E ele)
{
	//添加的思想
	//1.创建数组,len+1
	E* tmp = new E[len + 1];
	//2.将原来的数组中的元素一次拷贝到新的数组中,并且在遇到指定的下标位的时候,需要跳过。
	for (int j = 0,i = 0; j < len + 1; j++) {
		if (j == index) {
			continue;
		}
		tmp[j] = array[i++];
	}
	//3.将需要添加的新元素放到新数组中指定的下标位。
	tmp[index] = ele;
	//4.修改元素的数量。
	len++;
	//5.修改array指针的指向,使其指向新的数组。
	delete array;
	array = tmp;

	return *array;
}

template<typename E>
inline E QFMutableArray<E>::remove(int index)
{
	//1.备份被删除的元素
	E ele = array[index];
	//2.创建一个新数组,长度减一。
	E* tmp = new E[len - 1];
	//3.将原来数组中的元素拷贝到新的数组中。
	for (int i = 0, j = 0; i < len; i++) {
		if (i == index) {
			continue;
		}
		tmp[j++] = array[i];
	}
	//4.修改原来数组的长度。
	len--;
	//5.修改array指针的指向,使其指向新的数组。
	delete array;
	array = tmp;

	return ele;
}

template<typename E>
inline bool QFMutableArray<E>::removeElement(E ele)
{
	//1.先找到元素的下标
	int i = index(ele);
	//2.判断元素是否存在;
	if (i == -1) {
		return false;
	}
	//3.按照下标来删除元素
	remove(i);

	return true;
}

template<typename E>
inline void QFMutableArray<E>::clear()
{
	//1.将原来的数组置为空;
	delete array;
	array = new E[0];
	//2.重置元素的数量;
	len = 0;
}

template<typename E>
inline E QFMutableArray<E>::set(int index, E ele)
{
	//1.备份原来的值
	E tmp = array[index];
	//2.修改原来的值;
	array[index] = ele;
	
	//3.返回原来的值
	return tmp;
}

template<typename E>
inline E QFMutableArray<E>::get(int index)
{
	return array[index];
}

template<typename E>
inline void QFMutableArray<E>::sort()
{
	// 外层循环从数组的第一个元素开始,到倒数第二个元素结束
	for (int i = 0; i < len - 1; i++) {
		// 假设当前元素为最小元素
		int minIndex = i;
		// 内层循环从外层循环的下一个元素开始,到数组的最后一个元素结束
		for (int j = i + 1; j < len; j++) {
			// 每次循环比较当前元素和最小元素的大小
			if (array[minIndex] > array[j]) {
				// 如果当前元素比最小元素小,则更新最小元素的下标
				minIndex = j;
			}
		}
		// 如果最小元素的下标不等于当前元素的下标,则交换最小元素和当前元素的位置
		if (minIndex != i) {
			E tmp = array[i];
			array[i] = array[minIndex];
			array[minIndex] = tmp;
		}
	}
}


template<typename E>
inline int QFMutableArray<E>::index(E ele)
{
	for (int i = 0; i < len; i++) {
		if (ele == array[i]) {
			return i;
		}
	}
	return -1;
}

template<typename E>
inline string QFMutableArray<E>::str()
{
	if (len == 0) {
		return "[]";
	}
	//创建一个ostringstream的对象,用来拼接元素。
	ostringstream oss;
	oss << "[";
	for (int i = 0; i < len - 1; i++) {
		oss << array[i] << ",";
	}
	oss << array[len - 1] << "]";
	return oss.str();
}

template<typename E>
inline int QFMutableArray<E>::length()
{
	return len;
}

template<typename E>
inline QFMutableArray<E>::~QFMutableArray()
{
	if (array != nullptr) {
		delete array;
		array = nullptr;
	}
}

//template<typename E>
//inline QFMutableArray<E>::~QFMutableArray()
//{
//	if (array != nullptr) {
//		delete array;
//		array = nullptr;
//	}
//}

3.主函数

#include <iostream>
#include "QFMutableArray.hpp"
#include "QFMutableContainer.h"

using namespace std;


int main()
{
    QFMutableArray<int>* mutableArray = new QFMutableArray<int>();

    // 测试添加元素
    for (int i = 0; i < 10; i++) {
        mutableArray->add(i);
    }
    cout << mutableArray->str() << endl;

    // 测试在指定的下标插入一个元素
    mutableArray->add(4, 12);
    cout << mutableArray->str() << endl; 
    // [-33686019,-842150451,-842150451,12,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451,-842150451], for循环循环变量弄错,导致指向不知名域。
    // [0,1,2,3,12,4,5,6,7,8,9]

    // 测试删除指定下标
    cout << mutableArray->remove(5) << endl; // 4
    cout << mutableArray->str() << endl; // [0,1,2,3,12,4,5,6,7,8,9],没有对原来的数组进行任何操作,也没有将新的数组赋值给原来的数组。
    //[0,1,2,3,12,5,6,7,8,9]

    cout << "array[4]=" << mutableArray->index(4) << endl; // -1 不存在
    cout << "array[3]=" << mutableArray->index(3) << endl; // 3  第三位

    mutableArray->removeElement(3);
    cout << mutableArray->str() << endl; //[0,1,2,12,5,6,7,8,9],第一次error,未设置index函数,导致输出结果为删除首位元素的数组。
    
    // 测试清空数组
    // mutableArray->clear();
    // cout <<"array=" << mutableArray->str() << endl; // []

    // 测试修改值
    mutableArray->set(0, 1);
    cout << "array=" << mutableArray->str() << endl; // array=[1,1,2,12,5,6,7,8,9]

    // 获取值
    cout << "array[5]=" << mutableArray->get(5) << endl; // array[5]=6

    //选择排序
    mutableArray->sort();
    cout << "array=" << mutableArray->str() << endl; //array=[1,1,2,5,6,7,8,9,12],

    return EXIT_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值