【数据结构】栈和队列

【数据结构】栈和队列

栈的实现

#define STACK_INIT_SIZE  100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
#define SElemType int
#define Status int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef struct {
    SElemType *base; // 在栈构造之前和销毁之后,值位null
    SElemType *top; // 栈顶指针
    int StackSize; // 当前已分配的存储空间,以元素为单位
} SqStack;

// 构造一个空栈
Status InitStack(SqStack &S) {
    S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S.base) { // S.base == NULL
        return OVERFLOW; // 内存分配失败
    }
    S.top = S.base;
    S.StackSize = STACK_INIT_SIZE;
    return OK;
} // InitStack

// 判断栈是否为空
bool IsEmpty(SqStack S) {
    return S.top == S.base;
} // IsEmpty

// 元素入栈
Status Push(SqStack &S, SElemType e) {
    if (S.top - S.base >= S.StackSize) {
        S.base = (SElemType *)realloc(S.base, (S.StackSize + STACKINCREMENT) * sizeof(SElemType)); // 增加分配的空间
        if (!S.base) {
            return OVERFLOW; // 存储分配失败
        }
        S.top = S.base + S.StackSize;
        S.StackSize += STACKINCREMENT;
    }
    *S.top = e;
    S.top++;
    return OK;
} // Push

// 元素出栈
Status Pop(SqStack &S, SElemType &e) {
    if (IsEmpty(S)) { // 判断栈是否为空
        return ERROR;
    }
    S.top--;
    e = *S.top;
    return OK;
} // Pop

// 获取栈顶元素
Status GetTop(SqStack S, SElemType &e) {
    if (IsEmpty(S)) { // 判断栈是否为空
        return ERROR;
    }
    e = *(S.top - 1);
    return OK;
} // GetTop

队列的实现

#include <iostream>
using namespace std;

#define QElemType int
#define Status int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXQSIZE 100 // 队列最大长度
typedef struct {
    QElemType *base; // 分配存储空间
    int front; // 头指针
    int rear; // 尾指针
} SqQueue;

// 初始化循环队列
Status InitQueue(SqQueue &Q) {
    Q.base = (QElemType*)malloc(MAXQSIZE * sizeof(QElemType));
    if (!Q.base) {
        return OVERFLOW;
    }
    Q.front = Q.rear = 0;
    return OK;
} // InitQueue

// 求队列长度
int QueueLength(SqQueue Q) {
    return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
} // QueueLength

// 入队列
Status EnQueue(SqQueue &Q, QElemType e) {
    if ((Q.rear + 1) % MAXQSIZE == Q.front) {
        return ERROR; // 队列已经满了
    }
    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXQSIZE;
    return OK;
} // EnQueue

// 出队列
Status DeQueue(SqQueue &Q, QElemType &e) {
    if (Q.front == Q.rear) {
        return ERROR; // 队列已经满了
    }
    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXQSIZE;
    return OK;
} // DeQueue

习题

堆栈

Problem A 有趣的括号

在这里插入图片描述

思路

逐个读取字符。若为左括号,则将其压入栈;若为右括号,判断栈顶元素是否为该右括号对应的左括号,若是则弹出栈顶元素,若不是则直接返回False。在最后判断栈是否为空,若为空则返回true,否则返回false。

代码
#include <iostream>
using namespace std;

#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
#define SElemType char
#define Status int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef struct {
    SElemType *base; // 在栈构造之前和销毁之后,值位null
    SElemType *top; // 栈顶指针
    int StackSize; // 当前已分配的存储空间,以元素为单位
} SqStack;

// 构造一个空栈
Status InitStack(SqStack &S) {
    S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S.base) { // S.base == NULL
        return OVERFLOW; // 内存分配失败
    }
    S.top = S.base;
    S.StackSize = STACK_INIT_SIZE;
    return OK;
} // InitStack

// 判断栈是否为空
bool IsEmpty(SqStack S) {
    return S.top == S.base;
} // IsEmpty

// 元素入栈
Status Push(SqStack &S, SElemType e) {
    if (S.top - S.base >= S.StackSize) {
        S.base = (SElemType *)realloc(S.base, (S.StackSize + STACKINCREMENT) * sizeof(SElemType)); // 增加分配的空间
        if (!S.base) {
            return OVERFLOW; // 存储分配失败
        }
        S.top = S.base + S.StackSize;
        S.StackSize += STACKINCREMENT;
    }
    *S.top = e;
    S.top++;
    return OK;
} // Push

// 元素出栈
Status Pop(SqStack &S, SElemType &e) {
    if (IsEmpty(S)) { // 判断栈是否为空
        return ERROR;
    }
    S.top--;
    e = *S.top;
    return OK;
} // Pop

