栈的一些简单应用:
(1)数制转换:
- #include <stdio.h>
- #include "stack.h"
- void conversion(int num, int base)
- {
- struct stack *s = init_stack();
- while (num) {
- push(s, num % base);
- num /= base;
- }
- while(!stack_empty(s)) {
- printf("%d", top(s));
- pop(s);
- }
- destory_stack(s);
- }
- int main()
- {
- int num, base;
- scanf("%d %d", &num, &base);
- conversion(num, base);
- return 0;
- }
(2)括号匹配检验:
- #include <stdio.h>
- #include "stack.h"
- void match(char *str)
- {
- struct stack *s = init_stack();
- char ch, *p;
- bool flag = true;
- for (p = str; *p != NULL && flag; p++) {
- switch(*p) {
- case '(':
- case '[':
- push(s, *p);
- break;
- case ')':
- if ((ch = top(s)) == '(')
- pop(s);
- else
- flag = false;
- break;
- case ']':
- if ((ch = top(s)) == '[')
- pop(s);
- else
- flag = false;
- break;
- default:
- break;
- }
- }
- if (stack_empty(s))
- printf("brackets match right!/n");
- else
- printf("brackets not match!/n");
- destory_stack(s);
- }
- int main()
- {
- char s[20] = "[3+2)*5]*(2+5)";
- match(s);
- return 0;
- }
(3)行编辑:用户输入#表示前一个字符无效,输入一个@表示当前行中@前的字符都无效
- #include <stdio.h>
- #include "stack.h"
- #define MAXVAL 100
- void lineedit(int *count, char num[])
- {
- struct stack *s = init_stack();
- *count = 0;
- char tmp[MAXVAL], ch;
- ch = getchar();
- while (ch != EOF) {
- while (ch != EOF && ch != '/n') {
- switch (ch) {
- case '#':
- pop(s);
- break;
- case '@':
- clear_stack(s);
- break;
- default:
- push(s, ch);
- break;
- }
- ch = getchar();
- }
- int i, j;
- bool empty;
- i = 0;
- if (ch != EOF) {/*put the character '/n' in tmp array*/
- tmp[i++] = ch;
- ch = getchar();
- }
- /*also put characters of every line in tmp array*/
- for (; !(empty = stack_empty(s)); i++) {
- tmp[i] = top(s);
- pop(s);
- }
- for(j = i - 1; j >= 0; j--, (*count)++)
- num[*count] = tmp[j];
- }
- destory_stack(s);
- }
- int main()
- {
- char num[MAXVAL];
- int count, i;
- lineedit(&count, num);
- for (i = 0; i < count; i++)
- putchar(num[i]);
- return 0;
- }
(4)迷宫求解
思路:
do{
若 当前位置可通,// 可通只未曾走过的通道块。
则 {
将当前位置插入栈顶;//纳入路径
若该位置是出口位置,则结束;//求得的路径放在栈中
否则切换当前位置的东邻块(从东开始,顺时针方向)为新的当前位置;
}
否则,
若 栈不空但栈顶位置的四周均不可通,
则 {
删去栈顶位置;
若栈不空,则重新测试新的栈顶位置,
直到找到一个可通的的相邻块或出栈至栈空;
}
若 栈不空且栈顶位置尚有其他方向未经探索,
则 设定新的当前位置为顺时针方向旋转找到的栈顶位置的下一块相邻块;
}
数据结构:
这里用的栈的数据结构:
- /*stack.h*/
- #ifndef _STACK_H
- #define _STACK_H
- #define Type struct stack_elem*
- #define MAXVAL 100/*the max depth of stack*/
- #ifdef _MSC_VER
- #define bool int
- #define true 1
- #define false 0
- #else
- #include <stdbool.h>
- #include <stdint.h>
- #endif
- struct stack_elem;
- struct stack;
- struct stack *init_stack();
- void destory_stack(struct stack *s);
- void push(struct stack *s, Type data);
- void pop(struct stack *s);
- Type top(struct stack *s);
- int stack_size(struct stack *s);
- bool stack_empty(struct stack *s);
- void clear_stack(struct stack *s);
- #endif
- /*stack.c*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include "stack.h"
- struct stack {
- int sp;/*the next free pos*/
- Type val[MAXVAL];
- };
- struct stack *init_stack()
- {
- struct stack *s = (struct stack*)malloc(sizeof(struct stack));
- if (s != NULL)
- s->sp = 0;
- return s;
- }
- void destory_stack(struct stack *s)
- {
- assert(s != NULL);
- clear_stack(s);
- free(s);
- }
- void push(struct stack *s, Type data)
- {
- assert(s != NULL);
- if (s->sp < MAXVAL)
- s->val[s->sp++] = data;
- else
- printf("error: stack full, can't push %p/n", data);
- }
- void pop(struct stack *s)
- {
- assert(s != NULL);
- if (s->sp > 0) {
- free(s->val[--s->sp]);
- } else
- printf("error: stack empty!/n");
- }
- Type top(struct stack *s)
- {
- assert(s != NULL);
- if (s->sp > 0)
- return s->val[s->sp - 1];
- else {
- printf("error: stack empty!/n");
- return 0;
- }
- }
- void clear_stack(struct stack *s)
- {
- assert(s != NULL);
- while (! stack_empty(s))
- pop (s);
- }
- bool stack_empty(struct stack *s)
- {
- assert(s != NULL);
- if (s->sp > 0)
- return false;
- else
- return true;
- }
- int stack_size(struct stack *s)
- {
- if (s == NULL)
- return 0;
- else
- return s->sp;
- }
采用了指针数组,其中的指针指向了struct stack_elem结构体
其他数据结构:
- struct stack_elem {
- int ord;/*the order of pass object in the way*/
- struct pos seat;/*the coordinate of pass object */
- int di;/*the direction: east--1, south--2, west--3, north--4*/
- };
主函数:
- #include <stdio.h>
- #include <stdlib.h>
- #include "stack.h"
- #define MAX_M 10
- /*record the pass object status: pass--0, block--1, walk--2, back--3*/
- int status[MAX_M][MAX_M];
- struct pos {
- int x;
- int y;
- };
- struct stack_elem {
- int ord;/*the order of pass object in the way*/
- struct pos seat;/*the coordinate of pass object */
- int di;/*the direction: east--1, south--2, west--3, north--4*/
- };
- void init_status(char maze[][MAX_M])
- {
- int i, j;
- for (i = 0; i < MAX_M; i++) {
- for (j = 0; j < MAX_M; j++) {
- if (maze[i][j] == 002)
- status[i][j] = 1;
- else
- status[i][j] = 0;
- }
- }
- }
- void print_maze(char maze[][MAX_M])
- {
- int i, j;
- for (i = 0; i < MAX_M; i++) {
- for (j = 0; j < MAX_M; j++) {
- printf("%c ", maze[i][j]);
- }
- printf("/n");
- }
- }
- void print_status(int status[][MAX_M])
- {
- int i, j;
- for (i = 0; i < MAX_M; i++) {
- for (j = 0; j < MAX_M; j++) {
- printf("%d ", status[i][j]);
- }
- printf("/n");
- }
- }
- bool is_pass(struct pos *ps)
- {
- if (status[ps->x][ps->y] == 0)
- return true;
- else
- return false;
- }
- void foot_print(struct pos *ps)
- {
- status[ps->x][ps->y] = 2;
- }
- void make_print(struct pos ps)
- {
- status[ps.x][ps.y] = 3;
- }
- void next_pos(struct stack_elem *p, struct pos *p_curpos)
- {
- struct pos temp;
- temp.x = p->seat.x;
- temp.y = p->seat.y;
- switch (p->di) {
- case 1:
- temp.y++;
- break;
- case 2:
- temp.x++;
- break;
- case 3:
- temp.y--;
- break;
- case 4:
- temp.x--;
- break;
- default:
- break;
- }
- p_curpos->x = temp.x;
- p_curpos->y = temp.y;
- }
- struct stack *maze_path(char maze[][MAX_M], struct pos *start, struct pos *end)
- {
- struct stack *s = init_stack();
- struct pos curpos;
- struct pos *p_curpos = &curpos;
- p_curpos->x = start->x;
- p_curpos->y = start->y;
- int curstep = 1, direction = 1;
- do {
- if (is_pass(p_curpos)) {/*the current pos is passable*/
- foot_print(p_curpos);
- struct stack_elem *p = (struct stack_elem *)malloc(sizeof(struct stack_elem));
- p->ord = curstep;
- p->seat.x = p_curpos->x;
- p->seat.y = p_curpos->y;
- p->di = direction;
- push(s, p);
- if (p_curpos->x == end->x && p_curpos->y == end->y)/*find the exit*/
- return s;
- next_pos(p, p_curpos);
- curstep++;
- } else {/*the current pos is not passable*/
- if (! stack_empty(s)) {
- struct stack_elem *tip = top(s);
- while (tip->di == 4 && !stack_empty(s)) {
- make_print(tip->seat);
- pop(s);
- tip = top(s);
- }
- if (tip->di < 4) {
- tip->di++;
- next_pos(tip, p_curpos);
- }
- }
- }
- } while (! stack_empty(s));
- return s;
- }
- void mark_maze(char maze[][MAX_M], struct stack *s)
- {
- struct stack_elem *tip;
- char ch = 0;
- while (! stack_empty(s)) {
- tip = top(s);
- switch (tip->di) {
- case 1:
- ch = 26;
- break;
- case 2:
- ch = 25;
- break;
- case 3:
- ch = 27;
- break;
- case 4:
- ch = 24;
- break;
- default:
- break;
- }
- maze[tip->seat.x][tip->seat.y] = ch;
- pop(s);
- }
- }
- int main()
- {
- char maze[MAX_M][MAX_M] = {
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 0, 0, 2, 0, 0, 0, 2, 0, 2,
- 2, 0, 0, 2, 0, 0, 0, 2, 0, 2,
- 2, 0, 0, 0, 0, 2, 2, 0, 0, 2,
- 2, 0, 2, 2, 2, 0, 0, 0, 0, 2,
- 2, 0, 0, 0, 2, 0, 0, 0, 0, 2,
- 2, 0, 2, 0, 0, 0, 2, 0, 0, 2,
- 2, 0, 2, 2, 2, 0, 2, 2, 0, 2,
- 2, 2, 0, 0, 0, 0, 0, 0, 0, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- };
- printf("init status:/nmaze:/n");
- print_maze(maze);
- printf("/n");
- init_status(maze);
- printf("status array:/n");
- print_status(status);
- struct pos start, end;
- start.x = start.y = 1;
- end.x = end.y = 8;
- struct pos *p_start = &start, *p_end = &end;
- struct stack *pass_way = maze_path(maze, p_start, p_end);
- printf("/nfinal status:/nstatus array:/n");
- print_status(status);
- mark_maze(maze, pass_way);
- printf("/n");
- printf("maze:/n");
- print_maze(maze);
- destory_stack(pass_way);
- return 0;
- }
经purify检测,无内存泄露。运行截图: