#include<iostream> using namespace std; /* 本节学习链表栈。 栈是一种操作受限制线性表,即操作后进先出的。 栈的逻辑结构是线性表,而存储结构分顺序存储和链式存储,分别命名为 顺序栈和链表栈。 所谓链表栈就是用链表结构存储的栈。 注意: 链栈主要是插入与删除操作,把栈顶设置在表头,操作更加方便。 链栈 */ /*定义数据结构 */ #define ELEMTYPE int #define STACK_SIZE 100 typedef struct stackNode { ELEMTYPE data; stackNode * next; }stackNode; typedef stackNode* stackLink; /*初始化链栈*/ void initStack(stackLink &p)//*** 必须是传址,而不是传值,否则出错。因为传值话,只是给形参P 分配内存,而不是对实参s。 { p = new stackNode;//分配内存 p->next = NULL; } /*销毁链表,释放所有节点所占内存*/ void destroyStack(stackLink s) { stackLink p = s; while (s !=NULL) { p = s->next; delete s; s = p; } } /*清空栈。删除栈中数据节点,留下头节点*/ void clearStack(stackLink s) { stackLink p = s->next; stackLink q= p; while (p !=NULL) { q= p->next; delete p; q= p; } } /*求栈长*/ int getLength(stackLink s) { stackLink p = s->next; int i= 0; while (p !=NULL) { i++; p =p->next; } return i; } /*入栈。在链栈表头插入数据元素*/ void pushStack(stackLink s, ELEMTYPE x) { /* LIST OF THE PROCEDURE: 为新数据元素分配内存 插入元素到栈表头 */ stackNode *p = new stackNode; p->data = x; p->next = NULL; //在栈表头,插入新元素 p->next = s->next; s->next = p; } /*出栈.删除栈顶的元素,在链栈中就是删除表头元素*/ ELEMTYPE popStack(stackLink s) { /* 对参数进行检查:链表是否为空 如果链表不为空,就删除元素 */ if ( NULL ==s->next) { cout<<"链表为空"<<endl; return NULL; } ELEMTYPE x = s->next->data; s->next = s->next->next; return x; } /* 输出所有元素*/ void display(stackLink s) { while(s->next !=NULL) { s= s->next; cout<<s->data<<endl; } } void main() { stackLink s = NULL; initStack(s);//初始化栈 // clearStack(s);//请空栈 //添加元素,即入栈 int i =0; for (i=0; i<10; i++) { pushStack(s,i); } cout<<"输出栈中元素"<<endl; display(s); destroyStack(s);//销毁栈 } /* 链栈 与 顺序栈 异同: 都是 线性表,都是栈顶插入删除受限的线性表 物理存储方式不同,前者用链、指针;后者用顺序存储结构也就是数组。 以下是必须进行的分析,比较,对理解本质有帮助。懂得区别,优劣才能灵活运用。 数据结构的比较: 1 、 空间比较: 1)空间分配方式 2)存储密度 2、 时间比较: 1)存取 2)插入删除 顺序栈 空间分配需要一次性分配足够的内存。分多了浪费,分少了不够用。 链栈 空间分配时动态进行的,需要多少给多少。 顺序栈的存储密度是1. 链栈 的存储密度永远<1. 因为每个数据元素需要额外添加一个链指针。 顺序栈的存取时间复杂度是 O(1),插入删除也是o(1)的时间复杂度。——(因为栈只能在栈顶插入、删除和存取) 链表栈的存取时间复杂度是 O(1),插入删除的时间复杂度是 O(1)——(因为栈只能在栈顶插入、删除和存取) 对算法进行分析: 1) 空间复杂度 2) 时间复杂度 */