// 获取栈顶元素
Status GetTop(SqStack S, SElemType &e) {
    if (IsEmpty(S)) { // 判断栈是否为空
        return ERROR;
    }
    e = *(S.top - 1);
    return OK;
} // GetTop

// 判断是否为左括号
bool isLeftBracket(SElemType bracket) {
    return (bracket == '(' || bracket == '[' || bracket == '{');
} // isLeftBracket

// 左括号转换为右括号
SElemType Reverse(SElemType &e) {
    if (e == '(') {
        return ')';
    } else if (e == '[') {
        return ']';
    } else if (e == '{') {
        return '}';
    }
} // Reverse

SElemType bracket[100]; // 定义全局变量

int main() {
    SqStack S;
    InitStack(S);
    int index = 0;
    while (cin >> bracket[index]) {
        if (bracket[index] == '\n') {
            break;
        }
        ++index;
    }
    for (int i = 0; i < index; ++i) {
        if (isLeftBracket(bracket[i])) {
            Push(S, bracket[i]);
        } else {
            if (IsEmpty(S)) {
                cout << "False";
                return 0;
            } else {
                SElemType elem;
                GetTop(S, elem);
                if (bracket[i] == Reverse(elem)) {
                    Pop(S, elem);
                }
            }
        }
    }
    if (IsEmpty(S)) {
        cout << "True";
    } else {
        cout << "False";
    }
}
Problem B 进制转换

在这里插入图片描述

在这里插入图片描述

思路

首先输入对应的整数和进制类型,并把进制类型作为模数。每次对数进行取模,求得的数值压入栈。最后输出栈中的所有元素即可。

代码
#include <bits/stdc++.h>
using namespace std;

#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACKINCREMENT 10 // 存储空间分配增量
#define SElemType char
#define Status int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef struct {
    SElemType *base; // 在栈构造之前和销毁之后,值位null
    SElemType *top; // 栈顶指针
    int StackSize; // 当前已分配的存储空间,以元素为单位
} SqStack;

// 构造一个空栈
Status InitStack(SqStack &S) {
    S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!S.base) { // S.base == NULL
        return OVERFLOW; // 内存分配失败
    }
    S.top = S.base;
    S.StackSize = STACK_INIT_SIZE;
    return OK;
} // InitStack

// 判断栈是否为空
bool IsEmpty(SqStack S) {
    return S.top == S.base;
} // IsEmpty

// 元素入栈
Status Push(SqStack &S, SElemType e) {
    if (S.top - S.base >= S.StackSize) {
        S.base = (SElemType *)realloc(S.base, (S.StackSize + STACKINCREMENT) * sizeof(SElemType)); // 增加分配的空间
        if (!S.base) {
            return OVERFLOW; // 存储分配失败
        }
        S.top = S.base + S.StackSize;
        S.StackSize += STACKINCREMENT;
    }
    *S.top = e;
    S.top++;
    return OK;
} // Push

// 元素出栈
Status Pop(SqStack &S, SElemType &e) {
    if (IsEmpty(S)) { // 判断栈是否为空
        return ERROR;
    }
    S.top--;
    e = *S.top;
    return OK;
} // Pop

// 获取栈顶元素
Status GetTop(SqStack S, SElemType &e) {
    if (IsEmpty(S)) { // 判断栈是否为空
        return ERROR;
    }
    e = *(S.top - 1);
    return OK;
} // GetTop

int main() {
    int num, conversion, mod;
    cin >> num >> conversion;
    SqStack S;
    InitStack(S);
    while (num) {
        mod = num % conversion;
        if (mod < 10) {
            Push(S, mod + '0');
        } else {
            Push(S, (mod - 10) + 'A');
        }
        num = num / conversion;
    }
    while (!IsEmpty(S)) {
        SElemType e;
        Pop(S, e);
        cout << e;
    }
}

Problem C 表达式求值

在这里插入图片描述

思路

此题需要使用两个栈:操作数栈和操作符栈。对每个操作符设定一个优先级并进行比较,即可对操作数栈中的元素进行运算。最终操作数栈的栈顶元素即为表达式的值。

代码
#include <iostream>
#include <malloc.h>
#include <string>
using namespace std;

#define init_size 1
#define create_size 200

typedef struct Numstack {
    int *top, *base;
    int stacksize;
} numstack;

typedef struct Chstack {
    char *top, *base;
    int stacksize;
} chstack;

numstack num;
chstack ch;
string s;

bool isdigit(char c) {
    if (c >= '0' && c <= '9') {
        return true;
    } else {
        return false;
    }
}

int pow(int a, int b) {
    int ans = 1;
    for (int i = 0; i < b; ++i) {
        ans *= a;
    }
    return ans;
}

void init_stack(numstack &s) {
    s.base = (int *)malloc(init_size * sizeof(int));
    s.top = s.base;
    s.stacksize = init_size;
}

