【类和对象】第4关:DynArray类的第一个版本

将链表封装为一个动态数组(DynArray)类。该类能够实现元素的访问、元素的动态插入、删除等功能。

class DynArray {
public:
    DynArray();
    virtual ~DynArray();
protected:
    struct ArrayEle
    {
        int val;
        ArrayEle* next;
    };
private:
    ArrayEle * m_head;
    ArrayEle * m_tail;
    ArrayEle * position(int) const;
public:
    int count() const;
    void add(int);
    void insert(int, int);
    void remove(int);
    int  getAt(int) const;
    void setAt(int, int);
    void clear();
    void print() const;
};
DynArray()~DynArray() 当然是构造方法和析构方法 —— 注意这里的 ~DynArray() 前面增加了关键字 virtual,表明它是一个虚方法——该知识点会在后面“继承与多态”章节中作具体介绍;
在 DynArray 类中声明了一个嵌套类(嵌套结构) ArrayEle,它实际上封装了一个链表节点结构,因为我们不希望用户感知到这个结构的存在 —— 它的全名是 DynArray::ArrayEle。
私有属性 m_head、m_tail 分别对应链表的头尾节点指针;私有方法position(int) 用以返回指向指定位置节点的指针;
count()方法返回当前元素的总数;
add(int) 用于在尾部追加一个新的元素,参数为元素的值;
insert(int, int) 用于在指定位置插入新元素,两个参数分别对应元素索引(从0开始)与新插入元素的值;
remove(int) 分别用来删除指定位置的元素;
getAt(int)setAt(int, int) 分别完成对指定位置(第一参数)元素的读写访问操作;
clear() 用于清空所有元素;
print() 用于打印当前所有元素(输出时每个元素单独占一行)。
#include <iostream>
#include <sstream>

using namespace std;

class DynArray {

public:
	DynArray();
	virtual ~DynArray();

protected:
	struct ArrayEle
	{
		int val;
		ArrayEle* next;
	};

private:
	ArrayEle* m_head;
	ArrayEle* m_tail;
	ArrayEle* position(int) const;

public:
	int count() const;
	void add(int);
	void insert(int, int);
	void remove(int);
	int  getAt(int) const;
	void setAt(int, int);
	void clear();
	void print() const;
};

/************* begin ***************/
DynArray::DynArray()
{
	this->m_head = NULL;
	this->m_tail = NULL;
}
DynArray::~DynArray()
{
	this->clear();
}
DynArray::ArrayEle* DynArray::position(int idx) const
{
	using element_t = DynArray::ArrayEle;

	int cur = 0;
	for (element_t* it = this->m_head; it != this->m_tail; it = it->next, cur++)
	{
		if (cur == idx)return it;
	}

	return NULL;
}
int DynArray::count() const
{
	int cnt = 0;

	using element_t = DynArray::ArrayEle;
	for (element_t* it = this->m_head; it != this->m_tail; it = it->next)cnt++;

	return cnt;
}
void DynArray::add(int x)
{
	using element_t = DynArray::ArrayEle;

	element_t* p = new element_t;
	p->val = x;
	p->next = NULL;

	if (this->m_tail == NULL) // 链表原来是空的
	{
		this->m_head = this->m_tail = p;
	}
	else
	{
		this->m_tail->next = p;
		this->m_tail = p;
	}
}
void DynArray::insert(int idx, int y)
{
	using element_t = DynArray::ArrayEle;

	element_t* p = this->position(idx);
	if (p == NULL)return;
	
	//在p的后面插入新节点
	element_t* create = new element_t;
	create->val = y;
	create->next = NULL;

	create->next = p->next;
	p->next = create;

	swap(p->val, create->val);
}
void DynArray::remove(int idx)
{
	using element_t = DynArray::ArrayEle;

	if (this->m_head == NULL) return;
	if (idx == 0) // 要删头结点
	{
		element_t* h = this->m_head;
		this->m_head = this->m_head->next;

		delete h;
		return;
	}

	// 删的不是头结点,那她一定有前驱
	element_t* a = this->position(idx - 1);// 前驱
	element_t* b = this->position(idx);// 要删的节点
	if (a == NULL || b == NULL)return;

	// a和b都存在
	a->next = b->next;
	delete b;
}
int DynArray::getAt(int idx) const
{
	using element_t = DynArray::ArrayEle;
	element_t* p = this->position(idx);

	if (p == NULL)return -1;

	return p->val;
}
void DynArray::setAt(int idx, int x)
{
	using element_t = DynArray::ArrayEle;
	element_t* p = this->position(idx);

	if (p == NULL)return;

	p->val = x;
}
void DynArray::clear()
{
	using element_t = DynArray::ArrayEle;

	element_t* it = this->m_head;
	while (it)
	{
		element_t* d = it;
		it = it->next;

		delete d;
	}
	this->m_head = this->m_tail = NULL;
}
void DynArray::print() const
{
	using element_t = DynArray::ArrayEle;

	for (element_t* it = this->m_head; it; it = it->next)
		cout << it->val << endl;
}
/************* end  ***************/

int main(int argc, char** argv)
{
	int n; // number of elements;
	cin >> n;
	DynArray da;
	for (int i = 0; i < n; i++) {
		int d;
		cin >> d;
		da.add(d);
	}

	da.insert(1, 3);
	da.remove(2);
	da.print();
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值