用C++封装顺序表和双循环链表。

今天我来用C++封装一下以前写过的顺序表以及双循环链表。

一。顺序表:

#include<iostream>
using namespace std;

//定义一个内置类型int。
typedef int DataType;

//写一个动态顺序表:
class Myvector
{
public:
	//形参为空的构造函数
	Myvector()
		:_array(new DataType[3])       //直接初始化列表
		,_size(0)
		,_capacity(3)
	{}

	//已知顺序表的有效长度和每个值进行构造函数。
	Myvector(size_t n, const DataType& data = DataType())
		:_array(new DataType[n])
		,_size(n)
		,_capacity(n)
	{
		size_t i=0;
		for(i=0;i<n;i++)
		{
			_array[i]=data;
		}
	}

	//已知顺序表的两个边界的构造函数。
	Myvector(DataType* first, DataType* last)
	{
		size_t m=last-first;
		size_t i=0;
		_array=new DataType[m];
		_size=m;
		_capacity=_size;
		for(i=0;i<m;i++)
		{
			_array[i]=first[i];
		}
	}

	//拷贝构造函数:
	Myvector(const Myvector& v)
		:_array(new DataType[v._size])
		,_size(v._size)
		,_capacity(v._capacity)
	{
		size_t i=0;
		for(i=0;i<_size;i++)
		{
			_array[i]=v._array[i];
		}
	}

	//赋值运算符重载
	Myvector& operator=(const Myvector& v)
	{
		if(this!=&v)
		{
			DataType* t=new DataType[v._size];
			memcpy(t,v._array,v._size);
			delete[] _array;
			_array=t;
			_size=v._size;
			_capacity=v._capacity;
		}
		return *this;
	}

	//析构函数
	~Myvector()
	{
		if(_array)
		{
			delete[] _array;
			_size=_capacity=0;
		}
	}

	//Acess
	DataType& operator[](size_t index)
	{
		return _array[index];
	}

	const DataType& operator[](size_t index)const
	{
		return _array[index];
	}

	DataType& front()
	{
		return _array[0];
	}

	const DataType& front()const
	{
		return _array[0];
	}

	DataType& back()
	{
		return _array[_size-1];
	}

	const DataType& back()const
	{
		return _array[_size-1];
	}

	//capacity

	size_t size()
	{
		return _size;
	}

	size_t capacity()
	{
		return _capacity;
	}

	//改变顺序表的有效长度。
	void ReSize(size_t newSize, const DataType& data = DataType())
	{
		size_t i=0;
		size_t oldsize=size();
		//若新长度小于旧长度,直接领长度等于新的即可
		if(newSize<=oldsize)                 
		{
			_size=newSize;
		}
		else{
			//否则若不超过最大容量,则直接将data复制过去即可。
			if(newSize<=_capacity)
			{
				for(i=0;i<newSize;i++)
				{
					_array[i]=data;
				}
			}

			 //若超过了容量
			else{

				//开辟新的空间
			DataType* t=new DataType[newSize];
			//先将旧的值拷贝进来
			for(i=0;i<oldsize;i++)
			{
				t[i]=_array[i];
			}

			//再将剩下的赋成data
			while(i<newSize)
			{
				t[i++]=data;
			}
			//销毁旧空间
			delete[] _array;
			_array=t;
			_size=newSize;
			_capacity=_size;
			}
		}
	}

	// 为当前顺序表来预留空间,不能改变顺序表中有效元素的个数
	void Reserve(size_t newCapacity)
	{
		size_t i=0;
		size_t old=capacity();
		if(newCapacity>old)
		{
			DataType* t=new DataType[newCapacity];
			for(i=0;i<size();i++)
			{
				t[i]=_array[i];
			}
			delete[] _array;
			_array=t;
			_capacity=newCapacity;
		}
	}


	//modify


	//尾插
	void PushBack(DataType& d)
	{
		//检验是否超过容量。
		if(_capacity==_size)
		{
			Reserve(_capacity*2);
		}
		_array[_size++]=d;
	}

	//尾删
	void PopBack()
	{
		_size--;
	}

