1.栈是什么?
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在尾部进行插入和删除操作的结构。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
2.示例
栈使用的双向链表结构
// From Linux
struct list_head{
struct list_head *next, *prev;
};
// 初始化结构体
#define list_head_init(name) \
{ &(name), &(name) }
// 返回结构体成员相对起始位置的偏移
#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE *)0)->MEMBER))
// 返回prt所在结构体起始地址
#define container_of(ptr, type, member) (type *)((char *)ptr - offsetof(type, member))
#define list_entry(ptr, type, member) container_of(ptr, type, member)
双向链表的删除和新增
// From Linux
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
// 从链表中删除当前节点
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->prev = 0;
entry->next = 0;
}
static inline void __list_add(struct list_head *_new, struct list_head *prev, struct list_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
// 向当前元素之后添加一个元素
static inline void list_add(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head, head->next);
}
// 向链表尾部添加一个元素
static inline void list_add_tail(struct list_head *_new, struct list_head *head)
{
__list_add(_new, head->prev, head);
}
栈的简单实现
template <typename T>
class Stack {
private:
struct Node {
struct list_head list;
T data;
};
list_head head; // 栈底指针
size_t size; // 栈大小
Node *root; // 虚拟栈底指针
public:
Stack() {
head = list_head_init(head);
root = list_entry(&head, Node, list);
size = 0;
}
~Stack() {
Node *node = NULL;
while (root->list.next != root->list.prev) {
// 栈顶元素
node = list_entry(root->list.prev, Node, list);
// 将栈顶元素从链表中移除
list_del(&node->list);
delete node;
size--;
}
}
boolean empty() { return (size == 0) ? TRUE : FALSE; }
void push(const T &val) {
Node *node = new Node;
node->data = val;
list_add_tail(&node->list, &head);
size++;
}
T pop() {
if (empty()) return T(0);
Node *node = list_entry(root->list.prev, Node, list);
T val = node->data;
list_del(&node->list);
delete node;
size--;
return val;
}
T top() {
if (empty()) return T(0);
Node *node = list_entry(root->list.prev, Node, list);
return node->data;
}
};