🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 栈 栈的存储结构主要有顺序栈和链栈。 ## 出栈序列 n 个不同元素入栈, 出栈序列一共有 $\frac{C^n_{2n}}{n+1}$ 种不同排列。 ## 顺序栈 定义 ```C #define MaxSize 500 typedef struct{ ElemType data[MaxSize]; int top; }SqStack; ``` 初始化 ```C void InitStack(SqStack &st) { st.top = -1; } ``` 判断栈是否为空(栈为空返回 1) ```C int StackEmpty(SqStack st) { return(st.top==-1); } ``` 进栈算法 ```C int Push(SqStack &st, ElemType e) { if(st.top==MaxSize-1) return 0; st.data[++st.top] = e; return 1; } ``` 出栈算法 ```C int Pull(SqStack &st, ElemType &e) { if(st.top==-1) return 0; e = st.data[st.top--]; return 1; } ``` 取栈顶元素算法 ```C int GetTop(SqStack st, ElemType &e) { if(st.top==-1) return 0; e = st.data[st.top]; return 1; } ``` ### 求解迷宫问题 ```C #include <stdio.h> #define MaxSize 50 int main() { // 建立迷宫 int mg[10][10]={ {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1}, {1,0,1,0,0,0,1,0,0,1}, {1,0,1,1,1,0,1,1,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; // 建立路径栈 struct{ int i; // 行数,纵坐标 int j; int di; }st[MaxSize]; int top = -1; // 标记起点和终点 int si, sj, ei, ej; si = sj = 1; ei = ej = 8; int i, j, di, find, k; // 初始方块进栈 top++; st[top].i = si; st[top].j = sj; st[top].di = -1; // 方向还未确定之前赋值为-1 mg[si][sj] = -1; // 走过的路赋值-1,避免重复走;退回时重赋值 0 while(top>-1){ i = st[top].i; j = st[top].j; di = st[top].di; if(i== ei && j==ej){ printf("Find the path:\n"); for(k=0; k<=top;k++){ printf("(%d, %d)", st[k].i, st[k].j); if((k+1)%5==0) printf("\n"); } return 1; } find = 0; while(di<4 && find==0){ di++; switch(di){ case 0: i = st[top].i; j = st[top].j+1; break; case 1: i = st[top].i+1; j = st[top].j; break; case 2: i = st[top].i; j = st[top].j-1; break; case 3: i = st[top].i-1; j = st[top].j; break; } if(mg[i][j]==0) find = 1; } if(find==1){ st[top].di = di; top++; st[top].i = i; st[top].j = j; st[top].di = -1; mg[i][j] = -1; } else{ mg[st[top].i][st[top].j] = 0; top--; } } printf("No path!"); return 0; } ``` 求最短路径 ```C #include <stdio.h> #define MaxSize 50 int main() { // 建立迷宫 int mg[10][10]={ {1,1,1,1,1,1,1,1,1,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,1,0,0,0,1,0,1}, {1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1}, {1,0,0,0,1,0,0,0,0,1}, {1,0,1,0,0,0,1,0,0,1}, {1,0,1,1,1,0,1,1,0,1}, {1,1,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; // 建立路径栈 struct{ int i; // 行数,纵坐标 int j; int di; }st[MaxSize], path[MaxSize]; int top = -1; // 标记起点和终点 int si, sj, ei, ej; si = sj = 1; ei = ej = 8; int i, j, di, find, k; // 初始方块进栈 top++; st[top].i = si; st[top].j = sj; st[top].di = -1; // 方向还未确定之前赋值为-1 mg[si][sj] = -1; // 走过的路赋值-1,避免重复走;退回时重赋值 0 int minlen = MaxSize, count = 0; while(top>-1){ i = st[top].i; j = st[top].j; di = st[top].di; if(i== ei && j==ej){ count++; if(top+1<minlen){ minlen = top + 1; for(k=0; k<=top; k++){ path[k].i=st[k].i; path[k].j=st[k].j; path[k].di=st[k].di; } } mg[st[top].i][st[top].j] = 0; //让该位置重新变为可走 top--; i = st[top].i; j = st[top].j; di = st[top].di; } find = 0; while(di<4 && find==0){ di++; switch(di){ case 0: i = st[top].i; j = st[top].j+1; break; case 1: i = st[top].i+1; j = st[top].j; break; case 2: i = st[top].i; j = st[top].j-1; break; case 3: i = st[top].i-1; j = st[top].j; break; } if(mg[i][j]==0) find = 1; } if(find==1){ st[top].di = di; top++; st[top].i = i; st[top].j = j; st[top].di = -1; mg[i][j] = -1; } else{ mg[st[top].i][st[top].j] = 0; // 未找到下一个方块,则恢复环境 top--; // 回溯 } } if(count>0){ printf("There are total %d paths.\n", count); printf("Find the shortest path in %d steps that:\n", minlen); for(k=0; k<minlen;k++){ printf("(%d, %d)", path[k].i, path[k].j); if((k+1)%5==0) printf("\n"); } return 1; } printf("No path!"); return 0; } ``` ## 链栈 链栈的所有操作都在表头进行,起始节点是链栈的栈顶。 定义 ```C typedef struct linknode{ ElemType data; struct linknode *next; }LiStack; //声明链栈节点类型 ``` 初始化 ```C void InitStack(LiStack *&lst) { lst = (LiStack *)malloc(sizeof(LiStack)); lst->next = NULL; } ``` 判断链栈是否为空 ```C int LiStackEmpty(LiStack *lst) { return(lst->next==NULL); } ``` 进栈算法 ```C void Push(LiStack *lst, ElemType e) { LiStack *s; s = (LiStack *)malloc(sizeof(LiStack)); s->data = e; s->next = lst->next; l->next = s; } ``` 出栈算法 ```C int Pop(LiStack *lst, ElemType e) { if(lst->next==NULL) return 0; LiStack *p = lst->next; e = p->data; lst->next = p->next; free(p); return 1; } ``` 取栈顶元素算法 ```C int Get(LiStack *lst, ElemType e) { if(lst->next==NULL) return 0; e = lst->next->data; return 1; } ```