以下是链式栈的创建、压栈、出栈、清空、是否空栈的操作,本人在VC++6.0中调试通过。
/*
本程序研究的是对连续存储结构中的------栈(链式栈)。
包括创建、初始、压栈、遍历输出算法濱示。
*/
# 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_stack(pSTACK); //创建一个空栈。
void push_stack(pSTACK,int ); //压栈
bool pop_stack(pSTACK,int *); //出栈 (即删除栈中的节点,当然数据也被删除了)
void traversert(pSTACK); // 遍历输出
bool empty_stact(pSTACK);//判断栈是否为空
void clear_stact(pSTACK);//将栈中的节点一个一个的清除,使其为空
int main()
{
int num ,val,i;
stack Stk;
init_stack(&Stk);
printf("请输入您想压入栈的数量:");
scanf("%d",&num);
for(i=0; i< num; ++i)
{
printf("请输入您想压入栈的数据:");
scanf("%d",&val);
push_stack(&Stk,val);
}
traversert(&Stk);
pop_stack(&Stk,&val);
printf("删除的值为 %d\n",val);
traversert(&Stk);
clear_stact(&Stk);
traversert(&Stk);
return 0;
}
void init_stack(pSTACK pS)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL == pNew)
{
printf("动态内存分配失败!\n");
exit(-1);
}
else
{
pS->pTop = pNew;
pS->pBottom = pS->pTop ;
pS->pTop->pNext = NULL;
}
return ;
}
void push_stack(pSTACK pS,int val)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
pNew->data = val;
pNew->pNext = pS->pTop;
pS->pTop = pNew;
return ;
}
void traversert(pSTACK pS)
{
//PNODE ptmp = (PNODE)malloc(sizeof(NODE));
PNODE ptmp = pS->pTop;
while(ptmp != pS->pBottom)
{
printf("%d\t",ptmp->data);
ptmp = ptmp->pNext;
}
printf("\n");
return ;
}
bool empty_stact(pSTACK pS)
{
if(pS->pTop == pS->pBottom)
return true;
else
return false;
}
bool pop_stack(pSTACK pS,int * pVal )
{
if(empty_stact(pS))
{
printf("链表为空!\n");
return false;
}
else
{
PNODE p = (PNODE)malloc(sizeof(NODE));
//printf("%d",p);
p = pS->pTop; //创建这个指针的目的是用来指向要删除的指点的地址(即:头节点)最终通过free()函数来删除它。
//printf("%p",p);
*pVal = p->data;
//printf("%d",*pVal);
pS->pTop = p->pNext; //由于栈顶元素被删除了,所以应该把pTop指针指向下一个节点。
free(p); //删除掉栈顶元素。
// printf("%p",p);
p = NULL;
return true;
}
}
void clear_stact(pSTACK pS)
{
PNODE p = pS->pTop;
PNODE q = NULL;
while(p != pS->pBottom)
{
/* free(p);
p = p->pNext; */ //按照这种方式来对栈的节点进行删除的话,128行就把p所指向的节点的指针域给释放掉了。也就导致p不能获取它下一个一点的地址。
q = p->pNext; //将p所指向节点的指针域(即所指向节点的一下节点的地址)赋值给q指针。
free(p);
p = q; // 这样就将下节点的地址赋值给p进行再次释放。
}
pS->pTop = pS->pBottom;
return ;
}