• 线性结构——栈


    堆栈

    • 前缀、中缀和后缀表达式
    • 表达式求值的基本方法

    从左到右读入表达式的各项,运算数:入栈。运算符:从栈中弹出适当数量的运算数,计算并结果入栈,最后,堆栈顶上的元素就是表达式的结果值。

    • 基本策略:将中缀表达式转化为后缀表达式
    //例1:
     2+9/3-5 ————>   2 9 3 5 / + -
    // 运算数的相对顺序不变
    // 运算符号顺序发生改变
         需要存储等待中运算符号
         要与当前的运算符与等待中的预算符号比较
         
    //例2:
      a * (b + c) / d ———— a b c + * d /
    
    • 中例转换示例:( 2*(9+6/3-5)+4)

    栈的顺序存储实现

    • 栈的顺序存储结构通常是由一个一维数组和一个记录栈顶元素位置的变量组成
    typedef int Position;
    typedef int ElementType;
    
    struct SNode {
    	ElementType *Data; // 存储元素的数组
    	Position Top;      // 栈顶指针
    	int MaxSize;       // 栈顶的最大容量
    };
    
    typedef SNode* Stack;
    #define ERROR -1
    
    // 创建一个栈
    Stack Create(int MaxSize)
    {
    	Stack s = (Stack)malloc(sizeof(struct SNode));
    	s->Data = (ElementType*)malloc(sizeof(ElementType));
    	s->Top = -1;
    	s->MaxSize = MaxSize;
    	return s;
    }
    
    // 判断站是否满
    bool Isfull(Stack S)
    {
    	return S->Top = S->MaxSize - 1;
    }
    
    // 入栈
    bool Push(Stack S, ElementType X)
    {
    	if (Isfull(S))
    	{
    		std::cout << "栈已满,操作失败
    " << std::endl;
    		return false;
    	}
    	else
    	{
    		// 栈顶加 1
    		return S->Data[++(S->Top)] = X;
    	}
    }
    
    // 站是否为空
    bool IsEmpty(Stack S)
    {
    	// 注意双等号
    	return (S->Top == -1);
    }
    
    ElementType PopStack(Stack S)
    {
    	if (IsEmpty(S))
    	{
    		std::cout << "栈已空,操作失败
    " << std::endl;
    	}
    	else
    	{
    		return (S->Data[(S->Top)--]);
    	}
    }
    

    栈的链式存储实现

    • 栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行
    typedef int ElementType;
    typedef struct SNode* ptrToStack;
    
    struct SNode {
    	ElementType Data;  // 存储栈中元素
    	ptrToStack Next;   // 栈顶指针
    };
    
    typedef ptrToStack Stack;
    #define ERROR -1
    
    // 创建一个栈
    Stack Create( )
    {
    	Stack s = (Stack)malloc(sizeof(struct SNode));
    	s->Next = NULL;
    	return s;
    }
    
    // 站是否为空
    bool IsEmpty(Stack S)
    {
    	// 注意双等号
    	return (S->Next == NULL);
    
    }
    
    // 入栈
    bool Push(Stack S, ElementType X)
    {
    	// 将元素压入堆栈 S
    	ptrToStack temCell = NULL;
    	temCell = (ptrToStack)malloc(sizeof(struct SNode));
    	temCell->Data = X;
    	temCell->Next = S->Next;
    
    	S->Next = temCell;
    	return true;
    }
    
    // 弹出数据
    ElementType PopStack(Stack S)
    {
    	ptrToStack firstCell;
    	ElementType topElem;
    
    	if (IsEmpty(S))
    	{
    		printf("堆栈空
    ");
    		return ERROR;
    	}
    	else
    	{
    		firstCell = S->Next;
    		topElem = firstCell->Data;
    		S->Next = firstCell->Next;
    		free(firstCell);
    		return topElem;
    	}
    
    }
    

    堆栈的其他应用

    • 函数调用及递归实现
    • 深度优先搜索
    • 回溯算法
  • 相关阅读:
    背包问题
    计蒜客lev3
    线段树BIT操作总结
    图论题收集
    Codeforces Round #607 (Div. 2) 训练总结及A-F题解
    2-sat 学习笔记
    洛谷 P3338 【ZJOI2014】力/BZOJ 3527 力 题解
    $noi.ac$ #51 array 题解
    洛谷 P3292 【SCOI2016】幸运数字/BZOJ 4568 幸运数字 题解
    洛谷 P5283 【十二省联考2019】异或粽子 题解
  • 原文地址:https://www.cnblogs.com/TJTO/p/12443125.html
Copyright © 2020-2023  润新知