数据结构:栈
栈是一种线性结构,它只能从一端添加元素,也只能从一端取出元素(这一端称之为栈顶)。
Stack这种数据结构用途很广泛,在计算机的使用中,大量的运用了栈,比如编译器中的词法分析器、Java虚拟机、软件中的撤销操作(Undo)、浏览器中的回退操作,编译器中的函数调用实现等等。

本次使用单链表实现栈的基本操作,并用栈实现二进制转换十进制。
栈的创建和初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <stdio.h> #include <stdlib.h> #include <stdbool.h>
#define ERROR_CODE -108 #define EMPTY_CODE -109
typedef struct linklist { int number; struct linklist *next; }LINKLIST;
LINKLIST *init_list() { LINKLIST *head,*end; head = (LINKLIST*)malloc(sizeof(LINKLIST)); end = head; end->next = NULL; return head; }
|
在创建栈的时候引入了头文件<stdbool.h>,目的是引入了bool类型。
同时宏定义了两个出错代码,代表出错和栈为空。
判断栈为空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| bool is_empty(LINKLIST *list) { if (list == NULL ) { printf("stack is not exit!\n"); exit(EMPTY_CODE); } if (list->next == NULL) { return true; }
return false; }
|
如果只有一个头节点则栈为空
入栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int push(LINKLIST *list,int number) { LINKLIST *node; if (list == NULL) { return ERROR_CODE; }
while (list->next!=NULL) { list = list->next; }
node = (LINKLIST*)malloc(sizeof(LINKLIST)); node->number = number; list->next = node; node->next = NULL; return 0; }
|
采用尾插法完成入栈操作
出栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int pop(LINKLIST *list) { int number;
if (list == NULL) { return ERROR_CODE; }
if (is_empty(list)) { return EMPTY_CODE; }
while (list->next->next != NULL) { list = list->next; }
number = list->next->number; free(list->next); list->next = NULL;
return number; }
|
每次出栈从链表尾弹出一个节点
删除栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int del(LINKLIST **list) { if (*list == NULL) { return ERROR_CODE; } while ((*list)->next != NULL) { pop(*list); }
free(*list); *list = NULL;
}
|
将所有节点出栈,并删除头结点
二进制转换十进制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int main() { int i = 0; char c; int sum = 0; LINKLIST *list = init_list();
printf("请输入一个二进制数,输入#表示结束!\n"); scanf("%c", &c); while (c != '#') { push(list, c); scanf("%c", &c); } getchar();
while (list->next != NULL) { sum = sum+(pop(list)-48)*pow(2,i); i++; }
printf("转化为十进制数为:%d\n",sum); return 0; }
|
值得注意的是,直接gcc编译时会报链接错误,需要链接math库即 gcc stack.c -lm 具体原因不明
栈的创建和操作沿用之前的函数,只需要加一个main()并引入头文件<math.h>函数即可
首先将键盘上的每个字符入栈(偷懒了没做01字符的判断),然后每出栈一个字符就进行幂运算。
出栈得到的是ASCII码,0对应的ASCII码为48所以减去48就可以得到实际的数