二:栈的初始化操作及应用

顺序栈的结点结构

这里只需要更改SElemType就行,比如说单位里面存放的是整型int,就变成int就行了,如果说存放的是指向树的指针:那就 把SElemType 变成 BiTree 就行了或者换成 BiTNode *

这个base在初始化的时候分配空间用到。
top指在栈顶元素的下一个位置
特殊的线性表;;注意S.top;;
进栈的变化 以及 出栈的变化 ;;

typedef struct {
    SElemType	*base;  //数组首地址
    SElemType   *top;   //栈顶指针
    int 	stacksize; //栈容量
}SqStack;

初始化空栈: InitStack(&S)

int Init_Stack_Int(SqStack &S){
    S.base=(int*)malloc(sizeof(int)*MAXSIZE);
    if(S.base) exit (OVERFLOW);
    S.top=S.base;
    S.stacksize=MAXSIZE;
    return OK;
}

销毁栈: DestroyStack(&S)

int DestoryStack(SqStack &S){
    if(S.base){
        free(S.base);
        S.stacksize=0;
        S.base=S.top=NULL;
    }
    return OK;
}

清空栈: ClearStack(&S)

在这里插入代码片

判栈空: StackEmpty(S)

Status StackEmpty(SqStack S){
		//若栈空,返回TRUE;否则返回FALSE。
		if(S.top==S.base) return TRUE; //栈空
		else return FALSE;
}//StackEmpty

求栈长: StackLength(S)

int StackLen(SqStack S){
    return S.top-S.base;
}

读栈顶: GetTop(S, &e)

Status GetTop(SqStack S, SElemType &e){
		//若栈不空,则用e返回S的栈顶元素,并返OK,
		//否则返回ERROR
		if(S.top==S.base) return ERROR; //栈空
		e=*(S.top-1);
		return OK;
}//GetTop

进栈: Push(&S, e)

Status Push(SqStack &S, SElemType e){
   //插入元素e为新的栈顶元素
   if(S.top-S.base>=S.stacksize) {//栈满,追加空间
      S.base=(SElemType*)realloc(S.base,
		  (S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) exit(OVERFLOW);
	  S.top=S.base+S.stacksize;
      S.stacksize+=STACKINCREMENT;
   }
  *(S.top++)=e;
  return OK;
}//Push

出栈: Pop(&S, &e)

status Pop(SqStack &S, SElemType &e){
   //若栈不空,则删除栈顶元素,用e返回其值,并返回OK;
	//否则返回ERROR
   if(S.top==S.base) return ERROR;  //栈空
   e=*--S.top);
   return OK;
}//Pop

链式栈的结点结构

一般链式的结构都分为两部分:结点定义+整体定义

typedef struct  SNode{
   ElemType  data;
   struct  SNode  *next;
}SNode ,*LinkStackPoi;

typedef struct LinkStack {
	LinkStackPoi top;//栈顶结点
	int count;//元素个数
}LinkStack;

初始化空栈

由于LinkStack 是变量形式,不是指针形式,即下方的传递的不是变量 LinkStack S,而是 LinkStack *S,传的还是指针。

//初始化
Status InitLinkStack(LinkStack* stack)
{
	if (!stack)
	{
		return	ERROR;
	}
	stack->top = NULL;
	stack->count = 0;
	return OK;
}

清空栈


Status ClearLinkStack(LinkStack* stack)
{
	if (!stack||!stack->count)
	{
		return	ERROR;
	}
	while (stack->count)
	{
		StackNode* node = stack->top;
		stack->top = node->next;
		free(node);
		stack->count--;
	}
	return OK;
}

判断栈是否空


Status EmptyLinkStack(LinkStack* stack) {
	if (!stack)
	{
		return ERROR;
	}
	return stack->count == 0 ? 1 : 0;
}

获取元素个数


//获取元素个数
int GetLengthLinkStack(LinkStack* stack)
{
	if (!stack )
	{
		return	-1;
	}
	return stack->count;
}

得到栈顶元素

int GetStackTop(SqStack S,int &e){
    if(S.top==S.base)
        return ERROR;
    e=*(S.top-1);
    return OK;
}
Status GetTop(LinkStack* stack, StackNode** stackNode)
{
	if (!stack)
	{
		return	ERROR;
	}
	*stackNode = stack->top;//将栈顶元素的指针返回,获取指向可修改栈顶元素内容。
	return OK;
}

入栈

下面的这些的LinkStack 就是指针的形式。
链式栈的 进栈和 出栈 等等;;

status Push(LinkStack &S, SElemType e){
   //插入元素e为新的栈顶元素
   LinkStack p=(LinkStack)malloc(sizeof(SNode));
	 if(!p)   exit(OVERFLOW);
   p->data=e;
   p->next=S->next; S->next=p; //头插栈顶元素
   return OK;
}//Pusp

出栈

status Pop(LinkStack &S, SElemType &e){
   //若栈不空,则删除栈顶元素,用e返回其值,并返回OK;
	//否则返回ERROR
   if(S->next==NULL) return ERROR;  //栈空
   LinkStack p=s->next;
   e=p->data;
   S->next=p->next; free(p); //删除栈顶元素
   return OK;
}//Pop

数值转换


//数值转换 主要是 利用了栈的 特性;;
void  Convert(int N, int  d){//将十进制N转换成d进制数输出
   InitStack(S);
   cin>>N;
   while(N){
   Push(S,N%8);
   N=N/8;
   }
   while(!StackEmpty(S)){
     Pop(S,e);
     cout<<e<<endl;

  }

}//Convert

括号匹配问题

https://zhuanlan.zhihu.com/p/134675879 知乎大佬讲解

1、首先将这个字符串转换成字符数组,并初始化一个空栈。
2、遍历到第0个元素,(,为左括号,入栈
3、后面以此类推,遍历完第3个元素[后,栈空间应该是这样的
4、遍历到第4个元素]时,发现为右括号,此时,从栈顶出栈一个左括号,即[,刚好[与],匹配成一对
5、以此类推,直到第6个元素),都是匹配的
6、此时,序列已经遍历完毕,但是栈不是空的,所以原序列匹配失败

#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
using namespace std;
int matches(string a){
	stack<char> s;
	int l=a.length(),label=0;
    char t;
	for(int i=0;i<l;++i)
    {
        if(a[i]=='('||a[i]=='['||a[i]=='{')
        {
            s.push(a[i]);
        }
        if(a[i]==')'||a[i]==']'||a[i]=='}')
        {
		if(s.empty())return 3;
        else 
		{
		
        if(a[i]==')')
        {
        	t=s.top();
           if(t=='(')s.pop();
           else
           {
                label=1;
           		s.pop();
           		return 1;
	        }
			   
           
        }
        if(a[i]==']')
        {
           t=s.top();
           if(t=='[')s.pop();
           else
           {
           	    label=1;
           	    s.pop();
           		return 1;
			   
           }
        }
        if(a[i]=='}')
        {
           t=s.top();
           if(t=='{')s.pop();
           else
           {
		   
           		label=1;
           		s.pop();
           		return 1;   
           }
        }
		}
		}
    }
       if(!s.empty())return 2;
       if(s.empty()&&label!=1) return 0;
	
}
int main()
{
    string a;
    cin>>a;
    cout<<matches(a)<<endl;
    return 0;
}

迷宫问题

https://blog.csdn.net/Vit_rose/article/details/52781116 大佬代码

在这里插入代码片

表达式求值问题

三种表达式求值的问题

在这里插入代码片
  • 7
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值