Aritalab:Lecture/Programming/Java/LinkedList
From Metabolomics.JP
< Aritalab:Lecture | Programming | Java(Difference between revisions)
m |
m |
||
Line 1: | Line 1: | ||
− | + | ==Double-linked List== | |
+ | 二重リンクリストは最も単純なデータ構造の一つで、スタックやキューの実装として利用できます。 | ||
+ | <center> | ||
+ | {| class="wikitable" | ||
+ | ! 名称 || 利用するメソッド | ||
+ | |- | ||
+ | | スタック || push(), pop() | ||
+ | |- | ||
+ | | キュー || append(), pop() | ||
+ | |} | ||
+ | </center> | ||
+ | ここでは、C++のテンプレートに相当するJavaのジェネリック機能を用いたプログラムを紹介します。 | ||
+ | ジェネリック型がわかりにくい人は、プログラム中の<tt>GENTYPE</tt>をすべて<tt>Object</tt>に置き換え、<tt><GENTYPE></tt>を全て消去すれば<tt>Object</tt>型を用いた実装になります。 | ||
− | ; | + | ;ジェネリック機能を用いた二重リンクリスト LinkedList.java |
<pre> | <pre> | ||
− | class ListRep { | + | class ListRep<GENTYPE> { |
− | + | GENTYPE obj; | |
− | ListRep( | + | ListRep(GENTYPE o) { obj = o; } |
ListRep prev; | ListRep prev; | ||
ListRep next; | ListRep next; | ||
− | public | + | public GENTYPE inf() { return obj; } |
} | } | ||
− | public class LinkedList { | + | public class LinkedList<GENTYPE> { |
ListRep head =null; | ListRep head =null; | ||
ListRep tail =null; | ListRep tail =null; | ||
int size =0; | int size =0; | ||
− | LinkedList() {} | + | 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 38: | ||
} | } | ||
− | + | 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; | { ListRep x = head; | ||
if (x != null) | if (x != null) | ||
Line 33: | Line 53: | ||
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 | + | 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 52: | Line 75: | ||
//サンプルプログラム | //サンプルプログラム | ||
static public void main(String[] args) | static public void main(String[] args) | ||
− | { LinkedList L = new LinkedList(); | + | { 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> | ||
+ | 実行結果 | ||
+ | <pre> | ||
+ | $ javac LinkedList.java | ||
+ | 注:LinkedList.java の操作は、未チェックまたは安全ではありません。 | ||
+ | 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。 | ||
+ | |||
+ | $ java LinkedList | ||
+ | 4950 | ||
+ | </pre> | ||
+ | プログラムをよく見ると、<tt>pop()</tt>メソッドの戻り値の型はメソッドの中身だけからはわかりません。 | ||
+ | そのため、<tt>(GENTYPE)x.inf()</tt>と参照した値をキャストするため「安全ではありません」という警告が出ています。 |
Revision as of 01:06, 6 October 2010
Double-linked List
二重リンクリストは最も単純なデータ構造の一つで、スタックやキューの実装として利用できます。
名称 | 利用するメソッド |
---|---|
スタック | push(), pop() |
キュー | append(), pop() |
ここでは、C++のテンプレートに相当するJavaのジェネリック機能を用いたプログラムを紹介します。 ジェネリック型がわかりにくい人は、プログラム中のGENTYPEをすべてObjectに置き換え、<GENTYPE>を全て消去すればObject型を用いた実装になります。
- ジェネリック機能を用いた二重リンクリスト 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); } }
実行結果
$ javac LinkedList.java 注:LinkedList.java の操作は、未チェックまたは安全ではありません。 注:詳細については、-Xlint:unchecked オプションを指定して再コンパイルしてください。 $ java LinkedList 4950
プログラムをよく見ると、pop()メソッドの戻り値の型はメソッドの中身だけからはわかりません。 そのため、(GENTYPE)x.inf()と参照した値をキャストするため「安全ではありません」という警告が出ています。