栈与队列笔记

栈与队列(数据结构笔记)

3.栈与队列

3.1栈

限定仅在表尾进行插入和删除操作的线性表。

允许插入和删除的一端称为栈顶,另一端称为栈底。

后进先出的线性表。

栈的抽象数据类型
Data
同线性表。
Operation
  InitStack(*S):初始化操作,建立一个空栈S。
  DestroyStack(*S):销毁栈。
  ClearStack(*S):清空栈。
  StackEmpty(S):若栈为空,返回true,否则返回false。
  GetTop(S,*e):返回栈顶元素。
  Push(*S,e):插入元素。
  Pop(*S,e):删除元素。
  StackLength(S):返回栈的元素个数。
3.3.1栈的顺序实现
//栈的结构定义
typedef int SElemType;
typedef struct
{
    SElemType data[MAXSIZE];
    int top;//用于栈底指针
}SqStack;
3.3.2进栈
Status Push(SqStack *S,SEleType e)
{
  if(S->top == MAXSIZE-1)//栈满
  {
    return ERROR;
  }
  S->top++;
  S->data[S->top]=e;
  return OK;
}
3.3.3出栈
Status Pop(SqStack *S,SElemType *e)
{
    if(S->top==-1)
    {
        return ERROR;
    }
    *e=S->data[S->top];
    S->top--;
    return OK;
}

3.4 两栈共享空间

//结构
typedef struct
{
    SElemType data;
    int top1;
    int top2;
}SqDoubleStack;
//入栈
Status Push(SqDoubleStack *S,SElemType e,int stackNumber)
{
    if(S->top1+1==S->top2)
    {
        return ERROR;
    }
    if(stackNumber==1)
        S->data[++S->top1]=e;
    if(stacNumber==2)
        S->data[--S->top2]=e;
    return OK;
}
//出栈
Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber)
{
    if(stackNumber==1)
    {
        if(S->top1==-1)
            return REEOR;
        *e=S->data[S->top1--];
    }
     if(stackNumber==2)
    {
        if(S->top2==MAXSIZE)
            return REEOR;
        *e=S->data[S->top1++];
    }
    return OK;
}

3.5栈的链式存储结构即实现

通常链栈是不需要头结点的。

//链栈的存储结构
typedef struct StackNode
{
    SElemType data;
    struct StackNode *next; 
}StackNode,*LinkStackPtr;
typedef struct LinkStack
{
    LinkStackPtr top;
    int count;
}
//进栈
Status Push(LinkStack *S,SElemType e)
{
    LinkStackPtr s=new StackNode;
    s->data=e;
    s->next=S->top;
    S->top=s;
    S->count++;
    return OK;
}
//出栈
Staus Pop(LinkStack *S,SElemType *e)
{
    LinkStackPtr p;
    if(StackEmpty(S))
        return ERROR;
    e=S->top->data;
    p=S->top;
    S->top=S->top->next;
    free(p);
    S->count--;
    return OK;
}

3.6栈的应用——递归

直接调用自己或同一系列调用语句间接调用自己的函数,称为递归函数。

每个递归至少有一个条件,满足递归时不再进行,即不在引用自身而是返回值退出。

3.7四则表达式的运算

3.7.1后缀(逆波兰)表示法定义

举例:9 3 1 - 3 * + 10 2 / +

9,3,1先进栈,减号也进栈,然后计算3-1=2,2进栈,3进栈,*进栈,2 *3=6,6进栈,+进栈,9+6=15,15进栈,10进栈,2进栈,/进栈,10/2=5,5进栈,+进栈,15+5=20,20进栈,20出栈,栈为空。

3.7.2中缀表达式转后缀表达式

标重的四则运算表达式为中缀表达式。

规则,参考书p109。

3.8 队列

ADT 队列(Queue)
Data
同线性表
Operation
   InitQueue(*Q):初始化
   DestroyQueue(*Q):销毁
   ClearQueue(*Q):清空
   QueueEmpty(Q):判断是否为空
   GetHead(Q,*e):用e返回队头元素
   EnQueue(Q,*e):插入
   DeQueue(Q,*e):删除
   QueueLenght(Q):返回队列元素个数
endADT
3.8.1循环队列

队列的头尾相接的顺序存储结构称为循环队列。

顺序存储结构
#include<iostream>
using namespace std;
typedef int Status;
const int MAXSIZE = 100;
const int OK = 1;
const int ERROR = -1;
template<typename QElemType>
class SqQueue
{
public:
	SqQueue() // 初始化
	{
		this->front = 0;
		this->rear = 0;
	}
	Status QueueEmpty(); // 判断是否为空
	Status GetHead(QElemType *e); // 用e返回队头元素
	Status EnQueue(QElemType e); // 入队
	Status DeQueue(QElemType* e); // 出队
	Status QueueLenght(); // 返回队列元素个数
private:
	QElemType data[MAXSIZE];
	int front;
	int rear;
};
#include"Queue.h"
using namespace std;
template<typename QElemtype>
Status SqQueue<QElemtype>::QueueEmpty()
{
	if (this->front == this->rear)
		return OK;
}
template<typename QElemType>
Status SqQueue<QElemType>::GetHead(QElemType* e)// 用e返回队头元素
{
	if (this->QueueEmpty())
		return ERROR;
	*e = this->data[this->front];
}
template<typename QElemType>
Status SqQueue<QElemType>:: EnQueue(QElemType e)
{
	if ((this->rear + 1) % MAXSIZE == this->front)
		return ERROR;
	this->data[this->rear] = e;
	this->rear = (this->rear + 1) % MAXSIZE;
	return OK;
}
template<typename QElemType>
Status SqQueue<QElemType>::DeQueue(QElemType* e)
{
	if (this->QueueEmpty())
		return ERROR;
	*e = this->data[this->front];
	this->front = (this->front + 1) % MAXSIZE;
	return OK;
}
template<typename QElemType>
Status SqQueue<QElemType>::QueueLenght()
{
	return(this->rear - this->front + MAXSIZE) % MAXSIZE;
}
队列的链式存储
#include<iostream>
using namespace std;
typedef int Status;
const int OK = 1;
const int ERROR = -1;
template<typename QElemType>
class QNode//结点
{
public:
	QElemType data;
	QNode* next;
};
template<typename QElemType>
class LinkQueue//链队结构
{
public:
	Status EnQueue(QElemType e);
	Status DeQueue(QElemType *e);
private:
	QNode<QElemType>* front, rear;
};
#include"QNode.h"
template<typename QElemType>
Status LinkQueue<QElemType>::EnQueue(QElemType e)
{
	QNode<QElemType>* p = new QNode;
	if (!p) // 存储空间分配失败
		exit(OVERFLOW);
	p->data = e;
	p->next = NULL;
	this->rear->next = p;
	this->rear = p;
	return OK;
}
template<typename QElemType>
Status LinkQueue<QElemType>::DeQueue(QElemType *e)
{
	if (this->front == this->rear)
		return ERROR;
	QNode<QElemType>* p;
	p = this->front->next;
	*e = p->data;
	this->front->next = p->next;
	if (this->rear = p)
		this->rear = this->front;
	delete p;
	return OK;
}

3.9栈与队列练习题

3.9.1括号匹配问题
class Solution {
public:
    bool isValid(string s) {
    stack<char> s1;
    if(s.size()%2!=0)
        return false;
    for (int i = 0; i < s.size(); ++i)
    {
        if (s[i] == '(' || s[i] == '[' || s[i] == '{')
            s1.push(s[i]);
        else
        {
            if(s1.empty())
                return false;
            char top = s1.top();
            if ((top == '(' && s[i] == ')') || (top == '[' && s[i] == ']') || (top == '{' && s[i] == '}'))
                s1.pop();
            else
                return false;
        }
    }
    return s1.empty();
    }
};
3.9.2用队列实现栈
class MyStack {
public:
    MyStack() {


    }
    
    void push(int x) {
        //先判断栈是否为空
        if(empty())
        {
            q1.push(x);
            return;
        }
        //如果不为空,在有数据的那个队列里入队元素
        if(!q1.empty())
            q1.push(x);
        else
            q2.push(x);
    }
    
    int pop() {
        //将有数据的队列中的数据放入另一个队列中,只留最后一个输出
        if(!q1.empty())
        {
            int n = q1.size();
            for(int i=0;i<n-1;++i)
            {
                q2.push(q1.front());
                q1.pop();
            }
            int num=q1.front();
            q1.pop();
            return num;
        }
        else
        {
            int n = q2.size();
            for(int i=0;i<n-1;++i)
            {
                q1.push(q2.front());
                q2.pop();
            }
            int num=q2.front();
            q2.pop();
           return num;
        }
    }
    
    int top() {
        if(!q1.empty())
            return q1.back();
        return q2.back();
    }
    
    bool empty() {
        if(q1.empty()&&q2.empty())
            return true;
        return false;
    }
private:
    queue<int> q1;
    queue<int> q2;
};
3.9.3用栈实现队列
class MyQueue {
public:
    MyQueue() {


    }
    
    void push(int x) {
        stk1.push(x);
    }
    
    int pop() {
        if(empty())
            return 0;
        if(stk2.empty())
        {
            while(!stk1.empty())
            {
                stk2.push(stk1.top());
                stk1.pop();
            }
        }
        int num=stk2.top();
        stk2.pop();
        return num;
    }
    
    int peek() {
        if(empty())
            return 0;
        if(stk2.empty())
        {
            while(!stk1.empty())
            {
                stk2.push(stk1.top());
                stk1.pop();
            }
        }
        return stk2.top();
    }
    
    bool empty() {
        return stk1.empty()&&stk2.empty();
    }
private:
    stack<int> stk1;
    stack<int> stk2;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值