在学习栈的过程中,由于顺序栈的最大长度需要提前确定,失去了链表的灵活性,于是我开始思考能否将链表与栈有机结合,之后在《大话数据结构》一书中找到了答案,也就是栈的链式存储,下面对我在使用C语言实现链栈过程中的问题加以总结与反思。
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define maxsize 20
typedef int elemtype;
typedef int status;
typedef struct stacknode{
elemtype data;
struct stacknode* next;
}stacknode;//定义链栈节点
typedef struct stacknode* stackptr;//定义stackptr为指向结点指针
typedef struct linkstack{
stackptr top;//top为栈顶指针
int length;//定义栈长
}linkstack;
status visit(elemtype c){
printf("%d ",c);
return OK;
}
/*初始化链栈*/
status initlinkstack(linkstack *S){
S->top=(stackptr)malloc(sizeof(stacknode));//给栈顶指针分配内存,大小为stacknode所占空间
if(!S->top){
return ERROR;//分配失败,返回0
}
S->top=NULL;//栈顶指针置空
S->length=0;//栈长置零
}
/*清空链栈*/
status clearlinkstack(linkstack *S){
stackptr p=S->top,q;//定义两个指向节点的指针
while(p){
q=p->next;//q记录p的下一节点
free(p);//释放p
S->length--;
p=q;//将下一节点地址赋给p,循环往复直至p==NULL;
}
return OK;
}
/*判断链栈是否为空*/
status emptylinkstack(linkstack *S){
if(!S->length){
return TRUE;
}
else{
return FALSE;
}
}
/*返回链栈长*/
status linkstacklength(linkstack *S){
return S->length;
}
/*返回栈顶元素*/
status gettop(linkstack *S,elemtype data){
if(!S->top){
printf("空表\n");
return ERROR;
}
else{
data=S->top->data;//去栈顶指针top指向的节点
}
return OK;
}
/*入栈操作*/
status push(linkstack *S,elemtype data){
if(S->length==maxsize){
printf("满栈\n");
return ERROR;
}
else{
stackptr current=S->top,push;//声明current指向栈顶指针,push为待入栈指针
push=(stackptr)malloc(sizeof(stacknode));
if(!push){
return ERROR;
}
push->data=data;
push->next=S->top;//将push的next指向原先栈顶
S->top=push;//将新栈顶push赋给S->top
S->length++;//栈长加一
}
}
/*出栈操作*/
status pop(linkstack *S,elemtype data){
if(!S->top){
printf("空栈\n");
return ERROR;
}
else{
stackptr temp;//temp用于记录栈顶指针
data=S->top->data;//data记录栈顶元素
printf("%d ",data);
temp=S->top;
S->top=S->top->next;//将原栈顶赋给新栈顶
free(temp);//释放原栈顶
S->length--;//栈长减一
}
return OK;
}
/*遍历栈*/
status traverselinkstack(linkstack *S){
if(!S->top){
printf("空栈\n");
return ERROR;
}
else{
stackptr current=S->top;
while(current){
visit(current->data);
current=current->next;//别忘了更新current的值!!!否则会死循环,细心细心!!!
}
printf("\n");
}
return ERROR;
}
int main(void){
linkstack S;
initlinkstack(&S);
if(emptylinkstack(&S)){
printf("空栈\n");
}
else{
printf("非空\n");
}
printf("%d\n",linkstacklength(&S));
/*插入20个元素*/
for(int i=0;i<maxsize;i++){
push(&S,i);
}
if(emptylinkstack(&S)){
printf("空栈\n");
}
else{
printf("非空\n");
}
printf("%d\n",linkstacklength(&S));
/*满栈后再插入一个元素会提示满栈*/
push(&S,21);
//printf("%d",S.top->data);
traverselinkstack(&S);
//弹栈
printf("出栈元素为:");
elemtype data;
for(int i=0;i<maxsize;i++){
pop(&S,data);
}
printf("\n");
if(emptylinkstack(&S)){
printf("空栈\n");
}
else{
printf("非空\n");
}
printf("再次插入20个元素 ");
for(int i=0;i<maxsize;i++){
push(&S,i);
}
traverselinkstack(&S);
if(emptylinkstack(&S)){
printf("空栈\n");
}
else{
printf("非空\n");
}
//清空栈
clearlinkstack(&S);
if(emptylinkstack(&S)){
printf("空栈\n");
}
else{
printf("非空\n");
}
}