数据结构之链栈

来源:互联网 发布:js上传图片代码 编辑:程序博客网 时间:2024/06/06 03:01

一.引入

        通常链栈用单链表表示,因此其结点结构与单链表的结点结构相同。因为只能在栈顶执行插入和删除操作,显然以单链表的头部做栈顶是最方便地,而且没有必要像单链表那样为了运算方便附加一个头结点。


二.算法设计

LinkedStack.h

#ifndef SRC_LINKEDSTACK_H_#define SRC_LINKEDSTACK_H_/* * 结点: * data:数据域,存储数据元素 * next:指针域,存储该结点的后继结点的地址 */template <class T>struct Node{T data;Node<T> *next;};template <class T>class LinkedStack{public:LinkedStack();//无参构造器LinkedStack(T array[],int length);//有参构造器virtual ~LinkedStack();//析构函数int getLength();//取当前栈的长度void push(T value);//入栈T pop();//出栈T getTop();//取栈顶元素void getAll();//遍历栈的全部元素bool isEmpty();//判断是否栈空private:Node<T> *top;//栈顶指针int length;//当前栈的长度};#endif

三.详细设计(C++)

LinkedStack.cpp

#include "LinkedStack.h"#include <iostream>using namespace std;/* * 无参构造器: * 1.栈顶指针 top 置为 NULL * 2.当前栈的长度置为 0 */template <class T>LinkedStack<T>::LinkedStack(){top = NULL;length = 0;}/* * 有参构造器: * 1.栈顶指针 top 置为 NULL * 2.创建一个结点 node 置为 NULL * 3.循环: *   ①.为结点 node 申请空间 *   ②.把数组的值存储在结点 node 的 data 域中 *   ③.把栈顶指针 top 指向的结点的地址存储在 结点 node 的 next 域中 *   ④.栈顶指针 top 指向结点 node * 4.记录当前栈的长度 */template <class T>LinkedStack<T>::LinkedStack(T array[],int length){top = NULL;Node<T> *node = NULL;for(int i = 0;i < length;i++){node = new Node<T>;node->data = array[i];node->next = top;top = node;}this->length = length;}/* * 析构函数: * 1.创建一个结点 deleteNode 置为 NULL * 2.循环: *   ①.结点 deleteNode 指向栈顶结点 *   ②.栈顶指针 top 指向栈顶结点的下一个结点 *   ③.删除栈顶结点 *   ④.当前栈的长度减一 */template <class T>LinkedStack<T>::~LinkedStack(){Node<T> *deleteNode = NULL;while(!isEmpty()){deleteNode = top;top = top->next;delete deleteNode;length--;}}/* * 取当前栈的长度: * 返回当前栈的长度 */template <class T>int LinkedStack<T>::getLength(){return length;}/* * 入栈: * 1.创建一个结点 pushNode ,申请空间 * 2.把 value 存储在结点 pushNode 的 data 域中 * 3.结点 pushNode 与原来的栈顶元素相连 * 4.栈顶指针 top 指向结点 pushNode ,即结点 pushNode 成为栈顶元素 * 5.当前栈的长度加一 */template <class T>void LinkedStack<T>::push(T value){Node<T> *pushNode = new Node<T>;pushNode->data = value;pushNode->next = top;top = pushNode;length++;}/* * 出栈: * 1.判断是否栈空,若是则返回 -1,否则 * 2.创建一个结点 popNode ,其指向栈顶结点 * 3.创建一个变量 popNodeValue ,其记录栈顶结点存储的元素 * 4.栈顶指针 top 指向栈顶结点的下一个结点 * 5.删除栈顶结点 popNode * 6.返回栈顶结点存储的元素 popNodeValue */template <class T>T LinkedStack<T>::pop(){if(isEmpty()){cout<<"栈空!"<<endl;return -1;}Node<T> *popNode = top;T popNodeValue = popNode->data;top = top->next;delete popNode;length--;return popNodeValue;}/* * 取栈顶元素: * 1.判断是否栈空,若是则返回 -1,否则 * 2.返回栈顶结点存储的元素 * 注意:并不删除栈顶结点 */template <class T>T LinkedStack<T>::getTop(){if(isEmpty()){cout<<"栈空!"<<endl;return -1;}return top->data;}/* * 遍历栈的全部元素: * 1.判断是否栈空,若是则返回,否则 * 2.创建一个结点 node ,其指向栈顶结点 * 3.循环:当未到达栈底结点时 *   ①.输出栈顶结点存储的元素 *   ②.结点 node 指向下一个结点 * 4.输出栈底结点存储的元素 */template <class T>void LinkedStack<T>::getAll(){if(isEmpty()){cout<<"栈空!"<<endl;return;}Node<T> *node = top;while(node->next != NULL){cout<<node->data<<" ";node = node->next;}cout<<node->data<<endl;}/* * 判断是否栈空: * 若栈顶指针 top 为 NULL 则返回 true ,否则返回 false */template <class T>bool LinkedStack<T>::isEmpty(){return top == NULL ? true : false;}

四.测试

TestLinkedStack.cpp

#include "LinkedStack.h"#include "LinkedStack.cpp"#include <iostream>using namespace std;int main(int argc, char **argv) {int arr[] = {0,1,2,3,4};cout<<"创建对象:0、1、2、3、4 依次入栈 "<<endl;LinkedStack<int> linkedStack(arr,5);cout<<"遍历栈内的元素:";linkedStack.getAll();cout<<"当前栈的长度:";cout<<linkedStack.getLength()<<endl;cout<<"当前的栈顶元素:"<<linkedStack.getTop()<<endl;cout<<endl;while(!linkedStack.isEmpty()){cout<<linkedStack.pop()<<"出栈!"<<endl;cout<<"遍历栈内的元素:";linkedStack.getAll();cout<<"当前栈的长度:";cout<<linkedStack.getLength()<<endl;cout<<"当前的栈顶元素:"<<linkedStack.getTop()<<endl;cout<<endl;}cout<<endl;for(int i = 0;i < 10;i++){cout<<i<<"入栈!"<<endl;linkedStack.push(i);}cout<<"遍历栈内的元素:";linkedStack.getAll();cout<<"当前栈的长度:";cout<<linkedStack.getLength()<<endl;cout<<"当前的栈顶元素:"<<linkedStack.getTop()<<endl;cout<<endl;cout<<"销毁栈!"<<endl;linkedStack.~LinkedStack();return 0;}

五.运行结果