私は元に戻る/やり直しのテクニックを読んでいましたが、それをどのように実装すべきかを理解しています(直感的だと思いました)。
しかし、私は歴史として使われるべきコレクションについて考えています、
多くの人がスタックを使用しますが、C#スタックは配列として実装されており、これは問題です。「制限された」履歴を使用する場合(たとえば、2000コマンドの場合)、制限に達したときに、スタックの最後からアイテムを削除する方法。それを行う方法を見つけた場合は、配列のすべての要素を移動する必要があります(コマンドが実行されるたびにこれを移動します)。
LinkedListは見栄えがしますが、多くのメモリを浪費します。
私の最後のオプションは、リンクリスト、SingleLinkedListのカスタム実装です。このリストのノードはValueプロパティとNextNodeポインタプロパティで構成されているため、各アイテムにダブルメモリを使用しています(ただし、「sizeof(void *)」よりも小さいものを使用している場合を除いて、それ以上は使用しません)。
コレクションの最初の要素へのポインターと最後の要素へのポインターも格納しています。
この方法でコマンドを履歴に簡単に追加してREDO履歴に移動できますが、RemoveLastが許可されていないため、「制限付き」履歴を作成できません(最後のアイテムを削除するには、コレクション全体を調べる必要があります)。
だから私の質問は:LinkedListまたはカスタムSingleLinkedListを使用する必要がありますか?
アップデート1:
現時点で回答をありがとうございます。私の状況では、メモリの問題はありません。誰をターゲットにしているのかわかりません。ユーティリティプログラムを作成しています。私自身の「ユーティリティプログラム」のアイデアでは、可能な限り最小限のCPU/メモリを浪費する必要があります(大きな違いがあるので、明らかに「c ++で書く」とは言わないでください)。
私の意見では、singlelinkedlistはうまく機能します。履歴を制限するのは好きではありません。あなたの履歴が「無制限」である、Photoshopについて考えています。
私は、8時間の使用のように、元に戻す履歴が本当に大きくなったときに何が起こるかを恐れているだけです。そのため、LinkedListを使用して制限することを考えていました。
ただし、他の誰かが述べたように、リンクリストを大きなサイズ、約60000コマンド(十分なはずだと思います)に制限すると、シングルリンクリストと比較して、わずかなメモリ(4バイト* 60000)しか無駄になりません。
そうは言っても、私はLinkedListを使用すると思いますが、念のために言っておきますが、無制限に履歴を使用していれば大丈夫でしたか?
アップデート2:
@Akash Kavaええと、あなたが言うことは重要ですが、なぜLinkedListを使用したいのか、なぜスタックを使用したくないのかを誤解していました。Stackの主な問題は、サイズを制限する必要があることです。この制限に達したときに古いコマンドをすばやく削除する方法はありません(これは配列であり、必要なものではないたびに次元が2倍になります)。
単一のリンクリスト(どのように構築されるかを考えてください)はスタックとして高速であり(すべてのスタック操作はO(1)です)、制限はありません。ただし、この場合、制限を設ける必要はありません。そうしないと、スタックと同じ問題が発生します。わからないため、singlelinkedlistの最後の要素(スタックのように動作します)をすばやく削除する方法がありません。最後のノードからの前のノード要素。
この場合、非常に簡単なので、PreviousポインターがあるLinkedListについて考えることができます。ただし、「スタック」(今回はリンクリストを介して構築されます)の各要素に2つの追加のポインターを使用しています。これは、コマンドを格納するために必要なメモリの3倍のメモリを使用するようなものです(通常のメモリを備えた配列を使用)。使用量、singlelinkedlistのメモリ使用量は2倍、linkedlistのメモリ使用量は3倍です)。
だから私が基本的に求めていたのは、元に戻るパターンのスタックを実装するための「最良の」コレクションはどれかということです。
あなたの答えは、私が1つのプログラムで60000のコマンドを作成したとしても、それはプログラムの約5MBのメモリであり、それほど多くはないと思いました。
基本的に、元に戻す/やり直しの履歴を制限したい場合はLinkedListが必要です。それ以外の場合は、SingleLinkedListの方が適しています。