[C++] 利用模板的模板参数实现单链表

模板的模板顾名思义就是一个模板函数的参数是另一个模板函数的模板。

模板函数有兴趣的读者请看我上一篇博客模板函数,实现顺序表

请看模板的模板简要举例

上边两张图片就是模板的模板类型了,模板的模板也可以使用缺省参数(这一点与函数相似)

好了上面介绍过了,现在直接上代码吧,我个人觉得一个函数怎么用,还是直接看实例更容易让人懂,

下面是单链表的节点类, 用的是模板函数

#pragma once
#include<iostream>
using namespace std;

#include<string>

template<typename DataType>
struct SListNode   //单链表的节点
{
	SListNode(DataType x)
		:_data(x),
		_next(NULL)
	{}

	SListNode *_next;
	DataType _data;
};

下面列出单链表类以及主要的函数,也是模板的模板,

template<class DataType, class SListNode = SListNode<DataType> >
class SList
{
public:
	SList();
	SList(const SList&s);
	SList& operator=(SList s);
	~SList();
	void PushBack(DataType x);  //尾插
	void PopBack();  //尾删
	void PushFront(DataType x);
	void PopFront();
	void Insert(const SListNode* pos, DataType x);
	void PrintSList();
	void Clear();

private:
	SListNode*_head;
	SListNode *_tail;
};

下边列出构造函数、赋值运算符重载函数、以及析构函数

template<class DataType, class SListNode = SListNode<DataType> >
SList<DataType, SListNode>::SList()
:_head(NULL),
_tail(NULL)
{}

template<class DataType, class SListNode = SListNode<DataType> >
SList<DataType, SListNode>::SList(const SList&s)
: _head(NULL),
_tail(NULL)
{
	SListNode *cur = s._head;
	while (cur)
	{
		this->PushBack(cur->_data);
		cur = cur->_next;
	}
}

template<class DataType, class SListNode = SListNode<DataType> >
SList<DataType, SListNode>& SList<DataType, SListNode>::operator=(SList s)
{
	swap(_head, s._head);
	swap(_tail, s._tail);
	return *this;
}

//template<class DataType, class SListNode = SListNode<DataType> >
//SList<DataType, SListNode>& SList<DataType, SListNode>::operator=(SList s)
//{
//	if (this != &s)
//	{
//		this->Clear();
//		SListNode *cur = s._head;
//		while (cur)
//		{
//			this->PushBack(cur->_data);
//			cur = cur->_next;
//		}
//	}
//	return *this;
//}

template<class DataType, class SListNode = SListNode<DataType> >
SList<DataType, SListNode>:: ~SList()
{
	Clear();
}

template<class DataType, class SListNode = SListNode<DataType> >
void SList<DataType, SListNode>::Clear()
{
	SListNode* cur = _head;
	while (cur)
	{
		SListNode *del = cur;
		cur = cur->_next;
		delete del;
	}
	_head = NULL;
}

下边列出插入删除函数

template<class DataType, class SListNode = SListNode<DataType> >
void SList<DataType, SListNode>::PushBack(DataType x)
{
	if (_head == NULL)
	{
		_head = new SListNode(x);
		_tail = _head;
		//SList temp(x);//现代写法
		//swap(_head, temp._head);
		//swap(_tail, temp._tail);
	}
	else
	{
		_tail->_next = new SListNode(x);
		_tail = _tail->_next;
	}
}

template<class DataType, class SListNode = SListNode<DataType> >
void SList<DataType, SListNode>::PopBack()
{
	if (_head == NULL)
	{
		cout << "空单链表 " << endl;
		return;
	}
	SListNode*cur = _head;
	while (cur->_next->_next)
	{
		cur = cur->_next;
	}
	_tail = cur;
	delete cur->_next;
	_tail->_next = NULL;
}

template<class DataType, class SListNode = SListNode<DataType> >
void SList<DataType, SListNode>::PushFront(DataType x)
{
	if (_head == NULL)
	{
		PushBack(x);
	}
	SListNode *temp = new SListNode(x);
	temp->_next = _head;
	_head = temp;
}

template<class DataType, class SListNode = SListNode<DataType> >
void SList<DataType, SListNode>::PopFront()
{
	if (_head == NULL)
	{
		cout << "空链表" << endl;
		return;
	}
	SListNode*temp = _head;
	_head = _head->_next;
	delete temp;
}

//template<class DataType, class SListNode = SListNode<DataType> >
//void SList<DataType, SListNode>::Insert(const SListNode* pos, DataType x)
//{
//	if (_head == NULL)
//	{
//		cout << "空链表!" << endl;
//		return;
//	}
//	SListNode *cur = _head;
//	while (cur)
//	{
//		if (cur == pos)
//		{
//			SListNode*temp = new SListNode(x);
//			temp->_next = pos->_next;
//			pos->_next = temp;
//			return;
//		}
//		cur = cur->_next;
//	}
//	cout << "链表中未找到此节点!" << endl;
//}

下边给出输出函数

template<class DataType, class SListNode = SListNode<DataType> >
void SList<DataType, SListNode>::PrintSList()
{
	SListNode*cur = _head;
	while (cur)
	{
		cout << cur->_data << "->";
		cur = cur->_next;
	}
	cout << "NULL" << endl;
}

上边就是主要的函数声明与定义了,单链表内容也是很多的,用作举例,我认为上述的函数就够用了,下边给出测试函数:

