C++_STL容器vector和List学习笔记

向量vector的仿真MyVector
向量是一种单端开口的容器,其原始容器是一个数组,由于它属于数据成员,为了数据安全它在类模板MyVector中应具有private或者protected属性。为了可以实现数组的动态增长,因此在构造函数中以动态分配内存够的方式来创建这个数组,代码如下:

#include<iostream>
using namespace std;
template<typename Ty>
class MyVector
{
public:
	//内嵌类型表
	typedef Ty value;
	typedef Ty* viter;
public:
	//构造函数
	MyVector(int nlen = 0) :m_nLen(nlen), m_Data(NULL),finish(0)
	{
		if (nlen > 0)
		{
			m_Data = new Ty[nlen];
			star = m_Data;
			end_of_element = nlen;
		}
	}
	//析构函数
	~MyVector()
	{
		delete[]m_Data;
	}
	//在数组尾部输入数据的函数
	void push_back(const value& x)
	{
		if (end_of_element != finish)
		{
			* (star + finish) = x;
			++finish;
		}
		else
		{
			cout << "越界" << endl;
		}
	}
	//自数组尾部输出数据的函数
	inline value pop_back()
	{
		--finish;
		return *(star + finish);
	}
	//输出元素个数
	void size()
	{
		cout << finish << endl;
	}
	//重载的operator[]
	value& operator[](int n)
	{
		if (n == finish || n < finish)
			return *(star + n);
		else
			cout << "err" << endl;
	}
protected:
	viter m_Data;   //数组头指针
	int m_nLen;     //数组长度
	viter star;      //数组起始地址
	int finish;    //数组满位标志(star+finish指向所添加元素的最后一个元素)
	int end_of_element;    //数组末尾标志(数组中最后一个元素的下一个位置)
};

测试程序如下

int main()
{
	int x;
	//定义int类型MyVector对象v1
	MyVector<int>v1(10);
	//自v1尾部输入数据
	v1.push_back(100);
	v1.push_back(200);
	v1.push_back(300);
	//自V1尾部输出数据
	x = v1.pop_back();
	x = v1.pop_back();
	x = v1.pop_back();
	//x = v1.pop_back();
	cout << "x= " << x << endl;
	v1.size();
	//使用下标方式访问
	//cout << v1[0] << endl;
	//cout << v1[1] << endl;
	//cout << v1[2] << endl;
	//cout << v1[3] << endl;
	return 0;
}

列表list的仿真MyList
链表是一种可以存放多个同类数据的数据结构。在STL中,list就是一种以链表为数据存储核心的容器。list为首位双端的开口容器,MyList是对list的一个模拟,创建一个双向链表的节点结构。下面定义了支持头尾数据插入和删除操作函数push_front()、pop_front()、push_back()以及pop_back()并能向外提供操作,MyList也编写了数据的插入和删除函数insert()和erase(),为了能够使用下标对元素进行访问,MyList对运算符operator[]进行了重载,程序代码如下:

#include<iostream>
using namespace std;
template<typename T>
//定义节点
struct MyList_node
{
	MyList_node<T>* prev;  //前驱指针
	MyList_node<T>* next;    //后继指针
	T data;   //数据
};
//MyList*************
template<typename T>
class MyList
{
//内嵌数据类型
public:
	typedef MyList_node<T>* link_type;
protected:
	MyList_node<T>* node;   //链表尾指针
	size_t length;          //链表长度
public:
	//构造函数
	MyList() :length(0)
	{
		//创建链表尾对象,其数据为空
		node = new MyList_node<T>;
		//以尾对象为自身的前驱和后驱
		node->next = node;
		node->prev = node;
	}
	//析构函数
	~MyList(){}
	//返回链表头函数
	link_type begin()
	{
		return node->next;
	}
	//返回链表尾地址函数
	link_type end()
	{
		return node;
	}
	//向MyList头加入节点
	void push_front(T x)
	{
		insert(begin(), x);
	}
	//向MyList尾加入节点
	void push_back(T x)
	{
		insert(end(), x);
	}
	//自MyList头删除节点
	void pop_front()
	{
		erase(begin());
	}
	//自链表尾删除节点
	void pop_back()
	{
		erase(end()->prev);
	}
	//插入节点操作
	link_type insert(link_type position, T& x) //新节点插入此节点为后继 //新节点数据
	{
		//创建新节点
		MyList_node<T>* tmp = new MyList_node<T>;
		//为新节点的数据域data赋值
		tmp->data = x;
		//以position节点前驱为新节点前驱
		tmp->prev = position->prev;
		//以position节点为新节点后继
		tmp->next = position;
		//修改position的原前驱,使其后继指向新节点
		position->prev->next = tmp;
		//修改position,使前驱指针指向新的节点
		position->prev = tmp;
		//链表长度加1
		++length;
		return tmp;
	}
	//删除节点操作函数
	void erase(const link_type& position)
	{
		//被删除节点后继指针赋予该节点前驱的同名域
		position->prev->next = position->next;
		//被删除节点前驱指针赋予该节点后继的同名域
		position->next->prev = position->prev;
		--length;
	}
	//重载operator[]
	T& operator[](size_t n)
	{
		//判断n是否越界
		if (n < 0 || n >= length)
			cerr << "out of range";
		//设置查找结果指针
		link_type current = NULL;
		//n处于链表前半区
		if (n < length / 2)
		{
			//从链表头沿后继指向查询n次
			current = node->next;
			for (size_t i = 0; i < n; i++)
				current = current->next;
		}
		else  //n处于链表后半区
		{
			//修改n的数值
			n = length - n - 1;
			//从链表尾沿前驱指向查询n次
			current = node->prev;
			for (size_t i = 0; i < n; i++)
				current = current->prev;
		}
		//返回数据域的引用
		return current->data;
	}
};

测试程序如下:

int main()
{
	//创建MyList对象MyList1
	MyList<int>MyList1;
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//向头部输入数据10
	MyList1.push_front(10);
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//向头部输入数据20和30
	MyList1.push_front(20);
	MyList1.push_front(30);
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//向尾部输入数据300
	MyList1.push_back(300);
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//向尾部输入数据200
	MyList1.push_back(200);
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//显示当前MyList1中全部的数据
	for (int i = 0; i < 5; i++)
		cout << MyList1[i] << "     ";
	cout << endl << endl;

	
	//自头部删除数据
	MyList1.pop_front();
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//显示当前MyList1中全部的数据
	for (int i = 0; i < 4; i++)
		cout << MyList1[i] << "     ";
	cout << endl << endl;
	
	
	//自尾部删除数据
	MyList1.pop_back();
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//显示当前MyList1中全部的数据
	for (int i = 0; i < 3; i++)
		cout << MyList1[i] << "     ";
	cout << endl << endl;
	
	
	//自尾部删除数据
	MyList1.pop_back();
	//显示MyList1.begin()和MyList1.end()
	cout << "MyList1.begin = " << MyList1.begin()
		<< "          MyList1.end = " << MyList1.end() << endl << endl;
	//显示当前MyList1中全部的数据
	for (int i = 0; i < 2; i++)
		cout << MyList1[i] << "     ";
	cout << endl;
	return 0;
}

运行结果如下
在这里插入图片描述未完待续

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值