	//任意位置插入
	void Insert(size_t pos, const DataType& data)
	{
		size_t i=0;
		if(_size==_capacity)
		{
			Reserve(2*_capacity);
		}
		for(i=size();i>pos;i--)
		{
			_array[i]=_array[i-1];
		}
		_array[i]=data;
		_size++;
	}

	//任意位置进行删除
	void Erase(size_t pos)
	{
		size_t i=pos;
		for(i=pos+1;i<size();i++)
		{
			_array[i-1]=_array[i];
		}
		_size--;
	}

	//清空顺序表
	void Clear()
	{
		_size = 0;
	}

	//输出运算符重载
	friend ostream& operator<<(ostream& _cout, const Myvector& v)
	{
		for(size_t i = 0; i < v._size; ++i)
			_cout<<v._array[i]<<" ";

		return _cout;
	}
private:
	DataType *_array;
	size_t _size;
	size_t _capacity;
};

int main()
{
	Myvector v1;
	cout<<v1<<endl;
	cout<<v1.size()<<endl;
	cout<<v1.capacity()<<endl;
	Myvector v2(10,5);
	cout<<v2<<endl;
	cout<<v2.size()<<endl;
	cout<<v2.capacity()<<endl;
	int array[]={0,1,2,3,4,5,6,7,8,9};
	Myvector v3(array,array+sizeof(array)/sizeof(array[0]));
	cout<<v3<<endl;
	cout<<v3.size()<<endl;
	cout<<v3.capacity()<<endl;

	v3.Reserve(5);
	cout<<v3<<endl;
	cout<<v3.size()<<endl;
	cout<<v3.capacity()<<endl;

	v3.ReSize(5);
	cout<<v3<<endl;
	cout<<v3.size()<<endl;
	cout<<v3.capacity()<<endl;


	v3.ReSize(30,9);
	cout<<v3<<endl;
	cout<<v3.size()<<endl;
	cout<<v3.capacity()<<endl;

	system("pause");
	return 0;
}

这就是封装后的顺序表,这里面需要注意的就是在写拷贝构造函数时要记得写成深拷贝的任意形式,否则会造成内存泄漏。

 

二。双循环链表:

#include<iostream>

using namespace std;

typedef int DataType;


//双循环链表的结构体
struct ListNode
{
	ListNode(const DataType& data=DataType())
		:_data(data)
		,next(NULL)
		,pre(NULL)
	{}

	DataType _data;
	ListNode* next;
	ListNode *pre;
};

//双循环链表:
class MyList
{
public:
	//形参数为空的构造函数
	MyList()
	{
		creathead();
	}

	//已知个数和值的构造函数
	MyList(size_t n, const DataType& data = DataType())
	{
		size_t i=0;
		creathead();
		for(i=0;i<n;i++)
		{
			PushBack(data);
		}
	}

	//已知两个边界的构造函数
	MyList(DataType* first,DataType* last)
	{
		creathead();
		while(first!=last)
		{
			PushBack(*first);
			first++;
		}
	}

	//析构函数
	~MyList()
	{
		clear();
		destroy();
	}


	//拷贝构造函数。
	MyList(const MyList& m)
	{
		ListNode *p=new ListNode(m.head->_data);
		head=p;
		head->next=head->pre=head;
	}

	//赋值运算符重载
	MyList& operator=(const MyList& l)
	{
		if(this!=&l)
		{
			ListNode *p=new ListNode(l.head->_data);
			p->next=p->pre=p;
			delete head;
			head=p;
		}
		return *this;
	}

	//capacity:

	//求个数
	size_t size()
	{
		size_t n=0;
		ListNode* p=head->next;
		while(p!=head)
		{
			n++;
			p=p->next;
		}
		return n;
	}

	//判空
	bool empty()
	{
		return head->next==head;
	}

	//清空
	void clear()
	{
		ListNode *p=head->next;
		ListNode* q=head;
		while(p!=head)
		{
			head->next=p->next;
			delete p;
			p=head->next;
		}
		head->next=head;
		head->pre=head;
	}

