2019独角兽企业重金招聘Python工程师标准>>>
堆栈也可以采用链式存储结构,称为链栈。链栈常采用单链表表示。其实现是将链表的表头作为栈顶实现,这样就不需要在单链表中增加头结点,栈顶指针就是链表的头指针。
下面的代码实现了链栈的相关操作,其中有个错误关于重复申请堆空间让我郁闷了会儿,不过后来找出来了。
#include <stdio.h>
#include <stdlib.h>typedef struct node
{char data;struct node *next;
}linkstack;linkstack * Linkstack_Create(); //创建链栈
char Linkstack_GetTop(linkstack *q); //取得栈顶
linkstack *Linkstack_In(linkstack *q, char dat); //入栈
linkstack * Linkstack_Out(linkstack *q, char *dat); //出栈
void Linkstack_SetNull(linkstack *q); //置空栈
int Linkstack_Empty(linkstack *q); //栈是否为空
void ShowLinkstack(linkstack *q); //输出显示栈int main(void)
{linkstack *q;int choice, ans;char dat;printf("链栈的操作练习:\n");printf("请依次输入链栈字符数据('#'号表示结束):\n");q = Linkstack_Create();getchar();while(1){printf("链栈操作:\n");printf("1.取得栈顶结点\n");printf("2.入栈\n");printf("3.出栈\n");printf("4.输出显示链栈\n");printf("5.退出程序\n");printf("做出选择:");scanf("%d", &choice);getchar(); //消除回车为后面带来的影响switch(choice){case 1:dat = Linkstack_GetTop(q); if(dat == '\0')printf("取得头结点失败!\n");elseprintf("头结点为%c\n", dat);break;case 2:printf("输入想入栈的字符:\n");dat = getchar();q = Linkstack_In(q, dat);break;case 3:q = Linkstack_Out(q, &dat);if(dat != '\0')printf("出栈的字符为%c\n", dat);break;case 4:printf("输出的字符依次为:\n");ShowLinkstack(q);break;case 5:return 0;break;default:printf("选择无效!\n");break;}}return 1;
}//链栈置空
void Linkstack_SetNull(linkstack *q)
{linkstack *s;while(q != NULL) //链栈置空时需要释放每个结点的空间{s = q;q = q->next;free(s);}
}//判断链栈是否为空
int Linkstack_Empty(linkstack *q)
{if(q == NULL)return 1;elsereturn 0;
}//创建链栈
linkstack * Linkstack_Create()
{linkstack *q = NULL;char ch;Linkstack_SetNull(q);ch = getchar();while(ch != '#'){// q = (linkstack*)malloc(sizeof(linkstack));//此句又让人纠结了好久,有此句时创建的链栈只有栈顶字符,申请了两次空间(下面入栈函数中一次),至于为什么会造成这种结果,暂时不知道- -!!q = Linkstack_In(q, ch);ch = getchar();}return q;
}//取得栈顶结点
char Linkstack_GetTop(linkstack *q)
{if(Linkstack_Empty(q)) //先要判断栈顶是否为空return '\0';elsereturn q->data;
}//入栈,返回栈顶结点指针
linkstack *Linkstack_In(linkstack *q, char dat)
{linkstack *e;e = (linkstack*)malloc(sizeof(linkstack));e->data = dat;e->next = q;return e;
}//出栈,返回栈顶结点指针
linkstack *Linkstack_Out(linkstack *q, char *dat)
{linkstack *s;if(Linkstack_Empty(q)) //先要判断栈顶是否为空{ *dat = '\0';return NULL;}else{*dat = q->data;s = q;q = q->next;free(s);return q;}
}//输出显示链栈,从栈顶到栈底
void ShowLinkstack(linkstack *q)
{linkstack *s;s = q; while(s != NULL){putchar(s->data);putchar(' ');s = s->next;}printf("\n");
}