广大考研数据结构复习之栈

王道书籍上栈的基本操作和课后部分习题

代码如下:

/**
 * @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;
}

猜你喜欢

转载自www.cnblogs.com/hidamowang/p/11838652.html
今日推荐