	//给出新的大小进行操作。
	void ReSize(size_t newSize, const DataType& data = DataType())
	{
		size_t n=size();
		if(newSize<=n)
		{
			while(newSize<n)
			{
				PopBack();
				n--;
			}
		}
		else{
			while(n<newSize)
			{
				PushBack(data);
				n++;
			}
		}
	}


	//Access

	//求第一个值
	DataType& front()
	{
		return head->next->_data;
	}

	const DataType& front()const
	{
        return head->next->_data;
	}

	//求最后一个值
	DataType& back()
	{
		return head->pre->_data;
	}

	const DataType& back()const
	{
        return head->pre->_data;
	}


	//modify

	//尾插
	void PushBack(const DataType& d)
	{
		ListNode *pnew=new ListNode(d);
		ListNode *p=head->pre;
		p->next=pnew;
		head->pre=pnew;
		pnew->next=head;
		pnew->pre=p;
	}

	//尾删
	void PopBack()
	{
		ListNode *p=head->pre;
		if(p!=head){
		head->pre=p->pre;
		p->pre->next=head;
		delete p;
		}
	}

	//头插
	void PushFront(const DataType& data)
	{
		ListNode *pnew=new ListNode(data);
		pnew->pre=head;
		pnew->next=head->next;
		head->next->pre=pnew;
		head->next=pnew;
	}

	//头删
	void Popfront()
	{
		ListNode *p=head->next;
		if(p!=head)
		{
			head->next=p->next;
			p->next->pre=head;
			delete p;
		}
	}

	//任意位置插入
	void Insert(ListNode* pos, const DataType& data)
	{
		ListNode *pnew=new ListNode(data);
		pos->pre->next=pnew;
		pnew->pre=pos->pre;
		pnew->next=pos;
		pos->pre=pnew;

	}

	//任意位置删除
	void Erase(ListNode* pos)
	{
		if(pos)
		{
			pos->pre->next=pos->next;
			pos->next->pre=pos->pre;
			delete pos;
		}
	}

	//查找
	ListNode* Find(const DataType& data)
	{
		ListNode *p=head->next;
		while(p!=head)
		{
			if(p->_data==data)
			{
				return p;
			}
			p=p->next;
		}
	}

private:

	//开辟空间
	void creathead()
	{
		head=new ListNode;
		head->next=head;
		head->pre=head;
	}

	//销毁
	void destroy()
	{
		delete head;
		head=0;
		head->next=head->pre=NULL;
	}

	//输出运算符重载
	friend ostream& operator<<(ostream& _cout, const MyList& l)
	{
		ListNode* pCur = l.head->next;
		while(pCur != l.head)
		{
			cout<<pCur->_data<<" ";
			pCur = pCur->next;
		}

		return _cout;
	}


private:
	ListNode* head;
};
int main()
{
	MyList m1;
	MyList m2(10,5);
	cout<<m1<<endl;
	cout<<m2<<endl;
	cout<<m2.size()<<endl;


	int array[] = {1,2,3,4,5,6,7,8,9,0};
	MyList l3(array, array+sizeof(array)/sizeof(array[0]));
	cout<<l3<<endl;
	cout<<l3.size()<<endl;
	cout<<l3.front()<<endl;
	cout<<l3.back()<<endl;

	l3.PushBack(1);
	l3.PushBack(2);
	l3.PushBack(3);
	l3.PushBack(4);
	cout<<l3<<endl;

	l3.PopBack();
	l3.PopBack();
	cout<<l3<<endl;

	l3.PushFront(0);
	cout<<l3<<endl;

	l3.Popfront();
	cout<<l3<<endl;

	l3.ReSize(5);
	cout<<l3.size()<<endl;
	cout<<l3<<endl;

	l3.ReSize(20, 9);
	cout<<l3.size()<<endl;
	cout<<l3<<endl;

	ListNode* pos = l3.Find(3);
	l3.Insert(pos, 8);
	cout<<l3<<endl;

	l3.Erase(pos);
	cout<<l3<<endl;

	l3.clear();
	cout<<l3.size()<<endl;
	system("pause");
	return 0;
}

这就是双循环链表封装后的代码了,总的来说,这两个数据结构并不难,但是还是需要大家多多练习,这样才能熟练掌握。

谢谢观赏

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值