[データ構造] - スタック

スタックの説明:

  スタックは、特殊な線形形式で挿入の位置に特殊であり、削除操作は、テーブルの挿入及び欠失一端のみが線形であれば、スタックはLIFOを特徴とする、限られています。
 

抽象データモデルをスタック:

  スタック(スタック)がスタック(トップ)の操作が許可されていないとして表題スタック下端部(下)、スタックと呼ばれる操作の一端を可能にする、挿入および削除テーブルの一端のみが線形であろうことができ、特別な直線状であります操作スタックと呼ばれる挿入要素(プッシュ)は、削除操作は、スタックが空のスタック要素ではないと呼ばれる要素のスタック(POP)と呼ばれます
例えば、データシーケンスを実行{A、B、C、D} {スタックの動作シーケンス、プル、プッシュプッシュ、ポップ、ポップ。}スタック、スタックシーケンス{B、D、C、A}スタックマシン状態が示されています。
  スタック内のスタックのみ挿入および削除操作するので、各スタック要素がトップ要素になり、スタックの各要素は、常に最後の要素であり、スタックにスタック従って特徴付けプッシュ最初にLIFO(最後のOUT) 落下板として、各時間上部に1枚のだけのプレートは、上部プレートから除去は挿入できないか、途中から挿入されています。
スタックの基本的な動作は有するスタックを作成し、空のスタック、スタックは、上部要素および削除するかどうか判断される等。スタックは、指定された場所の挿入をサポートするように削除していません。
 

スタック順序

  順次記憶構造は、順次積層スタック{順次スタック}、次の宣言の順序のスタックと呼ばれる、スタックのインターフェイスは、スタックがヌルに同意することができない、スタックを達成するために、メンバ変数として配列表を使用して実装しました。
  プッシュとポップ操作が尾を除去するために実装され、テールは、配列表に挿入され、時間複雑度は、O(1)、シーケンステーブルを挿入する方法容量を拡張するために必要なときに自動的に拡張されたアレイは、容量を有し、スタックの時間複雑ですO度(n)は
  リニアテーブルとスタックは、データの抽象化のさまざまな種類があり、コンセプトはスタックに依存しない線形テーブルが存在する、我々はシーケンステーブルを使用する唯一のデザインは、配列を使用して実施することができます。
 
 

チェーンスタック

  采用连式存储结构的栈称为链式栈(Linked Stack),单链表结构的链式栈及入栈,出栈操作如图,设单链表(不带头节点)头指针top指向第一个元素节点(栈顶),入栈操作是头插入,在栈顶节点之前插入节点,出栈操作是头删除,删除栈顶节点并返回栈顶元素,再使top指向新的栈顶节点。
声明链式栈类如下,实现栈接口。使用单链表作为成员变量实现栈。入栈和出栈操作实现为单链表头部插入和删除。时间复杂度为O(1).
 

栈的应用

  在实现嵌套调用或者递归调用,实现非线性结构的深度遍历算法、以非递归方式实现递归算法等软件系统设计中,栈都是必不可少的数据结构。

1.栈是嵌套调用机制的实现基础

  在一个函数体重调用另一个函数,称为函数的嵌套调用,例如,在 main() 函数中调用 LinkedStack<T>(), 在LinkedStack<T>()中调用SinglyList<T>(), 此时 3 个函数均在执行,仍然占用系统资资源。根据嵌套调用规则,每个函数在执行完后返回调用语句。那么,操作系统怎样做到返回调用的函数?他是如何知道该返回哪个函数?
  由于函数返回次序与调用次序正好相反,如果借助一个栈“记住”函数从而来,就能获得函数返回的路径。当函数被调用时,操作系统将该函数的有关信息(地址,参数,局部变量值等)入栈,称为保护现场;一个函数执行完成返回后,出栈,获得调用函数信息,称为恢复现场,程序返回调用函数继续运行。
函数嵌套调用及系统栈如图,因此,栈是操作系统实现嵌套调用机制的基础。
 

实例:括号匹配语法检查:

  程序中出现 () [] {} 都应该是左右匹配的,所谓括号匹配,是指一对左右括号不止要个数相等,而且必须先左后右依次出现,以此界定一个范围的起始和结束位置。 例如 () 是匹配的。 )( 是不匹配的,括号语法检查由编译器进行,如果不匹配则不能通过编译。编译器将给出错误信息。
  括号可以嵌套,嵌套括号的原则是,一个右括号与其前面的一个最近的左括号匹配,因此检查括号是否匹配,需要一个栈,保存多个嵌套的左括号。
  设infix是一个表达式字符串,从左向右依次对 infix 中的每个字符ch进行语法检查,若ch是左括号,则ch入栈,若ch是右括号,则出栈,若出栈字符为左括号,表示这一对括号匹配,若栈空或者出栈字符不是左括号,表示缺少与ch匹配 的左括号。
重复执行,当infix检查结束时,若栈空 ,则全部匹配正确。否则,栈中仍然有左括号,表示缺少右括号,
  当infix = “((1+2)*3+4)” 判断括号匹配算法逻辑如图:
 

实例:使用栈计算算数表达式的值

  将运算符写在两个操作数中间的表达式,叫做 中缀表达式(Infix Expression).中缀表达式中,运算符具有不同的优先级,还可以使用圆括号改变运算次序,这两点使得运算规则较复杂,求值过程不能直接从做导游按顺序的进行。
  将运算符卸载两个操作数之前/后的表达式,分别称为 前/后缀表达式 (Prefix/Postfix Expression) 例如将中缀表达式 “1+2*(3-4)+5)” 转换为后缀表达式 1234 - * + 5+ 。后缀表达式中,运算符没有优先级,没有括号。求职过程能够严格从左到右按照顺序的进行,遇到运算符时,对他前面的两个操作数进行求值。符合运算器的求值规律。
  1.将中缀表达式转换为后缀表达式
  运算符优先级:(从低到高) ( + - * / )
  对输入的中缀表达式从左到右遍历:
1)如果遇到数字,直接添加到后缀表达式末尾;
2)如果遇到运算符+、-、*、/:
先判断栈是否为空。若是,则直接将此运算符压入栈。若不是,则查看当前栈顶元素。若栈顶元素优先级大于或等于此操作符级别,则弹出栈顶元素,将栈顶元素添加到后缀表达式中,并继续进行上述判断。如果不满足上述判断或者栈为空,将这个运算符入栈。要注意的是,经过上述步骤,这个运算符最终一定会入栈。
3)如果遇到括号:
如果是左括号,直接入栈。如果是右括号,弹出栈中第一个左括号前所有的操作符,并将左括号弹出。(右括号别入栈)。
4)字符串遍历结束后,如果栈不为空,则弹出栈中所有元素,将它们添加到后缀表达式的末尾,直到栈为空。

二、计算后缀表达式

  后缀表达式的计算就相当简单了。准备一个数字栈。从左到右扫描后缀表达式,如果是数字,放入数字栈。如果是符号,从数字栈中弹出两个数字,第一个取出的数字为右运算数,第二个为左运算数,进行运算。然后将结果放进数字栈中。如此反复,直到读完整个表达式后,留在数字栈中的那个数字就是最终结果。
 
 
 

おすすめ

転載: www.cnblogs.com/gwyy/p/11123233.html