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 */
运行截图:
原文地址:https://www.cnblogs.com/ryzz/p/12228219.html
时间: 2024-10-11 04:08:58