由于编者水平有限,如有错误,请多多包涵。
/*
File name: Stack.cpp
Description: 栈的初始化,压栈,出栈,判断栈是否为空,清空栈。
Author: Yang_Jiang
Date: 2018年10月11日
Compiler:Visual Studio 2008
*/
# include <stdio.h>
# include <stdlib.h>
typedef struct Student
{
int data; //数据域
struct Student* pNext;// 指针域
}NODE,*PNODE;
// NODE 等价于 struct Student
// PNODE 等价于 struct Student*
typedef struct Stack
{
PNODE pTop; //指向栈顶端
PNODE pButtom; //指向栈底部
}STACK,*PSTACK;
// STACK 等价于 struct Student* 因为 PNODE本身就等价于struct Student*
// PSTACK 等价于 struct Student**
//函数声明
void inti(PSTACK ); //初始化栈
void push(PSTACK , int ); // push()压栈 ,向栈中压入元素
void traverse(PSTACK ); //遍历栈 遍历栈中的元素
bool pop(PSTACK , int* ); // 出栈 , 并且把值带过来
bool empty(PSTACK ); //判断栈是否为空
void clear(PSTACK ); //清空栈
int main()
{
STACK s;
inti(&s);
push(&s , 3);
push(&s , 4);
push(&s , 5);
clear(&s);
traverse(&s);
return 0;
}
//初始化栈
void inti(PSTACK pS)
{
//使 ps->pTop 和 ps->pBottom 指向同一个位置 并且为NULL
pS->pTop = (PNODE) malloc( sizeof(NODE) );
if(NULL == pS->pTop)
{
exit(-1); //动态内存分配失败,程序终止!
}
else
{
pS->pButtom = pS->pTop; //指向最底端
pS->pButtom->pNext = NULL;
// pS->pTop->pNext = NULL; 和上面的写法等价 因为他们现在指向的是同一个地方
}
}
//压栈
void push(PSTACK pS, int val)
{
//向栈中压入一个元素
PNODE pNew = (PNODE) malloc(sizeof(NODE));
if( NULL == pNew )
{
exit(-1); //动态内存分配失败,程序终止!
}
else
{
pNew->data = val;
pNew->pNext = pS->pTop; //不能指向 pS->pBottom 因为pS->pBottom永远指向的是最底端
pS->pTop = pNew; //使得pS->pTop 指向 上一个元素
//此时 pNew->pNext 和 pS->pBottom->pNext指向同一个位置
//而pS->pTop->pNext指向的是 pNew->pNext;
}
}
// 遍历栈
void traverse(PSTACK pS)
{
// top == buttom 那么表示指向同一个位置 就是为空栈
if( pS->pTop == pS->pButtom )
{
printf("当前栈为空\n");
}
else
{
PNODE p = pS->pTop;
while( p != pS->pButtom) //从最后一个元素开始遍历到 为空 top == buttom
{
printf("%d\t",p->data);
p = p->pNext;
}
}
}
bool empty(PSTACK pS)
{
if(pS->pTop == pS->pButtom ) //top == buttom 那就是空栈
{
return true;
}
else
{
return false;
}
}
//出栈
bool pop(PSTACK pS, int* val)
{
if( empty(pS) )
{
return false; //栈为空 栈不存在满不满的问题 因为不是用的顺序结构而是用的链式结构
}
else
{
*val = pS->pTop->data; //把值给val 带回去
PNODE p = pS->pTop; //定义一个p 指向pS->pTop, 防止内存泄漏
pS->pTop = pS->pTop->pNext; //ps->pTop 指向他的下一个元素
free(p); //pS->pTop 已经指向下一个元素, 那么上一个元素就应当释放, 否则会造成内存泄漏
p->pNext = NULL;
return true; //出栈成功
}
}
//清空栈
void clear(PSTACK pS)
{
if( empty(pS) ) //如果是空栈
{
printf("无需清空,栈为空栈!");
}
else
{
//pS->pTop = pS->pBottom; //不可采取,如果数据太多,会造成内存泄漏问题
while( !empty(pS) ) //只要栈不为空就一直free
{
PNODE p = pS->pTop;
pS->pTop = pS->pTop->pNext;
free(p);
p = NULL;
}
printf("栈清空成功!");
}
}
/*
总结
判断栈是为否为空: pS->pTop == pS->pButtom 就是空栈
遍历栈 : p = pS->pTop ; p = p->pNext ; p != pS->pButtom 不会影响原始数据
压栈: pNew->pNext = pS->pTop; pS->pTop = pNew;
出栈: p = pS->pTop; pS->pTop = pS->pTop->pNext; free(p); p->pNext = NULL;
初始化栈: pS->pTop = pS->pButtom;
清空栈: 类似于出栈 只不过一直在出栈 一直在free罢了
本程序在Visual Studio 2008编译通过,文件是.cpp文件,代码的写法有点不规范,既有C语言
语法也包含了C++语法 望海涵。
*/