void init_stack(chstack &s) {
    s.base = (char *)malloc(init_size * sizeof(char));
    s.top = s.base;
    s.stacksize = init_size;
}

int top(numstack s) {
    return *(s.top - 1);
}

char top(chstack s) {
    return *(s.top - 1);
}

void push(numstack &s, int e) {
    if (s.top >= s.base + s.stacksize) {
        s.base = (int *)realloc(s.base, s.stacksize + create_size * sizeof(int));
        s.top = s.base + s.stacksize;
        s.stacksize += create_size;
    }
    *s.top = e;
    s.top++;
}

void push(chstack &s, char e) {
    if (s.top >= s.base + s.stacksize) {
        s.base = (char *)realloc(s.base, s.stacksize + create_size * sizeof(char));
        s.top = s.base + s.stacksize;
        s.stacksize += create_size;
    }
    *s.top = e;
    s.top++;
}

void pop(numstack &s) {
    s.top--;
}

void pop(chstack &s) {
    s.top--;
}

bool empty(chstack s) {
    if (s.top == s.base) {
        return true;
    } else {
        return false;
    }
}

int size(numstack s) {
    return (s.top - s.base) / sizeof(int *);
}

void calculate() {
    int a = top(num);
    pop(num);
    int b = top(num);
    pop(num);
    char c = top(ch);
    pop(ch);
    switch (c) {
    case '*':
        push(num, b * a);
        break;
    case '/':
        push(num, b / a);
        break;
    case '-':
        push(num, b - a);
        break;
    case '+':
        push(num, b + a);
        break;
    default:
        push(num, pow(b, a));
        break;
    }
}

int check(char c) {
    switch (c) {
        case '+':
        case '-':
            return 1;
        case '*':
        case '/':
            return 2;
        case '^':
            return 3;
        default:
            return 4;
    }
}

int main() {
    cin >> s;
    for (int i = 0; i < s.length();) {
        if (isdigit(s[i])) {
            int mid = 0;
            while (isdigit(s[i])) {
                mid = mid * 10 + s[i++] - '0';
            }
            push(num, mid);
        } else {
            if (s[i] == '(') {
                push(ch, s[i]);
            } else if (s[i] == ')') {
                while (top(ch) != '(') {
                    calculate();
                }
                pop(ch);
            } else {
                if (empty(ch) || check(s[i]) > check(top(ch))) {
                    push(ch, s[i]);
                } else {
                    while (check(s[i]) <= check(top(ch))) {
                        if (top(ch) == '(') {
                            break;
                        }
                        calculate();
                        if (empty(ch)) {
                            break;
                        }
                    }
                    push(ch, s[i]);
                }
            }
            ++i;
        }
    }
    while (size(num) != 1 && !empty(ch)) {
        calculate();
    }
    cout << top(num);
}

队列

Problem A 银行业务队列简单模拟

在这里插入图片描述

思路

本题要使用两个队列,分别为A和B。根据”A窗口处理速度是B窗口的2倍“,可以在一次处理中弹出两个A队列元素和一个B队列元素。最后若有剩余则全部弹出即可。

代码
#include <bits/stdc++.h>
using namespace std;

#define QElemType int
#define Status int
#define SElemType int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

vector<int> out;
int num;

typedef struct QNode { // 定义结点
    QElemType data;
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct {
    QueuePtr front; // 队头指针
    QueuePtr rear; // 队尾指针
} LinkQueue;

// 初始化一个空队列
Status InitQueue(LinkQueue &Q) {
    Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front) {
        return OVERFLOW;
    }
    Q.front->next = nullptr;
} // InitQueue

// 销毁队列
Status DestroyQueue(LinkQueue &Q) {
    while (Q.front) {
        Q.rear = Q.front->next;
        free(Q.front);
        Q.front = Q.rear;
    }
    return OK;
} // DestroyQueue

// 入队列
Status EnQueue(LinkQueue &Q, QElemType e) {
    QNode *p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) {
        return OVERFLOW; // 存储分配失败
    }
    p->data = e;
    p->next = nullptr;
    Q.rear->next = p;
    Q.rear = p;
    return OK;
} // EnQueue

// 出队列
QElemType DeQueue(LinkQueue &Q) {
    if (Q.front == Q.rear) {
        return ERROR;
    }
    QNode *p;
    p = Q.front->next;
    QElemType e = p->data;
    Q.front->next = p->next;
    if (Q.rear == p) {
        Q.rear = Q.front;
    }
    free(p);
    return e;
} // Dequeue

// 判断是否为奇数
bool isOdd(int n) {
    return (n % 2 != 0);
}

