最近在复习数据结构的内容,模仿了stl中的list、vector、queue和stack.当然是精简版的了,只写了最基本的功能。
这里要注意一点,模板类的类声明和定义要在同一个文件内,最好是在头文件内。因为模板类和模板函数在使用的时候才会被实例化,所以编译器需要知道所有的实现代码,然后去实例化各种数据类型的类或者函数。所以如果把类定义放在单独的源文件中的话,编译器找不到相关定义。
代码如下,这里实现的是双向循环链表
// list头文件
#pragma once
#include
template<typename T>
class list
{
public:
list();
virtual ~list();
list(const list & ob);
list(list && ob);
list & operator= (const list & ob);
list & operator= (list && ob);
private:
unsigned int m_nLength;
node * m_tailNode;
public:
// 获取元素值
T getElement(unsigned int index) const;
// 获取头节点值
T get_front() const;
// 获取尾节点值
T get_back() const;
// 插入元素
bool insert(unsigned int index, T elem);
// 插入首位
bool insert_front(T elem);
// 在尾部插入
bool insert_back(T elem);
// 设置某个位置的值
bool setValue(unsigned int index, T value);
// 删除某个节点并返回该节点的值
T deleteElement(unsigned int index);
// 删除头节点,返回该节点的值
T delete_front();
// 删除尾节点并返回该节点的值
T delete_back();
// 删除所有节点
void deleteAll();
// 获取链表长度
unsigned int getLength() const;
// 链表是否为空
bool empty() const;
};
template<typename T>
list ::list() : m_tailNode(nullptr), m_nLength(0u)
{
}
template<typename T>
list ::~list()
{
deleteAll();
m_tailNode = nullptr;
}
template<typename T>
list ::list(const list & ob)
{
try
{
unsigned int n = 0;
while (n < ob.getLength())// 拷贝元素节点
{
insert_back(ob.getElement(n));
n++;
}
}
catch (std::exception e)
{
deleteAll();
e.what();
}
}
template<typename T>
list ::list(list && ob)
{
m_tailNode = ob.m_tailNode;
m_nLength = ob.m_nLength;
ob.m_tailNode = nullptr;
ob.m_nLength = 0u;
}
template<typename T>
list & list ::operator= (const list & ob)
{
if (!empty())
{
deleteAll();
m_tailNode = nullptr;
}
try
{
unsigned int n = 0;
unsigned int nLength = ob.getLength();
while (n < nLength)
{
insert_back(ob.getElement(n));
n++;
}
}
catch (std::exception e)
{
deleteAll();
e.what();
}
return * this;
}
template<typename T>
list & list ::operator= (list && ob)
{
m_tailNode = ob.m_tailNode;
m_nLength = ob.m_nLength;
ob.m_tailNode = nullptr;
ob.m_nLength = 0u;
return * this;
}
template<typename T>
T list ::getElement(unsigned int index) const
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
T temp;
if (index <= m_nLength / 2)
{
unsigned int n = 0;
node * pnode = m_tailNode;
while (n++ <= index)
{
pnode = pnode->next;
}
temp = pnode->data;
}
else
{
unsigned int n = m_nLength - 1;
node * pnode = m_tailNode;
while (n-- > index)
{
pnode = pnode->pre;
}
temp = pnode->data;
}
return temp;
}
template<typename T>
T list ::get_front() const
{
return getElement(0u);
}
template<typename T>
T list ::get_back() const
{
if (m_nLength == 0u)
{
return T;
}
return get_Element(m_nLength - 1);
}
template<typename T>
bool list ::insert(unsigned int index, T elem)
{
if (index > m_nLength)
{
std::cout << "out of ranges" << std::endl;
return false;
}
if (0u == m_nLength)
{
node * pnode = new node;
if (nullptr == pnode)
{
throw (std::exception("内存分配出错!"));
}
m_tailNode = pnode;
pnode->data = elem;
pnode->next = m_tailNode;
pnode->pre = m_tailNode;
}
else if (0u == index)// 插入第一位置
{
node * pnode = new node;
pnode->data = elem;
pnode->next = m_tailNode->next;
m_tailNode->next = pnode;
pnode->pre = m_tailNode;
pnode->next->pre = pnode;
}
else if (m_nLength == index)// 插入尾部
{
node * pnode = new node;
pnode->data = elem;
pnode->next = m_tailNode->next;
m_tailNode->next = pnode;
pnode->pre = m_tailNode;
pnode->next->pre = pnode;
m_tailNode = pnode;
}
else if (index <= m_nLength / 2)
{
node * pnode = m_tailNode;
unsigned int n = 0u;
while (n++ < index)// 定位到index上一个节点
{
pnode = pnode->next;
}
// 插入节点
node * pnodeElem = new node;
pnodeElem->data = elem;
pnodeElem->next = pnode->next;
pnode->next = pnodeElem;
pnodeElem->pre = pnode;
pnodeElem->next->pre = pnodeElem;
}
else
{
node * pnode = m_tailNode;
unsigned int n = m_nLength - 1;
while (--n > index )// 定位到index上一个节点
{
pnode = pnode->pre;
}
node * pnodeElem = new node;
pnodeElem->data = elem;
pnodeElem->pre = pnode->pre;
pnode->pre = pnodeElem;
pnodeElem->next = pnode;
pnodeElem->pre->next = pnodeElem;
}
// 长度增加
m_nLength++;
return true;
}
template<typename T>
bool list ::insert_front(T elem)
{
return insert(0u, elem);
}
template<typename T>
bool list ::insert_back(T elem)
{
return insert(m_nLength, elem);
}
template<typename T>
bool list ::setValue(unsigned int index, T value)
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
T temp;
if (index <= m_nLength / 2)
{
unsigned int n = 0;
node * pnode = m_tailNode;
while (n++ <= index)
{
pnode = pnode->next;
}
pnode->data = value;
}
else
{
unsigned int n = m_nLength - 1;
node * pnode = m_tailNode;
while (n-- > index)
{
pnode = pnode->pre;
}
pnode->data = value;
}
return true;
}
template<typename T>
T list ::deleteElement(unsigned int index)
{
if (index > m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
T temp;
if (0u == index)// 删除第一个
{
node * pnode;
pnode = m_tailNode->next;
m_tailNode->next = pnode->next;
pnode->next->pre = m_tailNode;
temp = pnode->data;
}
else if (m_nLength - 1 == index)// 删除尾部
{
node * pnode;
m_tailNode->pre->next = m_tailNode->next;
m_tailNode->next->pre = m_tailNode->pre;
pnode = m_tailNode;
m_tailNode = m_tailNode->pre;
temp = pnode->data;
delete pnode;
}
else if (index <= m_nLength / 2)
{
node * pnode = m_tailNode;
unsigned int n = 0u;
while (n++ < index)// 定位到index上一个节点
{
pnode = pnode->next;
}
// 删除节点
node * pnodeElem;
pnodeElem = pnode->next;
pnode->next = pnodeElem->next;
pnodeElem->next->pre = pnode;
temp = pnodeElem->data;
delete pnodeElem;
}
else
{
node * pnode = m_tailNode;
unsigned int n = m_nLength - 1;
while (--n > index)// 定位到index上一个节点
{
pnode = pnode->pre;
}
node * pnodeElem;
pnodeElem = pnode->pre;
pnodeElem->pre->next = pnode;
pnode->pre = pnodeElem->pre;
temp = pnode->data;
delete pnodeElem;
}
m_nLength--;
return temp;
}
template<typename T>
T list ::delete_front()
{
return deleteElement(0u);
}
template<typename T>
T list ::delete_back()
{
if (m_nLength > 0u)
{
return deleteElement(m_nLength - 1);
}
else
{
return 0;
}
}
template<typename T>
void list ::deleteAll()
{
while (m_nLength > 0u)
{
deleteElement(0u);
}
}
template<typename T>
unsigned int list ::getLength() const
{
return m_nLength;
}
template<typename T>
bool list ::empty() const
{
return m_nLength > 0u ? false : true;
}
测试代码如下:
#include "list.h"
#include
void show_list(list<double> &ls)
{
unsigned int n = ls.getLength();
for (unsigned int i = 0u; i < n; i++)
{
std::cout << ls.getElement(i) << std::endl;
}
}
list<double> listTest()
{
list<double> ls;
ls.insert_back(1.1);
ls.insert_back(2.3);
ls.insert_back(3.55);
ls.insert_back(4.44);
return ls;
}
void list_test()
{
// 插入元素
std::cout << "插入元素" << std::endl;
list<double> ls;
ls.insert_back(1.1);
ls.insert_back(2.3);
ls.insert_back(3.55);
ls.insert_back(4.44);
show_list(ls);
list<double> ls1(ls);
list<double> ls2 = ls;
list<double> ls3 = listTest();
// 删除元素
std::cout << "删除元素" << std::endl;
ls.deleteElement(5);
ls.deleteElement(3);
ls.delete_front();
ls.delete_back();
show_list(ls);
// 设置值
std::cout << "设置元素值" << std::endl;
ls.setValue(0, 10983.9348);
ls.setValue(2, 333333.000);
show_list(ls);
// 删除所有
std::cout << "删除所有" << std::endl;
ls.deleteAll();
if (ls.empty())
{
std::cout << "list is empty" << std::endl;
ls.insert(0, 300.875);
}
show_list(ls);
std::cout << std::endl << "ls1" << std::endl;
show_list(ls1);
std::cout << std::endl << "ls2" << std::endl;
show_list(ls2);
std::cout << std::endl << "ls3" << std::endl;
show_list(ls3);
}
int main()
{
list_test();
getchar();
}
测试结果如下:
实现代码:
// vector头文件
#pragma once
template<typename T>
class vector
{
public:
vector();
virtual ~vector();
vector(const vector & ob);
vector(vector && ob);
vector & operator= (const vector & ob);
vector & operator= (vector && ob);
private:
unsigned int m_nLength;
unsigned int m_nCapacity;
unsigned int m_nIncrement;
T * m_array;
bool adjustCapacity();
public:
// 获取元素值
T getElement(unsigned int index) const;
// 获取头节点值
T get_front() const;
// 获取尾节点值
T get_back() const;
// 插入元素
bool insert(unsigned int index, T elem);
// 插入首位
bool insert_front(T elem);
// 在尾部插入
bool insert_back(T elem);
// 设置某个位置的值
bool setValue(unsigned int index, T value);
// 删除某个节点并返回该节点的值
T deleteElement(unsigned int index);
// 删除头节点,返回该节点的值
T delete_front();
// 删除尾节点并返回该节点的值
T delete_back();
// 删除所有节点
void deleteAll();
// 获取链表长度
unsigned int getLength() const;
// 链表是否为空
bool empty() const;
};
template<typename T>
vector ::vector() : m_nLength(0u), m_nCapacity(0u), m_nIncrement(10u), m_array(nullptr)
{
m_nCapacity = 10u;
m_array = new T[m_nCapacity];
}
template<typename T>
vector ::~vector()
{
if (nullptr != m_array)
delete[] m_array;
}
template<typename T>
vector ::vector(const vector & ob)
{
m_nLength = ob.m_nLength;
m_nCapacity = ob.m_nCapacity;
m_nIncrement = ob.m_nIncrement;
if (nullptr != m_array)
{
delete[] m_array;
}
m_array = new T[m_nCapacity];
for (unsigned int i = 0u; i < m_nLength; i++)
{
m_array[i] = ob.m_array[i];
}
}
template<typename T>
vector ::vector(vector && ob)
{
m_nLength = ob.m_nLength;
m_nCapacity = ob.m_nCapacity;
m_nIncrement = ob.m_nIncrement;
m_array = ob.m_array;
ob.m_array = nullptr;
}
template<typename T>
vector & vector ::operator= (const vector & ob)
{
m_nLength = ob.m_nLength;
m_nCapacity = ob.m_nCapacity;
m_nIncrement = ob.m_nIncrement;
if (nullptr != m_array)
{
delete[] m_array;
}
m_array = new T[m_nCapacity];
for (unsigned int i = 0u; i < m_nLength; i++)
{
m_array[i] = ob.m_array[i];
}
return * this;
}
template<typename T>
vector & vector ::operator= (vector && ob)
{
m_nLength = ob.m_nLength;
m_nCapacity = ob.m_nCapacity;
m_nIncrement = ob.m_nIncrement;
m_array = ob.m_array;
ob.m_array = nullptr;
return * this;
}
template<typename T>
bool vector ::adjustCapacity()
{
T * pTemp = new T[m_nCapacity + m_nIncrement];
if (nullptr == pTemp)
{
return false;
}
m_nCapacity += m_nIncrement;
for (unsigned int i = 0u; i < m_nLength; i++)
{
pTemp[i] = m_array[i];
}
delete[] m_array;
m_array = pTemp;
return true;
}
template<typename T>
T vector ::getElement(unsigned int index) const
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
return m_array[index];
}
template<typename T>
T vector ::get_front() const
{
return getElement(0u);
}
template<typename T>
T vector ::get_back() const
{
if (0u == m_nLength)
return 0;
return getElement(m_nLength - 1);
}
template<typename T>
bool vector ::insert(unsigned int index, T elem)
{
bool bRet = true;
if (m_nLength + 1 > m_nCapacity)
bRet = adjustCapacity();
if (!bRet)
return false;
if (index > m_nLength)
{
std::cout << "out of ranges" << std::endl;
return false;;
}
for (unsigned int i = m_nLength; i > index; i--)
{
m_array[i] = m_array[i - 1];
}
m_array[index] = elem;
m_nLength++;
return true;
}
template<typename T>
bool vector ::insert_front(T elem)
{
return insert(0u, elem);
}
template<typename T>
bool vector ::insert_back(T elem)
{
return insert(m_nLength, elem);
}
template<typename T>
bool vector ::setValue(unsigned int index, T value)
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return false;
}
m_array[index] = value;
return true;
}
template<typename T>
T vector ::deleteElement(unsigned int index)
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return false;
}
T temp = m_array[index];
for (unsigned int i = index; i < m_nLength - 1; i++)
{
m_array[i] = m_array[i + 1];
}
m_nLength--;
return temp;
}
template<typename T>
T vector ::delete_front()
{
return deleteElement(0u);
}
template<typename T>
T vector ::delete_back()
{
if (m_nLength == 0u)
return 0;
return deleteElement(m_nLength - 1);
}
template<typename T>
void vector ::deleteAll()
{
m_nLength = 0;
}
template<typename T>
unsigned int vector ::getLength() const
{
return m_nLength;
}
template<typename T>
bool vector ::empty() const
{
return m_nLength > 0u ? false : true;
}
测试代码如下:
#include "vector.h"
#include
vector<double> vectorTest()
{
vector<double> vec;
vec.insert_back(0.12);
vec.insert_back(1.12);
vec.insert_back(2.12);
vec.insert_back(3.12);
vec.insert_back(4.12);
vec.insert_back(5.12);
vec.insert_back(6.12);
vec.insert_back(7.12);
vec.insert_back(8.12);
vec.insert_back(9.12);
vec.insert_back(10.12);
return vec;
}
void show_vec(vector<double> & vec)
{
for (unsigned int i = 0u; i < vec.getLength(); i++)
{
std::cout << vec.getElement(i) << std::endl;
}
}
void vector_test()
{
vector<double> vec;
vec.insert_back(0.12);
vec.insert_back(1.12);
vec.insert_back(2.12);
vec.insert_back(3.12);
vec.insert_back(4.12);
vec.insert_back(5.12);
vec.insert_back(6.12);
vec.insert_back(7.12);
vec.insert_back(8.12);
vec.insert_back(9.12);
vec.insert_back(10.12);
vector<double> vec1(vec);
vector<double> vec2 = vec;
vector<double> vec3 = vectorTest();
show_vec(vec);
// 插入元素
std::cout << "插入元素" << std::endl;
vec.insert(0, 0.12);
vec.insert(2, 2.22);
vec.insert(8, 7.22);
show_vec(vec);
std::cout << std::endl;
// 删除元素
std::cout << "删除元素" << std::endl;
vec.delete_front();
vec.delete_back();
vec.deleteElement(3);
show_vec(vec);
std::cout << std::endl;
// 删除所有
std::cout << "删除所有" << std::endl;
vec.deleteAll();
vec.insert_front(1.2);
vec.insert_back(2.3);
show_vec(vec);
std::cout << std::endl;
std::cout << "vec1" << std::endl;
show_vec(vec1);
std::cout << "vec2" << std::endl;
show_vec(vec2);
std::cout << "vec3" << std::endl;
show_vec(vec3);
}
int main()
{
vector_test();
getchar();
}
测试结果如下:
实现代码如下:
// queue头文件
#pragma once
template <typename T, template <typename N> class C>
class queue
{
public:
queue();
~queue();
queue(const queue & ob);
queue(queue &&ob);
queue & operator= (const queue & ob);
queue & operator= (queue && ob);
private:
C * m_data;
public:
bool insert_back(T value);
T delete_front();
T get_front() const;
T getElement(unsigned int index) const;
unsigned int getLength() const;
bool empty() const;
};
template<typename T, template <typename N> class C>
queue ::queue() : m_data(nullptr)
{
m_data = new C;
}
template<typename T, template<typename N> class C>
queue ::~queue()
{
if (nullptr != m_data)
{
delete m_data;
m_data = nullptr;
}
}
template<typename T, template<typename N> class C>
queue ::queue(const queue & ob)
{
m_data = new C;
unsigned int n = ob.m_data->getLength();
for (unsigned int i = 0u; i < n; i++)
{
m_data->insert_back(ob.m_data->getElement(i));
}
}
template<typename T, template<typename N> class C>
queue ::queue(queue &&ob)
{
m_data = ob.m_data;
ob.m_data = nullptr;
}
template<typename T, template<typename N> class C>
queue & queue ::operator= (const queue & ob)
{
if (nullptr != m_data)
{
delete m_data;
m_data = nullptr;
}
m_data = new C;
unsigned int n = ob.m_data->getLength();
for (unsigned int i = 0u; i < n; i++)
{
m_data->insert_back(ob.m_data->getElement(i));
}
return * this;
}
template<typename T, template<typename N> class C>
queue & queue ::operator= (queue && ob)
{
if (nullptr != m_data)
{
delete m_data;
m_data = nullptr;
}
m_data = ob->m_data;
ob.m_data = nullptr;
return * this;
}
template<typename T, template<typename N> class C>
bool queue ::insert_back(T value)
{
return m_data->insert_back(value);
}
template<typename T, template<typename N> class C>
T queue ::delete_front()
{
return m_data->delete_front();
}
template<typename T, template<typename N> class C>
T queue ::getElement(unsigned int index) const
{
return m_data->getElement(index);
}
template<typename T, template<typename N> class C>
T queue ::get_front() const
{
return m_data->get_front();
}
template<typename T, template<typename N> class C>
unsigned int queue ::getLength() const
{
return m_data->getLength();
}
template<typename T, template<typename N> class C>
bool queue ::empty() const
{
return m_data->empty();
}
测试代码如下:
#include "list.h"
#include "vector.h"
#include "queue.h"
#include
queue<double, vector> queueTest()
{
queue<double, vector> q;
q.insert_back(1.34);
q.insert_back(2.34);
q.insert_back(3.34);
q.insert_back(4.34);
q.insert_back(5.34);
q.insert_back(6.34);
q.insert_back(7.34);
return q;
}
void queue_test()
{
queue<double, vector> q;
std::cout << q.empty() << std::endl;
q.insert_back(1.34);
q.insert_back(2.34);
q.insert_back(3.34);
q.insert_back(4.34);
q.insert_back(5.34);
q.insert_back(6.34);
q.insert_back(7.34);
queue<double, vector> q1(q);
queue<double, vector> q2 = q;
queue<double, vector> q3 = queueTest();
std::cout << q.empty() << std::endl;
std::cout << q.getElement(0u) << std::endl << std::endl;
std::cout << "q" << std::endl << std::endl;
for (unsigned int i = 0u; q.getLength() > 0;)
{
std::cout << q.delete_front() << std::endl;
}
std::cout << "q1" << std::endl << std::endl;
for (unsigned int i = 0u; q1.getLength() > 0;)
{
std::cout << q1.delete_front() << std::endl;
}
std::cout << "q2" << std::endl << std::endl;
for (unsigned int i = 0u; q2.getLength() > 0;)
{
std::cout << q2.delete_front() << std::endl;
}
std::cout << "q3" << std::endl << std::endl;
for (unsigned int i = 0u; q3.getLength() > 0;)
{
std::cout << q3.delete_front() << std::endl;
}
}
int main()
{
queue_test();
getchar();
}
测试结果如下;
实现代码如下:
// stack头文件
#pragma once
template <typename T, template <typename N> class C>
class stack
{
public:
stack();
~stack();
stack(const stack & ob);
stack(stack &&ob);
stack & operator= (const stack & ob);
stack & operator= (stack && ob);
private:
C * m_data;
public:
bool insert_front(T value);
T delete_front();
T get_front() const;
bool empty() const;
};
template <typename T, template<typename N> class C>
stack ::stack() : m_data(nullptr)
{
m_data = new C;
}
template <typename T, template<typename N> class C>
stack ::~stack()
{
if (nullptr != nullptr)
{
delete m_data;
m_data = nullptr;
}
}
template <typename T, template<typename N> class C>
stack ::stack(const stack & ob)
{
m_data = new C;
unsigned int n = ob.m_data->getLength();
for (unsigned int i = 0u; i < n; i++)
{
m_data->insert_back(ob.m_data->getElement(i));
}
}
template <typename T, template<typename N> class C>
stack ::stack(stack &&ob)
{
m_data = ob.m_data;
ob.m_data = 0u;
}
template <typename T, template<typename N> class C>
stack & stack ::operator= (const stack & ob)
{
if (nullptr != nullptr)
{
delete m_data;
m_data = nullptr;
}
m_data = new C;
unsigned int n = ob.m_data->getLength();
for (unsigned int i = 0u; i < n; i++)
{
m_data->insert_back(ob.m_data->getElement(i));
}
return * this;
}
template <typename T, template<typename N> class C>
stack & stack ::operator= (stack && ob)
{
if (nullptr != nullptr)
{
delete m_data;
m_data = nullptr;
}
m_data = ob.m_data;
ob.m_data = 0u;
return * this;
}
template <typename T, template<typename N> class C>
bool stack ::insert_front(T value)
{
return m_data->insert_front(value);
}
template <typename T, template<typename N> class C>
T stack ::delete_front()
{
return m_data->delete_front();
}
template <typename T, template<typename N> class C>
T stack ::get_front() const
{
return m_data->get_front();
}
template <typename T, template<typename N> class C>
bool stack ::empty() const
{
return m_data->empty();
}
测试代码如下:
#include "list.h"
#include "vector.h"
#include "stack.h"
#include
stack<double, list> stackTest()
{
stack<double, list> s;
s.insert_front(1.12);
s.insert_front(2.12);
s.insert_front(3.12);
s.insert_front(4.12);
return s;
}
void stack_test()
{
stack<double, list> s;
s.insert_front(1.12);
s.insert_front(2.12);
s.insert_front(3.12);
s.insert_front(4.12);
stack<double, list> s1(s);
stack<double, list> s2 = s;
stack<double, list> s3 = stackTest();
std::cout << "s" << std::endl;
while (!s.empty())
{
std::cout << s.delete_front() << std::endl;
}
std::cout << "s1" << std::endl << std::endl;
while (!s1.empty())
{
std::cout << s1.delete_front() << std::endl;
}
std::cout << "s2" << std::endl << std::endl;
while (!s2.empty())
{
std::cout << s2.delete_front() << std::endl;
}
std::cout << "s3" << std::endl << std::endl;
while (!s3.empty())
{
std::cout << s3.delete_front() << std::endl;
}
}
int main()
{
stack_test();
getchar();
}
测试结果如下: