51CTO オープンソース基本ソフトウェア コミュニティ をご覧ください。
1. スタックの概念
スタックは次のように構成されていますオブジェクトごとに編成された一連のオブジェクトのコレクション。これらのオブジェクトの追加および削除操作は、「後入れ先出し」(LIFO) の原則に従います。
いつでもスタックに挿入できるオブジェクトは 1 つだけですが、取得または削除できるのはスタックの最上位でのみです。たとえば、本の山の中で、表紙が露出しているのは一番上の本だけです。他の本を取り出すには、図に示すように一番上の本を取り出すしかありません。
## スタックの実用的な応用
#実際、多くのアプリケーションは次のようなスタックを使用します。
Web ブラウザは、最近アクセスした URL を次の場所に保存します。スタック。ユーザーの訪問者が新しい Web サイトにアクセスするたびに、新しい Web サイトの URL がスタックの一番上にプッシュされます。このようにして、ブラウザの [戻る] ボタンをクリックするたびに (またはキーボード ショートカット CTRL Z、ほとんどの元に戻すショートカットを押すと)、最後にアクセスした URL をポップアップ表示して、前回アクセスしたときの閲覧状態に戻ることができます。- テキスト エディタには通常、最新の編集操作をキャンセルして前の状態に戻る「元に戻す」メカニズムが備わっています。この取り消し操作は、テキストの変更された状態をスタックに保存することによっても実現されます。
- 一部の高級言語のメモリ管理、JVM スタック、Python スタックは、メモリ管理、入れ子になった言語機能のランタイム環境などにも使用されます。
- バックトラック (ゲームのプレイ、パスの検索、網羅的検索)
- ハノイ塔、ツリー トラバーサル、ヒストグラム問題などのアルゴリズムで使用され、トポロジカル ソートなどのグラフ アルゴリズムでも使用されます
- 構文処理:
- 中括弧の一致に関するコンパイラ構文チェック
- 再帰のサポート
- コンパイラにおける接尾辞や接頭辞などの式
- 2. 抽象データ型stack
あらゆるデータ構造は、データの保存と取得の方法から切り離せません。上で述べたように、スタックは順序付けられた要素のコレクションであり、追加、操作、および削除はすべて発生します。その最上部では (
Stack(): 空のスタックを作成します。パラメータは必要なく、空のスタックを返します。- push(e): 要素 e をスタック S の先頭に追加します。パラメータ e が必要で、戻り値はありません。
- pop(): スタックの最上位にある要素を削除します。パラメータは必要ありませんが、最上位の要素を返し、スタックの内容を変更します。
- top(): スタックの先頭にある要素を返しますが、スタックの先頭にある要素は削除しません。スタックが空の場合、この操作は動作します。
- is_empty(): スタックに要素が含まれていない場合は、ブール値 True を返します。
- size(): スタック内の要素のデータを返します。パラメータは必要なく、整数を返します。 Python では、これは特別なメソッド __len__ を使用して実現できます。
Python スタックのサイズは固定されている場合もあれば、サイズの変更を許可する動的実装がある場合もあります。固定サイズのスタックの場合、すでにいっぱいのスタックに要素を追加しようとすると、スタック オーバーフロー例外が発生します。同様に、
操作を使用してすでに空のスタックから要素を削除しようとすることをアンダーフローと呼びます。 3. Python リストを使用してスタックを実装する
Python を学習するときは、Python リスト
list を学習している必要があります。メソッド内 スタックの関数を実装します:
- pop() メソッドは、ポップ操作をシミュレートするために使用されます。
- L[-1] を介して top() 操作をシミュレートします。
- len(L)==0 を判定して isEmpty() 操作をシミュレートします。
- size() 関数を len() 関数を通じて実装します。
コードは以下のように表示されます:
class ArrayStack: """ 通过 Python 列表实现 LIFO 栈""" def __init__(self): self._data = [] def size(self): """ return the number of elements in the stack""" return len(self._data) def is_empty(self): """ return True if the stack is empty""" return len(self._data) == 0 def push(self, e): """ add element e to the top of the stack""" self._data.append(e) def pop(self): """ remove and return the element from the top of the stack """ if self.is_empty(): raise Exception('Stack is empty') return self._data.pop() def top(self): """return the top of the stack Raise Empty exception if the stack is empty """ if self.is_empty(): raise Exception('Stack is empty') return self._data[-1]# the last item in the list arrayStack = ArrayStack() arrayStack.push("Python") arrayStack.push("Learning") arrayStack.push("Hello") print("Stack top element: ", arrayStack.top()) print("Stack length: ", arrayStack.size()) print("Stack popped item: %s" % arrayStack.pop()) print("Stack is empty?", arrayStack.is_empty()) arrayStack.pop() arrayStack.pop() print("Stack is empty?", arrayStack.is_empty()) # arrayStack.pop()
このプログラムを実行すると、結果は次のようになります:
Stack top element:Hello Stack length:3 Stack popped item: Hello Stack is empty? False Stack is empty? True
リストの末尾をスタックの先頭として使用することに加えて、リストの先頭をスタックの先頭として使用することもできます。ただし、この場合、pop() メソッドと append() メソッドを直接使用することはできませんが、pop() メソッドと insert() メソッドを通じて、リストの最初の要素であるインデックス 0 の要素に明示的にアクセスできます。
class ArrayStack: """ 通过 Python 列表实现 LIFO 栈""" def __init__(self): self._data = [] def size(self): """ return the number of elements in the stack""" return len(self._data) def is_empty(self): """ return True if the stack is empty""" return len(self._data) == 0 def push(self, e): """ add element e to the top of the stack""" self._data.insert(0, e) def pop(self): """ remove and return the element from the top of the stack """ if self.is_empty(): raise Exception('Stack is empty') return self._data.pop(0) def top(self): """return the top of the stack Raise Empty exception if the stack is empty """ if self.is_empty(): raise Exception('Stack is empty') return self._data[0]# the last item in the list
抽象データ型の実装を変更しましたが、その論理特性は保持しました。この能力は抽象的思考を体現します。どちらのメソッドもスタックを実装していますが、パフォーマンス方法は異なります。
- append() メソッドと Pop() メソッドの時間計算量は両方とも *O(1)、*定数レベルの操作#です。 ##2 番目の実装のパフォーマンスは、スタック内の要素の数によって制限されます。これは、insert(0) と Pop(0) の時間計算量が O(n) であるためです。要素が多いほど、遅くなります。
>>> from collections import deque >>> myStack = deque() >>> myStack.append('Apple') >>> myStack.append('Banana') >>> myStack.append('Orange') >>> >>> myStack deque(['Apple', 'Banana', 'Orange']) >>> myStack.pop() 'Orange' >>> myStack.pop() 'Banana' >>> >>> len(myStack) 1 >>> myStack[0] 'Apple' >>> myStack.pop() 'Apple' >>> >>> myStack.pop() Traceback (most recent call last): File "<pyshell#13>", line 1, in <module> myStack.pop() IndexError: pop from an empty deque >>>リストがあるのに、なぜ deque が必要なのでしょうか? deque と list が要素に対して同様の操作を行うことがわかると思いますが、Python ではなぜ deque データ構造をリストに追加するのでしょうか? これは、Python のリストが連続したメモリ ブロックに構築されているためです。つまり、リストの要素は互いに近くに格納されます。
>>> from queue import LifoQueue >>> stack = LifoQueue() >>> stack.put('H') >>> stack.put('E') >>> stack.put('L') >>> stack.put('L') >>> stack.put('O') >>> stack <queue.LifoQueue object at 0x00000123159F7310> >>> >>> stack.get() 'O' >>> stack.get() 'L' >>> stack.empty() False >>> stack.qsize() 3 >>> stack.get() 'L' >>> stack.get() 'E' >>> stack.qsize() 1 >>> stack.get() 'H' >>> stack.get_nowait() Traceback (most recent call last): File "<pyshell#31>", line 1, in <module> stack.get_nowait() _queue.Empty >>> >>> stack.put('Apple') >>> stack.get_nowait() 'Apple'
与 deque 不同,LifoQueue 被设计为完全线程安全的。它的所有方法都可以在线程环境中安全使用。它还为其操作添加了可选的超时功能,这在线程程序中经常是一个必须的功能。
然而,这种完全的线程安全是有代价的。为了实现这种线程安全,LifoQueue 必须在每个操作上做一些额外的工作,这意味着它将花费更长的时间。
通常情况下,这种轻微的减速对你的整体程序速度并不重要,但如果你已经测量了你的性能,并发现你的堆栈操作是瓶颈,那么小心地切换到 deque 可能是值得做的。
六、选择哪一种实现作为栈
一般来说,如果你不使用多线程,你应该使用 deque。如果你使用多线程,那么你应该使用 LifoQueue,除非你已经测量了你的性能,发现 push 和 pop 的速度的小幅提升会带来足够的差异,以保证维护风险。
你可以对列表可能很熟悉,但需要谨慎使用它,因为它有可能存在内存重新分配的问题。deque 和 list 的接口是相同的,而且 deque 没有线程不安全问题。
七、总结
本文介绍了栈这一数据结构,并介绍了在现实生活中的程序中如何使用它的情况。在文章的中,介绍了 Python 中实现栈的三种不同方式,知道了 deque 对于非多线程程序是一个更好的选择,如果你要在多线程编程环境中使用栈的话,可以使用 LifoQueue。
以上がPython でスタックを実装するいくつかの方法とその利点と欠点の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于Seaborn的相关问题,包括了数据可视化处理的散点图、折线图、条形图等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于进程池与进程锁的相关问题,包括进程池的创建模块,进程池函数等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于简历筛选的相关问题,包括了定义 ReadDoc 类用以读取 word 文件以及定义 search_word 函数用以筛选的相关内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于数据类型之字符串、数字的相关问题,下面一起来看一下,希望对大家有帮助。

VS Code的确是一款非常热门、有强大用户基础的一款开发工具。本文给大家介绍一下10款高效、好用的插件,能够让原本单薄的VS Code如虎添翼,开发效率顿时提升到一个新的阶段。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于numpy模块的相关问题,Numpy是Numerical Python extensions的缩写,字面意思是Python数值计算扩展,下面一起来看一下,希望对大家有帮助。

pythn的中文意思是巨蟒、蟒蛇。1989年圣诞节期间,Guido van Rossum在家闲的没事干,为了跟朋友庆祝圣诞节,决定发明一种全新的脚本语言。他很喜欢一个肥皂剧叫Monty Python,所以便把这门语言叫做python。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

WebStorm Mac版
便利なJavaScript開発ツール

Dreamweaver Mac版
ビジュアル Web 開発ツール

Safe Exam Browser
Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

メモ帳++7.3.1
使いやすく無料のコードエディター

ホットトピック