void OutAll(LinkQueue &La, LinkQueue &Lb, int la, int lb) {
    if (la > 2 * lb) {
        int c = 0;
        for (int i = 1; i <= lb; ++i) {
            out.push_back(DeQueue(La));
            out.push_back(DeQueue(La));
            out.push_back(DeQueue(Lb));
            c += 3;
        }
        for (int i = 1; i <= num - c; ++i) {
            out.push_back(DeQueue(La));
        }
    } else if (la == 2 * lb) {
        for (int i = 1; i <= lb; ++i) {
            out.push_back(DeQueue(La));
            out.push_back(DeQueue(La));
            out.push_back(DeQueue(Lb));
        }
    } else {
        int c = 0;
        for (int i = 1; i <= la / 2; ++i) {
            out.push_back(DeQueue(La));
            out.push_back(DeQueue(La));
            out.push_back(DeQueue(Lb));
            c += 3;
        }
        if (la % 2 != 0) {
            out.push_back(DeQueue(La));
            c++;
        }
        for (int i = 1; i <= num - c; ++i) {
            out.push_back(DeQueue(Lb));
        }
    }
}

int main() {
    while (out.size()) {
        out.pop_back();
    }
    LinkQueue A, B;
    InitQueue(A);
    InitQueue(B);
    int la = 0, lb;
    cin >> num;
    for (int i = 1; i <= num; ++i) {
        int m;
        cin >> m;
        if (isOdd(m)) {
            EnQueue(A, m);
            la++;
        } else {
            EnQueue(B, m);
        }
    }
    lb = num - la;
    OutAll(A, B, la, lb);
    for (int i = 0; i < out.size(); i++) {
        if (i == out.size() - 1) {
            cout << out[i];
        } else {
            cout << out[i] << " ";
        }
    }
}
Problem B 堆栈模拟队列

在这里插入图片描述

在这里插入图片描述

思路

本题需要使用两个堆栈,分别为S1和S2。取大小最大的栈为S1,较小的为S2。注意S1不能压满元素,而至多能装min(S1,S2)个元素。当S1满时把元素装到S2中,然后再弹出,即可模拟队列实现先进先出的特性。如图所示。

在这里插入图片描述

代码
#include <bits/stdc++.h>
using namespace std;

#define SElemType int
#define Status int
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef struct {
    SElemType *base; // 在栈构造之前和销毁之后,值位null
    SElemType *top; // 栈顶指针
    int StackSize; // 当前已分配的存储空间,以元素为单位
} SqStack;

SqStack S1, S2;

// 构造一个空栈
Status InitStack(SqStack &S, int size) {
    S.base = (SElemType *)malloc(size * sizeof(SElemType));
    S.top = S.base;
    S.StackSize = size;
    return OK;
} // InitStack

// 判断栈是否为空
bool IsEmpty(SqStack S) {
    return S.top == S.base;
} // IsEmpty

// 判断栈是否为满
bool IsFull(SqStack S) {
    return (S.top >= S.base + S.StackSize);
}

// 元素入栈
Status Push(SqStack &S, SElemType e) {
    *S.top = e;
    S.top++;
    return OK;
} // Push

// 元素出栈
SElemType Pop(SqStack &S) {
    S.top--;
    return *S.top;
} // Pop

// 获取栈顶元素
SElemType GetTop(SqStack S) {
    SElemType e;
    e = *(S.top - 1);
    return e;
} // GetTop

// 转换
void transfer() {
    while (!IsEmpty(S1)) {
        Push(S2, Pop(S1));
    }
} // transfer

// 队尾添加元素
void AddQ(SElemType e) {
    if (!IsFull(S1)) {
        Push(S1, e);
    } else {
        if (IsEmpty(S2)) {
            transfer();
            Push(S1, e);
        } else {
            cout << "ERROR:Full" << endl;
        }
    }
    // if (IsFull(S1)) {
    //     if (!IsEmpty(S2)) {
    //         cout << "ERROR:Full" << endl;
    //     } else {
    //         transfer();
    //         Push(S1, e);
    //     }
    // } else {
    //     Push(S1, e);
    // }
}

// 队首弹出元素
void DeleteQ() {
    if (IsEmpty(S2)) {
        transfer();
        if (IsEmpty(S2)) {
            cout << "ERROR:Empty" << endl;
        } else {
            cout << Pop(S2) << endl;
        }
    } else {
        cout << Pop(S2) << endl;
    }
}

int main() {
    int size1, size2;
    cin >> size1 >> size2;
    if (size1 > size2) {
        swap(size1, size2);
    }
    InitStack(S1, size1);
    InitStack(S2, size2);
    char c;
    int num;
    while (cin >> c) {
        if (c == 'T') {
            break;
        } 
        if (c == 'A') {
            cin >> num;
            AddQ(num);            
        } else {
            DeleteQ();
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值