首先我们看看什么是栈和动态栈?
栈一种可以实现“先进后出”的存储结构;而动态栈是以链表节点为基本单位的;
第二,动态空栈应该有什么结构?
代码:一个动态栈的结构体需要一个pTop栈顶指针和一个pBottom栈底指针
typedef struct Node{
int data;
struct Node * pNext;
}NODE,* PNODE;
typedef struct Stack{
PNODE pTop;
PNODE pBottom;
}STACK,* PSTACK;
第三,如何造一个动态空栈?
思路示意图 :
思路:
1.先创造一个结构体S,S中有栈顶指针和栈底指针
2.动态创建一个头节点,把头节点的地址赋值给栈底指针和栈顶指针
3.将头指针的指针域清空
代码:
void init(PSTACK pS){
pS->pBottom = (PNODE)malloc(sizeof(NODE));
if(pS->pBottom == NULL){
printf("动态初始化失败!");
exit(-1);
}
else{
pS->pTop = pS->pBottom;
pS->pBottom->pNext = NULL;
}
return;
}
第四、如何给栈的链表结构增添新的节点(压栈)?‘
思路示意图:
思路:
1.动态创建一个新的节点,地址用pNew保存
2.将新节点和头节点和栈连接一起
将栈顶底指向新节点,pNew->pNext = pS->pBottom;
**考虑到节点多了之后应该是将栈顶指向新的节点就行了,因此将pBottom改写成pTop才行**
将栈顶指向新节点,pS->pTop = pNew;
代码:
void push(PSTACK pS,int val){
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(pNew == NULL){
printf("动态初始化失败!");
exit(-1);
}
pNew->data = val;
pNew->pNext = pS->pTop;//可以先理解成 pNew->pNext = pS->pBottom;但是元素多了就不行了
pS->pTop = pNew;
return;
}
再度理解链接的两行代码pNew->pNext = pS->pTop;pS->pTop = pNew;,如图所示:
五、如何遍历栈的元素?
思路示意图:
思路:
1.用新的指针p永远指向栈顶,因为只是遍历栈不能够改变栈顶指针,如果改变了栈顶指针我们就找不到遍历完的元素了,所以用一个新的指针。
2.当p不等于栈底指针的时候,p边向下移动边输出每一个节点的数值域;
代码:
void traverse(PSTACK pS){
PNODE p = pS->pTop;
while(p!=pS->pBottom){
printf("%d\t",p->data);
p=p->pNext;
}
return;
}
六、如何出栈?
思路示意图:
思路:
1.出栈存在是否出栈成功的清空,如果栈是空栈(栈顶指针==栈底指针),那么就出栈失败,返回false
2.如果不是空栈,就可出栈了
应该有一个变量,保存出栈节点的数值域,要实现跨函数改变,就应该输入指针变量给这个函数
3.创建一个新的指针P保存栈顶指针
4.栈顶指针指向下一个栈节点
5.保存出栈节点的数值域
6.free(p),p = NULL;
代码:
bool pop(PSTACK pS,int * pVal){
if(empty(pS)){
return false;
}else{
PNODE p = pS->pTop;
pS->pTop = p->pNext;
*pVal = p->data;
free(p);
p = NULL;
return true;
}
}
bool empty(PSTACK pS){
if(pS->pBottom==pS->pTop){
return true;
}else{
return false;
}
}
七、如何清空栈的节点?
思路示意图:
思路:
1.创建两个指针变量p和q
p保存栈顶指针
q保存p的指针域
2.通过一个循环,当p不等于栈底指针
free(p)
p=q
q=q->pNext
3.结束循环,将栈顶指针赋值为栈底指针。
代码:
void clear(PSTACK pS){
PNODE p = pS->pTop;
while(p!=pS->pBottom){
PNODE q = p->pNext;
free(p);
p=q;
}
pS->pTop = pS->pBottom;
return;
}
主函数代码:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node * pNext;
}NODE,* PNODE;
typedef struct Stack{
PNODE pTop;
PNODE pBottom;
}STACK,* PSTACK;
void init(PSTACK pS);
void push(PSTACK pS,int val);
void traverse(PSTACK pS);
bool pop(PSTACK pS,int * pVal);
bool empty(PSTACK pS);
void clear(PSTACK pS);
int main(void){
STACK S;
init(&S);
push(&S,1);
push(&S,2);
push(&S,3);
push(&S,4);
push(&S,5);
push(&S,6);
traverse(&S);
int val;
if(pop(&S,&val)){
printf("\n出栈的值是:%d\n",val);
}else{
printf("出栈失败!");
}
traverse(&S);
clear(&S);
if(pop(&S,&val)){
printf("\n出栈的值是:%d\n",val);
}else{
printf("出栈失败!");
}
return 0;
}
运行结果: