栈的链式存储结构(C语言实现)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define OK 1
  5 #define ERR 2
  6 #define TRUE 1
  7 #define FALSE 0
  8 
  9 typedef int status; //定义函数返回的状态,OK & ERR
 10 typedef char datatype; //定义栈中每个元素的数据类型,这里暂定为字符型
 11 
 12 typedef struct LinkStack_anon{
 13     datatype data; //数据区
 14     struct LinkStack_anon * next; //指针区
 15 } LinkStack;
 16 
 17 /* 函数原型,栈的基本操作 */
 18 LinkStack *createLinkStack(datatype first_node_value);
 19 status isEmpty(LinkStack *L);
 20 void clear(LinkStack **L);
 21 datatype getTop(LinkStack *L);
 22 int getLength(LinkStack *L);
 23 status push(LinkStack *L, datatype node_to_push);
 24 datatype pop(LinkStack *L);
 25 void showStack(LinkStack *L);
 26 
 27 int main(){
 28     /* 测试 */
 29     LinkStack *root; //指向一个通过createLinkStack函数创建的栈
 30     root=createLinkStack('f');
 31     printf("isEmpty = %d\n",isEmpty(root));
 32     printf("Length = %d\n",getLength(root));
 33     push(root,'a');
 34     push(root,'b');
 35     push(root,'c');
 36     push(root,'d');
 37     printf("isEmpty = %d\n",isEmpty(root));
 38     printf("Length = %d\n",getLength(root));
 39     showStack(root);
 40     putchar('\n');
 41     printf("pop = %c\n",pop(root));
 42     printf("pop = %c\n",pop(root));
 43     printf("getTop = %c\n",getTop(root));
 44     printf("isEmpty = %d\n",isEmpty(root));
 45     printf("Length = %d\n",getLength(root));
 46     showStack(root);
 47     putchar('\n');
 48     clear(&root);
 49     printf("isEmpty = %d\n",isEmpty(root));
 50     printf("Length = %d\n",getLength(root));
 51 
 52     return 0;
 53 }
 54 
 55 LinkStack *createLinkStack(datatype first_node_value){
 56     LinkStack *tmp;
 57     tmp=malloc(sizeof(LinkStack)); //void*类型指针能自动转为其他类型的指针
 58     tmp->data=first_node_value; //初始化栈顶的数据区
 59     tmp->next=NULL; //初始化栈顶的指针区
 60     return tmp;
 61 }
 62 status isEmpty(LinkStack *L){
 63     if (L==NULL)
 64         return TRUE;
 65     else
 66         return FALSE;
 67 }
 68 void clear(LinkStack **L){
 69     //之所以形参的类型是双重指针,是因为这个函数需要修改传入的实参的值
 70     //函数clear的作用是将栈清空,这时实参应当指向NULL,所以需要在这个函数内修改实参的值
 71     if (isEmpty(*L)==FALSE){
 72         //不为空时才执行删除
 73         LinkStack * p,* q; //p始终指向当前要被删除的结点,而q始终指向要被删除的结点的下一个
 74         p=*L; //将p指向单链表的头结点,即栈的栈顶
 75         while (p!=NULL){
 76             //不是NULL就继续
 77             q=p->next; //q始终指向下一个结点
 78             free(p); //释放p所指的结点
 79             p=q; //交换
 80         }
 81         *L=NULL; //将指向栈的指针设为NULL
 82     }
 83 }
 84 datatype getTop(LinkStack *L){
 85     LinkStack * p=L;
 86     while (p && p->next!=NULL) //遍历到最后一个结点
 87         p=p->next;
 88     return p->data;
 89 }
 90 int getLength(LinkStack *L){
 91     int i=0;
 92     LinkStack * p=L;
 93     while (p){
 94         i++; p=p->next;
 95     }
 96     return i;
 97 }
 98 status push(LinkStack *L, datatype node_to_push){
 99     //node_to_insert表示想要入栈的元素
100     //单链表中的尾插法
101     LinkStack * s=malloc(sizeof(LinkStack)); //等待入栈的新结点
102     LinkStack * p=L;
103     s->data=node_to_push;
104     s->next=NULL;
105     while(p && p->next!=NULL) //找到栈的最后一个结点
106         p=p->next;
107     p->next=s;
108     return OK;
109 }
110 datatype pop(LinkStack *L){
111     //尾删法
112     datatype s;
113     LinkStack * p=L;
114     if (isEmpty(L)) return ERR; //空栈
115     while(p && p->next->next!=NULL) //找到栈的最后一个结点的前一个结点
116         p=p->next;
117     s=p->next->data; //先将最后一个结点的值保存
118     free(p->next); //释放最后一个结点
119     p->next=NULL;
120     return s; //返回出栈的元素的值
121 }
122 void showStack(LinkStack *L){
123     int i;
124     int total=getLength(L);
125     LinkStack * p=L;
126     for (i=0; i<total; i++){
127         printf("%c\t",p->data); p=p->next;
128     }
129 }
130 /*
131     栈的定义:仅限定在表尾进行插入和删除操作的线性表,即操作受限的线性表
132     一般,把允许插入和删除的一端作为栈顶,另一端则是栈底
133     不含任何元素的栈就是空栈
134     所以,栈又称后进先出(Last in First out)的线性表
135     对于链式存储的栈,不存在栈满的情况,除非已经没有可用的内存了,如果真的发生,那此时计算机就面临死机崩溃的地步了
136 */
137 /* 环境: Code::Blocks with GCC 5.1 */

运行截图:

猜你喜欢

转载自www.cnblogs.com/ryzz/p/12228219.html