「リスト(list)」というデータ構造は、通常、次のような構造を表します。
しかし、教科書では、上記の構造を「連結リスト」と呼び、 「リスト」という語を「データを線形に並べたもの」とか「一覧表」 などという意味で使用しているようです。混乱しないように注意して下さい。
項番 | 操作 |
---|---|
1 | k番目の要素の前に要素を挿入する |
2 | k番目の要素を削除する |
3 | k番目の要素の内容を読む/書く |
4 | 特定のキーを持つ要素を探索する |
5 | 複数のリストを1つにまとめる |
6 | 1つのリストを複数のリストに分割する |
7 | リストの複製を作る |
8 | リストに含まれる要素の個数を求める |
int[] x = new int[データの最大個数];
k番目に要素を挿入するには、それよりも後ろの要素を全て 1ずつずらしてコピーする必要があります。 要素の個数がn個だとすると、ずらすべき要素の個数は平均で n/2 となるので、要素を1個挿入するための計算量はO(n) です。
k番目の要素を削除するための計算量も、同様にO(n)と なります。
k番目の要素を読み書き(アクセス)するには k[i] でいいので、計算量はO(1)となります。
結論として、リストへの要素の挿入や削除が多く発生する場合、 配列は適切な実現方法ではないことになります。
「挿入と削除がリストの先頭のみで行われるもの」が「スタック (stack)」です。
スタックでは、リストの先頭をtop, 最後をbottomと呼びます。 「topにデータを挿入すること」を push, 「topからデータを取り出すこと」を popと呼びます。
「最初に挿入されたデータが最後に取り出される」ために "First In, Last Out" と呼ぶことがあります。 もちろん、逆の見方をすれば 「最後に挿入されたデータが最初に取り出される」ことになるので "Last In, First Out" とも言います。
MyStack.java |
RunMyStack.java |
RunMyStack.javaの実行例 |
|
式 $(a + b) \times (c - d)$ を括弧を使わずに読み上げてみましょう。 もし、「$a$ 足す $b$ かける $c$ 引く $d$ 」 と読み上げると $ a + b \times c - d$ との区別がつかなくなってしまいます。 このような場合は、「演算子をデータの後から読み上げる」 方法を取るとうまくいきます。 つまり 「$a$ と $b$ を足したもの に $c$ から $d$ を引いたものを掛けたもの」 と表現すると括弧を使わずにうまく表現できます。
このような、「データを先に書いて、演算子を後に書く方法」を、 『後置記法 (postfix notation)』とか『逆ポーランド記法 (reverse polish notation)』などと呼びます。 逆ポーランド記法を用いると、上記の例は 「$a$ $b$ $+$ $c$ $d$ $−$ $\times$」 と表現されます。 式を表すのに括弧が不要なので「演算式の処理が簡単である」 という利点が逆ポーランド記法にはあります。
ちなみに、 式 $(a + b) \times (c - d)$ のような通常の記法を挿入記法 (infix notation)と呼びます。
逆ポーランド記法で表現された式を処理するときは
例として (3 + 5) * (7 - 1) という式が逆ポーランド記法で 表されたときに、スタックを使ってどのように処理できるか 見てみましょう。
挿入記法: (3 + 5) * (7 - 1)
逆ポーランド記法: 3 5 + 7 1 - *
スタックの様子 bottom ... top | 入力 | 備考 |
---|---|---|
空 | 初期状態 | |
3 | 3 | データをスタックにpush |
3 5 | 5 | データをスタックにpush |
8 | + | 2個popして演算し結果をスタックにpush |
8 7 | 7 | データをスタックにpush |
8 7 1 | 1 | データをスタックにpush |
8 6 | - | 2個popして演算し結果をスタックにpush |
48 | * | 2個popして演算し結果をスタックにpush |
48 | 最後にスタック上に1個残ったデータが演算結果 |
Calculator.java |
|
Calculator.javaの実行例 |
|
課題提出〆切は次回の講義の開始時刻です。
提出先 | http://ynitta.com/class/algoA/local/handin/list.php?id=kadai4a |
---|---|
提出ファイル | Calculator.java |
コメント欄 | 以下の3種類データに対する出力結果 |
Calculator.java を次のデータに対して動作させて下さい (注意: Calculator.javaの実行にはMyStack.javaも必要です)。
[データ1]
73 26 * 5 10 + 27 103 19 - * - -
[データ2]
21 17 5 203 32 - 2 3 5 * * + - - 108 9 / +
[データ3]
21 17 5 203 32 - 2 3 5 * * + - - 108 9 / - +
提出先 | http://ynitta.com/class/algoA/local/handin/list.php?id=kadai4b |
---|---|
提出ファイル | Calculator2.java |
コメント欄 | 実行したときの出力結果 |
課題4aで作成した Calculator.java を参考にして、 実数を扱えるようにしたCalculator2.javaを作成しなさい。 すべての計算は実数で行えばよいものとします。
コメント欄には実行結果を貼り付けておいて下さい。
Calculator2.javaの実行例 |
|