C++模板實現順序表、連結串列
阿新 • • 發佈:2019-02-12
順序表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->大
是大
是大
請按任意鍵繼續. . .