Aritalab:Lecture/Programming/Java/LinkedList
From Metabolomics.JP
< Aritalab:Lecture | Programming | Java(Difference between revisions)
m (New page: 二重リンクリスト ;File List.java <pre> class ListRep { // publicなclassではない(List.java中に書ける。) Object obj; ListRep(Object o) { obj = o; } // コンス...) |
m |
||
| (8 intermediate revisions by one user not shown) | |||
| Line 1: | Line 1: | ||
| − | + | ==Double-linked List== | |
| + | 二重リンクリストは最も単純なデータ構造の一つで、スタックやキューの実装として利用できます。 | ||
| + | <center> | ||
| + | {| class="wikitable" | ||
| + | ! 名称 || 利用するメソッド | ||
| + | |- | ||
| + | | スタック || push(), pop() | ||
| + | |- | ||
| + | | キュー || append(), pop() | ||
| + | |} | ||
| + | </center> | ||
| + | ここでは、C++のテンプレートに相当するJavaのジェネリック機能を用いたプログラムを紹介します。 | ||
| + | ジェネリック型がわかりにくい人は、プログラム中の<tt>GENTYPE</tt>型をすべて<tt>Object</tt>型に置き換え、クラス定義やnew構文にある<tt><GENTYPE></tt>を全て消去すれば<tt>Object</tt>型を用いた実装になります。 | ||
| − | ; | + | ;ジェネリック機能を用いた二重リンクリスト LinkedList.java |
<pre> | <pre> | ||
| − | + | // リスト実装に使うコンテナクラス。外部には見せない。 | |
| − | + | // public class としなければ、ファイル LinkedList.java 中に定義できます。 | |
| − | ListRep( | + | class ListRep<GENTYPE> { |
| + | GENTYPE obj; | ||
| + | ListRep(GENTYPE o) { obj = o; } | ||
ListRep prev; | ListRep prev; | ||
ListRep next; | ListRep next; | ||
| − | public | + | public GENTYPE inf() { return obj; } |
} | } | ||
| − | public class | + | public class LinkedList<GENTYPE> { |
ListRep head =null; | ListRep head =null; | ||
ListRep tail =null; | ListRep tail =null; | ||
int size =0; | int size =0; | ||
| − | + | LinkedList() {} | |
| − | void push( | + | void push(GENTYPE o) // リストの先頭に追加 |
| − | { ListRep r = new ListRep(o); | + | { ListRep r = new ListRep<GENTYPE>(o); |
if (size > 0) head.prev = r; else tail = r; | if (size > 0) head.prev = r; else tail = r; | ||
r.next = head; | r.next = head; | ||
| Line 26: | Line 40: | ||
} | } | ||
| − | + | void append(GENTYPE o) // リストの末尾に追加 | |
| + | { ListRep r = new ListRep<GENTYPE>(o); | ||
| + | if (size > 0) tail.next = r; else head = r; | ||
| + | r.prev = tail; | ||
| + | tail = r; | ||
| + | size++; | ||
| + | } | ||
| + | </pre> | ||
| + | <pre> | ||
| + | GENTYPE pop() // リストの先頭から削除 | ||
{ ListRep x = head; | { ListRep x = head; | ||
if (x != null) | if (x != null) | ||
| Line 33: | Line 56: | ||
if (y != null) y.prev = null; else tail = null; | if (y != null) y.prev = null; else tail = null; | ||
size--; | size--; | ||
| − | return x.inf( | + | return (GENTYPE)x.inf(); |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
} | } | ||
| + | else { | ||
| + | System.err.println("Error: empty list (function pop)"); | ||
| + | return null; | ||
| + | } | ||
} | } | ||
| − | + | GENTYPE peek() // リストの先頭を参照 | |
| − | { | + | { if (head != null) |
| − | + | return (GENTYPE)head.inf(); | |
| − | + | else { | |
| − | + | System.err.println("Error: empty list (function peek)"); | |
| − | + | return null; | |
| + | } | ||
} | } | ||
| Line 54: | Line 78: | ||
//サンプルプログラム | //サンプルプログラム | ||
static public void main(String[] args) | static public void main(String[] args) | ||
| − | { | + | { LinkedList<Integer> L = new LinkedList<Integer>(); |
| − | for(int i=0; i < | + | for(int i=0; i < 100; i++) |
L.push(i); | L.push(i); | ||
| + | int sum=0; | ||
while (!L.empty()) | while (!L.empty()) | ||
| − | System.out.println( | + | sum += L.pop(); |
| + | System.out.println(sum); | ||
} | } | ||
} | } | ||
</pre> | </pre> | ||
| + | ;実行結果 | ||
| + | 0から100までの数字を逆順に取り出して(スタック)、和をとっています。 | ||
| + | <pre> | ||
| + | $ javac LinkedList.java | ||
| + | 注:LinkedList.java の操作は、未チェックまたは安全ではありません。 | ||
| + | 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。 | ||
| + | |||
| + | $ java LinkedList | ||
| + | 4950 | ||
| + | </pre> | ||
| + | プログラムをよく見ると、<tt>pop()</tt>メソッドの戻り値の型はメソッドの中身だけからはわかりません。 | ||
| + | 戻り値をキャストするのに<tt>(GENTYPE)x.inf()</tt>と書いているため、コンパイル時に「安全ではありません」という警告が出てきます。(利用には問題ありません。) | ||
Latest revision as of 10:13, 19 May 2011
[edit] Double-linked List
二重リンクリストは最も単純なデータ構造の一つで、スタックやキューの実装として利用できます。
| 名称 | 利用するメソッド |
|---|---|
| スタック | push(), pop() |
| キュー | append(), pop() |
ここでは、C++のテンプレートに相当するJavaのジェネリック機能を用いたプログラムを紹介します。 ジェネリック型がわかりにくい人は、プログラム中のGENTYPE型をすべてObject型に置き換え、クラス定義やnew構文にある<GENTYPE>を全て消去すればObject型を用いた実装になります。
- ジェネリック機能を用いた二重リンクリスト LinkedList.java
// リスト実装に使うコンテナクラス。外部には見せない。
// public class としなければ、ファイル LinkedList.java 中に定義できます。
class ListRep<GENTYPE> {
GENTYPE obj;
ListRep(GENTYPE o) { obj = o; }
ListRep prev;
ListRep next;
public GENTYPE inf() { return obj; }
}
public class LinkedList<GENTYPE> {
ListRep head =null;
ListRep tail =null;
int size =0;
LinkedList() {}
void push(GENTYPE o) // リストの先頭に追加
{ ListRep r = new ListRep<GENTYPE>(o);
if (size > 0) head.prev = r; else tail = r;
r.next = head;
head = r;
size++;
}
void append(GENTYPE o) // リストの末尾に追加
{ ListRep r = new ListRep<GENTYPE>(o);
if (size > 0) tail.next = r; else head = r;
r.prev = tail;
tail = r;
size++;
}
GENTYPE pop() // リストの先頭から削除
{ ListRep x = head;
if (x != null)
{ ListRep y = x.next;
head = y;
if (y != null) y.prev = null; else tail = null;
size--;
return (GENTYPE)x.inf();
}
else {
System.err.println("Error: empty list (function pop)");
return null;
}
}
GENTYPE peek() // リストの先頭を参照
{ if (head != null)
return (GENTYPE)head.inf();
else {
System.err.println("Error: empty list (function peek)");
return null;
}
}
int size() { return size; }
boolean empty() { return (size==0); }
//サンプルプログラム
static public void main(String[] args)
{ LinkedList<Integer> L = new LinkedList<Integer>();
for(int i=0; i < 100; i++)
L.push(i);
int sum=0;
while (!L.empty())
sum += L.pop();
System.out.println(sum);
}
}
- 実行結果
0から100までの数字を逆順に取り出して(スタック)、和をとっています。
$ javac LinkedList.java 注:LinkedList.java の操作は、未チェックまたは安全ではありません。 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。 $ java LinkedList 4950
プログラムをよく見ると、pop()メソッドの戻り値の型はメソッドの中身だけからはわかりません。 戻り値をキャストするのに(GENTYPE)x.inf()と書いているため、コンパイル時に「安全ではありません」という警告が出てきます。(利用には問題ありません。)