单链表实现的一个栈,只实现了栈的主要功能:push pop
#ifndef _STACK_USE_SINGLE_LINKED_LIST_H_
#define _STACK_USE_SINGLE_LINKED_LIST_H_
/*********************************************************
算法导论:10.2-2 使用单链表实现一个栈
使用单链表实现一个栈的 push 操作,只需要向链表中第一个元素之前插入元素,
pop 操作将链表的第一个元素删除即可。
push 和 pop 操作运行时间为 O(1)。
**********************************************************/
#include <stdexcept>
template <class T>
class StackUseSinglyLinkedList{
public:
// 一个表示链表结点的数据结构
class Node{
public:
// 只有 StackUseSinglyLinkedList 才可以构造这个类型的对象
// 访问这个类型的私有成员
friend class StackUseSinglyLinkedList < T > ;
// 结点的值
T value;
private:
// 默认构造函数,要求类型 T 也要有默认构造函数
Node() = default;
// 将构造函数设置为私有的,防止在外部创建这个类型的对象
Node(const T& e) :_next(nullptr), value(e){}
// 指向下一个元素,如果这个值为空,
// 表示本结点是链表中的最后一个元素
Node* _next;
};
// 分别在默认构造函数和析构函数中分配和释放头指针指向的内存空间
StackUseSinglyLinkedList() { _head = new Node(); }
~StackUseSinglyLinkedList();
// 栈的 push 操作
void push(const T&);
// 栈的 pop 操作
T pop();
// 测试栈是否为空,只需要测试头结点的 _next 是否指向一个空的结点。
inline bool empty()const{ return (nullptr == _head->_next); }
private:
// 链表头结点的指针,指向链表的第一个元素。
Node* _head;
};
template <class T>
void StackUseSinglyLinkedList<T>::push(const T& element){
// 构造一个结点
Node* node = new Node(element);
node->_next = _head->_next;
_head->_next = node;
}
template <class T>
T StackUseSinglyLinkedList <T>::pop(){
// 如果栈为空,则抛出异常
if (empty())
throw underflow_error("stack empty");
Node* node = _head->_next;
T value = node->value;
_head->_next = node->_next;
// 释放出栈元素的空间
delete node;
return value;
}
template <class T>
StackUseSinglyLinkedList<T>::~StackUseSinglyLinkedList(){
// 将链表中元素占用的空间释放
Node* node = _head->_next;
while (node)
{
Node *n = node->_next;
delete node;
node = n;
}
// 释放头结点占用的空间
delete _head;
}
#endif