1. 程式人生 > >C++模板實現順序表、連結串列

C++模板實現順序表、連結串列

順序表Vector

#include<iostream>
#include<assert.h>
#include<string>
using namespace std;

template<class T>

class Vector{
public:
	//類內定義建構函式
	/*Vector()
		:_Array(NULL)
		, _size(0)
		, _capacity(0)
	{}*/
	
	Vector();//類外定義建構函式,類內宣告
	~Vector()
	{
		if (_Array)
		{
			delete[] _Array;
			_size =
_capacity = 0; } } Vector(const Vector<T>&t) { if (t._size != 0) { _Array = new T[t._size]; memcpy(_Array, t._Array, sizeof(T)*t._size); _capacity = _size = t._size; } else { _Array = NULL; _capacity = _size = 0; } } /*Vector<T>& operator=(const Vector<T>&v) { if (this != &v) { delete[] _Array; if (v._size != 0) { _Array = new T[v._size]; memcpy(_Array, t._Array, sizeof(T)*t._size); _size = _capacity = t._size; } else { _size = 0; } } return *this; }*/
Vector&operator=(Vector<T> v)//現代寫法的賦值操作運算子 { if (v._size!=0) { swap(_Array, v._Array); swap(_capacity, v._capacity); swap(_size, v._size); } else { _size = 0; } return *this; } T& operator[](size_t pos)//const物件不可呼叫,[]意味著可讀可寫 { return _Array[pos]; } const
T& operator[](size_t pos) const//const型別的物件可呼叫 { return _Array[pos]; } void PushBack(const T& x) { Insert(_size,x); } void PopBack() { Erase(_size - 1); } void Insert(size_t pos, const T& x) { assert(pos <= _size); //是否需要增容 if (_size == _capacity) { size_t newcapacity = _capacity == 0 ? 3 : _capacity * 2; T*newArray = new T[newcapacity]; for (size_t i = 0; i < _size; i++) newArray[i] = _Array[i]; delete[] _Array; _Array = newArray; _capacity = newcapacity; } //pos位置以後的節點從後到前後挪一位 size_t end = _size; while (pos < end) { _Array[end] = _Array[end - 1]; end--; } _Array[pos] = x; _size++; } void Erase(size_t pos)//刪除pos位置 { assert(pos <= _size); size_t cur = pos; while (cur < _size-1) { _Array[cur] = _Array[cur + 1]; cur++; } _size--; } size_t Find(const T& x) { size_t i = 0; for (i = 0; i < Size(); i++) { if (x == _Array[i]) { cout << "找到了" << endl; return i; } } cout << "沒找到" << endl; return -1; } size_t Size() { return _size; } void Print() { size_t i = 0; while (i < _size) { cout << _Array[i] << " "; i++; } cout << endl; } private: T* _Array; size_t _size; size_t _capacity; }; //類外定義建構函式 template<class T> Vector<T>::Vector() :_Array(NULL) , _size(0) , _capacity(0) {} void Test1() { Vector<string> s2; s2.PushBack("aaaaaaaaaaaaaaaaaaa"); s2.PushBack("bbb"); s2.PushBack("ccc"); s2.PushBack("ddd"); s2.Print(); Vector<int> v1; //Vector<int>型別 //Vector類名 v1.PushBack(1); v1.PushBack(2); v1.PushBack(3); v1.PushBack(4); Vector<int>v2(v1); v2[v2.Find(3)] = 8; v2.Print(); Vector<int>v3; v3 = v2; v3.PopBack(); v3.Print(); }
aaaaaaaaaaaaaaaaaaa     bbb     ccc     ddd
1       2       3       4
1       2       3       4
請按任意鍵繼續. . .

帶頭雙向迴圈連結串列(無死角)List

在這裡插入圖片描述

//帶頭雙向迴圈連結串列(無死角)
//帶頭(頭結點不儲存資料)
#include<iostream>
#include<string>
using namespace std;

template<class T>
struct Node{
	T _data;
	Node* _next;
	Node* _prev;
};
template<class T>
class List{
public:
	List()
	{
		_head = new Node<T>;
		_head->_next = _head;
		_head->_prev = _head;
	}
	void SetEmpty()//釋放連結串列,只留下頭結點
	{
		if (_head)
		{
			Node<T>*cur = _head->_next;
			while (cur != _head)
			{
				Node<T>*next = cur->_next;
				delete cur;
				cur = next;
			}
			_head->_next = _head;
			_head->_prev = _head;
		}
	}
	~List()//解構函式,釋放所有資源
	{
		SetEmpty();
		delete _head;
	}
	List(const List&l)
	{
		_head = new Node<T>;
		_head->_next = _head;
		_head->_prev = _head;
		Node<T>*cur = l._head->_next;
		while (cur != l._head)
		{
			PushBack(cur->_data);
			cur = cur->_next;
		}
	}
	
	List<T>& operator=(List<T> l)
	{
		SetEmpty();
		Node<T>*cur = l._head->_next;
		while (cur != l._head)
		{
			PushBack(cur->_data);
			cur = cur->_next;
		}
		return *this;
	}

	//增加結點
	void PushBack(const T&x)
	{
		Insert(_head->_prev,x);
	}
	void PushFront(const T&x)
	{
		Insert(_head, x);
	}
	//刪除結點
	void Erase(Node<T>*pos)//刪除掉pos位置結點
	{
		Node<T>*next = pos->_next;
		Node<T>*prev = pos->_prev;
		delete pos;
		prev->_next = next;
		next->_prev = prev;
	}
	void PopBack()
	{
		Erase(_head->_prev);
	}
	void PopFront()
	{
		Erase(_head->_next);
	}
	//插入結點
	void Insert(Node<T>*pos, const T& x)//任意結點pos位置後插入資料x
	{
		Node<T>*node = new Node<T>;
		node->_data = x;
		//pos  node   next
		Node<T>*next = pos->_next;

		pos->_next = node;
		node->_prev = pos;
		node->_next = next;
		next->_prev = node;
	}
	//查
	Node<T>* Find(const T&x)//任意型別的資料x,去查詢資料是x的結點,找不到,返回NULL
	{
		Node<T>*cur = _head->_next;
		while (cur != _head)
		{
			if (x == cur->_data)
				return cur;
			cur = cur->_next;
		}
		return NULL;
	}
	//改
	void Chang(Node<T>*pos, const T&x)//把pos結點位置的資料更換成x
	{
		pos->_data = x;
	}
	//列印
	void Print()
	{
		Node<T>*cur = _head->_next;
		while (cur != _head)
		{
			cout << cur->_data;
			cur = cur->_next;
		}
		cout << endl;
	}
	//該介面向類外提供連結串列表頭
	Node<T>* Head()
	{
		return _head;
	}
private:
	Node<T>* _head;
};
void TestList()
{
	List<string>l1;
	l1.PushBack("是");
	l1.PushFront("我");
	l1.PushBack("大");
	l1.PushBack("佬");
	l1.Print();

	l1.Chang(l1.Head()->_next , "你");
	l1.Print();
	l1.PopBack();
	l1.Print();
	l1.PopFront();
	l1.Print();
	cout << "找到了:"<<l1.Find("大") << "->"<<l1.Find("大")->_data << endl;

	List<string>l2(l1);
	List<string>l3;
	l3 = l1;
	l2.Print();
	l3.Print();
}
我是大佬
你是大佬
你是大
是大
找到了:00BFA8D8->大
是大
是大
請按任意鍵繼續. . .