王道书籍上栈的基本操作和课后部分习题
代码如下:
/** * @author Dawn * @date 2019年11月9日21:52:16 * @version 1.0 * 栈的复习,由于函数不是很多,就写在一起算了 */ #include<stdio.h> #include<stdlib.h> #define MaxSize 50//栈中元素最大个数 typedef int ElemType; typedef struct { ElemType data[MaxSize];//存放栈中元素 int top;//栈顶指针 }SqStack; //仅仅是为了写第四题 typedef struct LNode{ ElemType data; struct LNode* next; }LNode,*LinkList; //仅仅为了第五题 共享栈 typedef struct { ElemType data[MaxSize];//共享栈 int top[2];//2个栈顶指针 }ShareStack; //============栈的基本操作=============== //1.初始化 void InitStack(SqStack& S); //2.判栈空 bool StackIsEmpty(SqStack S); //3.进栈 bool Push(SqStack& S, ElemType x); //4.出栈 bool Pop(SqStack& S,ElemType &x); //5.读栈顶元素,将读取的结果放在x中 bool GetTop(SqStack S, ElemType& x); //============课后习题=============== //3.简陋版的符号匹配问题 bool Judge(char A[]); bool Judge2(char A[]); //4.判断一个链表是否对称,用栈的思想来完成 bool IsSymmetry(LinkList L,int n); //5.共享栈的设计,包括它的入栈和出栈操作 //i 表示栈号(0,1这2个栈),x表示入栈的元素 bool Push_S(ShareStack& S, int i, ElemType x); bool Pop_S(ShareStack& S, int i, ElemType& x); int main() { int arr[5] = { 1,2,3,4,5 }; SqStack S; int i = 0; int x; //InitStack(S); //printf("栈是否为空:%s\n", StackIsEmpty(S) ? "为空" : "不为空"); //while (i < 5) { // Push(S, arr[i++]); //} //printf("栈是否为空:%s\n", StackIsEmpty(S) ? "为空" : "不为空"); ////GetTop(S, x); ////printf("栈顶元素为:%d", x); //Pop(S, x); //printf("出栈的元素为:%d", x); ////课后习题测试 //printf("\n"); //char A[7] = { 'O','O','I','I','O','O' }; ////Judge(A); //Judge2(A); return 0; } //============课后习题实现=============== //3.简陋版的符号匹配问题, bool Judge(char A[]) { //思路?遍历数组,用 j k分别代表入栈I和出栈O的个数。然后通过这个次数来判断是否符合栈的规则 int i = 0; int j = 0, k = 0; while (A[i] != '\0') { switch (A[i]) { case 'I': j++;//个数加1 break;//退出switch case 'O': k++; if (k > j) {//当出栈大于入栈,则返回false printf("序列非法\n"); return false; } }//wtitch i++;//判断下一个元素 } if (j != k) { //如果倒数第二次次是j = k,最后一次进去是I加了一个1,还有其他情况,懒得举例子了 printf("序列非法\n"); return false; } else { printf("序列合法\n"); return true; } } //使用栈来实现 bool Judge2(char A[]) { int i = 0; int sum = 0;//这个sum就代替栈的意思 while (A[i] != '\0') { if (sum == -1) { printf("序列不合法\n"); return false; } else { //2中情况 if (A[i] == 'I') { sum++; } else { sum--; } } i++;//判断下一个元素 } //如果上面通过了,还有入栈多余出栈的结果,或者倒数第二次循环的时候是s==0,最后一次就成了s==-1。然而没有进入循环中去 if (sum != 0) { printf("序列不合法\n"); return false; } else { printf("序列合法\n"); return true; } } //4.判断一个带头节点链表是否对称,用栈的思想来完成 bool IsSymmetry(LinkList L,int n) { int i; char s[10];//char s[n / 2];不能用变量,就用10随便表示一下吧 LNode* p = L->next; for (i = 0; i < n / 2; i++) { s[i] = p->data; p = p->next; } i--;//恢复最后i值 if (n % 2 == 1) p = p->next;//如果是奇数,后移到中心节点后的一个位置 while (p != NULL && s[i] == p->data) { i--; p = p->next; } if (i == -1) { return true; } else { return false; } } //5.共享栈的设计,包括它的入栈和出栈操作 //i 表示栈号(0,1这2个栈),x表示入栈的元素 bool Push_S(ShareStack& S, int i, ElemType x) { //判断输入的i是否正确 if (i < 0 || i>1) return false; //是否栈满 if (S.top[1] - S.top[0] == 1) return false; //k开始入栈 switch (i) { case 0: S.data[++S.top[0]] = x; return true; break;//第一个操作了就不要操作第二个了。。。其实这个这个break都是多余的,不过加上显得更加有逻辑性。因为有return.只要经过了return,就退出去了,根本不得执行那个break了 case 1: S.data[--S.top[1]] = x; return true; } } bool Pop_S(ShareStack& S, int i, ElemType& x) { if (i < 0 || i>1) return false; switch (i) { //对于此处的case语句结束之后要不要加break,可以不要加,因为这个的return 可以直接返回出去了, case 0: if (S.top[0] == -1) return false;//0栈为空 else { x = S.data[S.top[0]--]; return true; } case 1: if (S.top[1] == MaxSize) return false; else { x = S.data[S.top[1]--]; return true; } } } //============栈的基本操作实现=============== //1.初始化 void InitStack(SqStack& S) { S.top = -1; } //2.判栈空 bool StackIsEmpty(SqStack S) { if (S.top == -1) return true; else return false; } //3.进栈 bool Push(SqStack& S, ElemType x) { //如果判断栈是否满了 if (S.top == MaxSize - 1) return false; S.data[++S.top] = x;//这是栈顶从-1开始的情形。所以栈顶先加1再进栈 //S.data[S.top++] = x;//这是栈顶从0开始的情形。所以先进栈,然后再栈顶加1 return true; } //4.出栈 bool Pop(SqStack& S, ElemType& x) { //判断栈是否为空 if (S.top == -1) return false; x = S.data[S.top--];//这是栈顶从-1开始的情形。所以先出栈再指针减一 //x = S.data[--S.top];//这是栈顶从0开始的情形。所以先栈顶指针减一再出栈 } //5.读栈顶元素,将读取的结果放在x中 bool GetTop(SqStack S, ElemType& x) { //如果栈为空, if (S.top == -1) return false; x = S.data[S.top]; return true; }