#include"SList.h"

void test5()
{
	cout << "使用 int 类型构造 :" << endl;
	cout << "s1:" << endl;
	SList<int> s1;
	s1.PushBack(1);
	s1.PushBack(2);
	s1.PushBack(3);
	s1.PushBack(4);
	s1.PushBack(5);
	s1.PrintSList();
	cout << "拷贝构造 s2:" << endl;
	SList<int> s2(s1);
	s2.PopBack();
	s2.PrintSList();

	cout << "赋值运算符重载 s3:" << endl;
	SList<int> s3;
	s3 = s1;
	s3.PopFront();
	s3.PrintSList();
}

void test6()
{
	cout << "使用 char 类型构造 :" << endl;
	cout << "s1:" << endl;
	SList<char> s1;
	s1.PushBack(‘a‘);
	s1.PushBack(‘b‘);
	s1.PushBack(‘c‘);
	s1.PushBack(‘d‘);
	s1.PushBack(‘e‘);
	s1.PrintSList();
	cout << " 拷贝构造  s2:" << endl;
	SList<char> s2(s1);
	s2.PopBack();
	s2.PrintSList();

	cout << "赋值运算符重载  s3:" << endl;
	SList<char> s3;
	s3 = s1;
	s3.PopFront();
	s3.PrintSList();
}

void test7()
{
	cout << "使用 string 类型构造 :" << endl;
	cout << "s1:" << endl;
	SList<string> s1;
	s1.PushBack("xxxx");
	s1.PushBack("ssss");
	s1.PushBack("aaaa");
	s1.PushBack("dddd");
	s1.PushBack("eeee");
	s1.PrintSList();
	cout << "拷贝构造  s2:" << endl;
	SList<string> s2(s1);
	s2.PopBack();
	s2.PrintSList();

	cout << "赋值运算符重载  s3:" << endl;
	SList<string> s3;
	s3 = s1;
	s3.PopFront();
	s3.PrintSList();
}

int main()
{
	test5();
	test6();
	test7();

	system("pause");
	return 0;
}

在测试函数里主要测试了基本类型中的int char类型以及非基本类型中的string类型,使用了构造函数、析构函数、赋值运算符重载、插入删除操作,结果如下图

限于我目前的c++水平 仅能实现上述函数,欢迎大家阅读,如发现错误或者不足,恳请您给予批评指正,谢谢!

时间: 2024-11-07 07:18:39

[C++] 利用模板的模板参数实现单链表的相关文章

用模板实现顺序表与单链表

//顺序表 #include<iostream> using namespace std; template<typename T> class SeqList { public: SeqList(); ~SeqList(); SeqList(const SeqList& s); SeqList& operator=(const SeqList &s); void _CheakCapacity(); void PushBack(const T& x)

单链表大整数加法

单链表大整数加法,节点是char型. First     List:   head->1->8->9 Second List:   head->9->8->1 Result  List:    head->1->1->7->0 实现了单链表(单链表类模板),现在使用单链表实现大整数加法 1 #include "stdafx.h" 2 #include "SingleList.h" 3 #include &l

模板实现单链表

由于类模板不支持分离编译,我们可以将模板类成员函数的声明和定义放在一个.hpp的文件中 SList.hpp #pragma once #include<iostream> using namespace std; #include<assert.h> template<class T> struct LinkNode      //节点类(建议写法) { LinkNode(const T x); T _data;    //节点的数据 LinkNode<T>

单链表的结点类模板

C++语言程序设计进阶 (2015年秋) 郑莉教授 http://www.xuetangx.com/courses?org=-1&cid=117&page_type=0&page=2 单链表 //单链表的结点类模板 template <class T> class Node{ private: Node<T> *next;//后继结点的指针 public: T data; Node(const T& item,Node<T>*next =

C++数据结构 单链表(模板类)

利用模板类实现单链表及其功能 需要实现的操作: [1] push_back       [2] push_front [3] show_list       [0] quit_system [4] pop_back        [5] pop_front [6] insert_val      [7] delete_val [8] find            [9]length [10] clear          [11]destroy [12] reserv         [13]

模板系列(一) 模板的模板参数

前面我们写过类似的Stack: template <typename T, typename Alloc = std::vector<T> > class Stack { public: void push(const T &); void pop(); T top() const; bool empty() const; private: Alloc _cont; }; 那么我们使用的时候需要这样: Stack<string, list<string>

模板系列(一)模板的模板参数

在之前,我们写过类似的stack template <typename T, typename Alloc = std::vector<T> > class Stack { public: void push(const T &); void pop(); T top() const; bool empty() const; private: Alloc cont_; }; 那么我们使用的时候,需要这样写 Stack<string, list<string>

模板的模板参数使用示例

注意:函数模板不支持模板的模板参数. Stack7.h中定义的Stack: #ifndef STACK7_H #define STACK7_H #include <deque> #include <stdexcept> #include <memory> template <typename T, template <typename ELEM, typename = std::allocator<ELEM> > class CONT =

C++ 单链表模板类实现

单链表的C语言描述 基本运算的算法--置空表.求表的长度.取结点.定位运算.插入运算.删除运算.建立不带头结点的单链表(头插入法建表).建立带头结点的单链表(尾插入法建表),输出带头结点的单链表 #include<cstdio>#include<iostream>using namespace std;template <class T>class Linklist{private: struct node { T date; node * next; node():n