栈和队列

本文介绍了顺序栈、链栈、循环队列和链队的实现,包括初始化、入栈/出栈/入队/出队操作。此外,还展示了如何使用栈进行括号匹配检查以及计算括号的嵌套深度。最后,提到了如何构造最大二叉树的问题,给出了相关算法实现。
摘要由CSDN通过智能技术生成

顺序栈:

#include <stdio.h>
#include<stdlib.h>
#define MaxSize 10
typedef  struct{
    int data[MaxSize]; //静态数组存放栈中元素 
    int top;  //栈顶指针 
}SqStack; 

//初始化栈
void InitStack(SqStack &s){
    s.top=-1;

//判断是否栈空
bool Empty(SqStack s){
    if(s.top==-1){
        return true;
    }else{
        return false;
    }

//进栈
bool push(SqStack &s,int elem){
    if(s.top==MaxSize-1){//栈满 
        return false;
    }
    s.top++;  //指针加一
    s.data[s.top]=elem; //新元素入栈 
    //等价于: s.data[++s.top]=elem;
    return true; 
}

//出栈
bool pop(SqStack &s){
    if(s.top==-1){ //栈空 
        return false;
    }
    int x=s.data[s.top];
    s.top--;
    return true; 
}

//输出栈顶元素
int GetElem(SqStack s){
    int x=s.data[s.top];
    printf("%d ",x);

int main(){
    SqStack s;
    InitStack(s);
    push(s,1);
    push(s,2);
    push(s,3);
    pop(s);
    GetElem(s);
    return 0;
}
 

链栈:

#include<stdio.h>
#include<stdlib.h>
//链栈
typedef struct Linknode{
    int data;
    Linknode *next;
}*LiStack; 

//初始化
void InitStack(LiStack &s){
    s=new Linknode();
    s->next=NULL;
}
//判断是否为空
bool Empty(LiStack s){
    if(s==NULL){
        return true;
    }else{
        return false;
    }
}
//进栈
bool Push(LiStack &s,int elem){
    Linknode *p,*q;
    p=new Linknode(); //分配空间
    p->data=elem;
    p->next=s->next;
    s->next=p;
    return true;
}
//出栈
bool Pop(LiStack &s){
    if(s->next==NULL){
        return false;
    }
    printf("%d ",s->data);
    Linknode *p;
    p=s->next;
    s->next=p->next;
    return true;
}
//遍历
void travel(LiStack s){
    Linknode *p;
    for(p=s->next;p!=NULL;p=p->next)
    {
        printf("%3d",p->data);
    }

int main(){
    LiStack s;
    InitStack(s);
    Push(s,1);
    Push(s,2);
    Push(s,3);
    travel(s);
    return 0;

循环队列:

#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
//顺序队列
 typedef struct{
     int date[MaxSize];  //静态数组存放队列元素 
     int front,rear; //定义头指针,尾指针 
 }SqQueue;
 
 //初始化
 bool InitQueue(SqQueue &q){
     q.rear=q.front=0;
 }
 //判断队列是否为空
 bool Empty(SqQueue q){
     if(q.rear==q.front){
         return true;
     }
     return false;
 } 
 //入队
 bool EnQueue(SqQueue &q,int elem){
     if((q.rear+1)%MaxSize==q.front){  //队满 
         return false;
     }
     q.date[q.rear]=elem;
     q.rear=(q.rear+1)%MaxSize;
     return true;
 }
 //出队
 bool OutQueue(SqQueue &q){
     if(q.front==q.rear){  //队空 
         return false;
     } 
     int x=q.date[q.front];
     printf("%d ",q.date[q.front]);
     q.front=(q.front+1)%MaxSize;
     return true; 
 }
 
//得到队首元素
bool GetElem(SqQueue q){
    if(q.front==q.rear){ //队空则报错 
        return false;
    }
    printf("%d ",q.date[q.front]);

 int main(){
     SqQueue q;
     InitQueue(q);
     EnQueue(q,1);
     EnQueue(q,2);
     EnQueue(q,3);
     OutQueue(q);
     OutQueue(q);
     return 0;
 } 

链队:

#include <stdio.h>
#include<stdlib.h>

typedef struct LinkNode{ //链式队列节点 
    int date;
    struct LinkNode *next;
}LinkNode;

typedef struct {  //链式队列 
    LinkNode *front,*rear;  //队头指针,队尾指针 
}LinkQueue; 

//初始化(带头节点)
bool InitQueue(LinkQueue &q){
    q.front=q.rear=(LinkNode *)malloc(sizeof(LinkNode));
    q.front->next=NULL;
    return false;
}
//初始化(不带头节点)
bool InitQueues(LinkQueue &q){
    q.front=NULL;
    q.rear=NULL;
    return false;

//判断是否为空
bool Empty(LinkQueue q){
    if(q.front==q.rear){
        return true;
    }else{
        return true;
    }

//入队
bool EnQueue(LinkQueue &q,int elem){
    LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
    s->date=elem;
    s->next=NULL;
    q.rear->next=s;  //新节点插入到rear节点之后 
    q.rear=s;        //修改表尾指针 
    return true;    
}
//出队
bool OutQueue(LinkQueue &q){
    if(q.front==q.rear){ //队列为空 
        return false;    
    } 
    LinkNode *p=q.front->next;
    int x=p->date;   //用x返回出队元素
    printf("%d ",x);
    q.front->next=p->next;
    if(q.rear==p){
        q.rear=q.front;
    } 
    free(p);
    return true;
}
int main(){
    LinkQueue q;
    InitQueue(q);
    EnQueue(q,1);
    EnQueue(q,2);
    EnQueue(q,3);
    OutQueue(q);
    return 0;

栈的括号匹配:

#include <stdio.h>
#include<stdlib.h>
#define MaxSize 10
//栈在括号匹配中的应用 
typedef struct{
    int date[MaxSize];
    int top;
}SqStack;

//初始化
void InitStack(SqStack &s){
    s.top=-1;

//判断栈是否为空
bool EmptyStack(SqStack s){
    if(s.top==-1){
        return true;
    }
    return false;

//入栈
bool Push(SqStack &s,char x){
    if(s.top==MaxSize-1){
        return false;
    }
    s.date[++s.top]=x;
    return true;

//栈顶元素出栈
char Pop(SqStack &s){
    if(s.top==-1){
        return false;
    }
    char x=s.date[s.top];
    //printf("%c ",x);
    s.top--;
    return x;

//栈的括号匹配
bool CheckStack(char str[],int length){
    SqStack s;
    InitStack(s);  //初始化一个栈
    for(int i=0;i<length;i++){
        if(str[i]=='('||str[i]=='['||str[i]=='{'){ //扫描到左括号,入栈 
            Push(s,str[i]); 
        }else{
            if(EmptyStack(s)){//扫描到右括号,且当前栈空,匹配失败 
                return false;
            }
            char topelem;
            topelem=Pop(s);//栈顶元素出栈 
            if(str[i]=='('&&topelem!=')') {
                return false;
            }
            if(str[i]=='['&&topelem!=']') {
                return false;
            }
            if(str[i]=='{'&&topelem!='}') {
                return false;
            }
        }
    }
    return EmptyStack(s); //检索完全部括号后,如果栈空则匹配成功 

int main(){
    SqStack s;
    InitStack(s);
    char str[4]={'(','[',']',')'};
    if(CheckStack(str,4)==true){
        printf("1");
    }else{
        printf("0");
    }
    return 0;
}

【1】括号的最大嵌套深度

如果字符串满足以下条件之一,则可以称之为 有效括号字符串(valid parentheses string,可以简写为 VPS):

字符串是一个空字符串 "",或者是一个不为 "(" 或 ")" 的单字符。
字符串可以写为 AB(A 与 B 字符串连接),其中 A 和 B 都是 有效括号字符串 。
字符串可以写为 (A),其中 A 是一个 有效括号字符串 。
类似地,可以定义任何有效括号字符串 S 的 嵌套深度 depth(S):

depth("") = 0
depth(C) = 0,其中 C 是单个字符的字符串,且该字符不是 "(" 或者 ")"
depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是 有效括号字符串
depth("(" + A + ")") = 1 + depth(A),其中 A 是一个 有效括号字符串
例如:""、"()()"、"()(()())" 都是 有效括号字符串(嵌套深度分别为 0、1、2),而 ")(" 、"(()" 都不是 有效括号字符串 。

给你一个 有效括号字符串 s,返回该字符串的 s 嵌套深度 。

示例 1:

输入:s = "(1+(2*3)+((8)/4))+1"
输出:3
解释:数字 8 在嵌套的 3 层括号中。

class Solution {
public:
    int maxDepth(string s) {
        //数括号,(+1,)-1,返回最大值
        int n = s.length(),max = 0,k = 0;
        for(int i = 0;i< n;i++){
            if(s[i] == '(') k++;
            else if(s[i] == ')') k--;
            if(k > max) max = k;
        }
        return max;

    }
};

【2】最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。

示例 1:

输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
    - [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
        - 空数组,无子节点。
        - [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
            - 空数组,无子节点。
            - 只有一个元素,所以子节点是一个值为 1 的节点。
    - [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
        - 只有一个元素,所以子节点是一个值为 0 的节点。
        - 空数组,无子节点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
        return construct(nums.begin(), nums.end());
    }
    
private:
    TreeNode * construct(vector<int>::iterator l, vector<int>::iterator r) {
        if (l == r) return NULL;
        auto it = max_element(l, r);
        TreeNode *tn = new TreeNode(*it);
        tn->left  = construct(l, it);
        tn->right = construct(it + 1, r);
        return tn;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值