Aritalab:Lecture/Programming/Java/LinkedList

From Metabolomics.JP
< Aritalab:Lecture | Programming | Java(Difference between revisions)
Jump to: navigation, search
m
m
 
Line 32: Line 32:
 
   LinkedList() {}
 
   LinkedList() {}
  
   void push(GENTYPE o)
+
   void push(GENTYPE o) // リストの先頭に追加
 
   { ListRep r = new ListRep<GENTYPE>(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;
Line 40: Line 40:
 
   }
 
   }
  
   void append(GENTYPE o)
+
   void append(GENTYPE o) // リストの末尾に追加
 
   { ListRep r = new ListRep<GENTYPE>(o);
 
   { ListRep r = new ListRep<GENTYPE>(o);
 
     if (size > 0) tail.next = r; else head = r;
 
     if (size > 0) tail.next = r; else head = r;
Line 47: Line 47:
 
     size&#43;&#43;;
 
     size&#43;&#43;;
 
   }
 
   }
 
+
</pre>
   GENTYPE pop()
+
<pre>
 +
   GENTYPE pop() // リストの先頭から削除
 
   { ListRep x = head;
 
   { ListRep x = head;
 
     if (x != null)
 
     if (x != null)
Line 63: Line 64:
 
   }
 
   }
  
   GENTYPE peek()
+
   GENTYPE peek() // リストの先頭を参照
 
   { if (head != null)
 
   { if (head != null)
 
       return (GENTYPE)head.inf();
 
       return (GENTYPE)head.inf();

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()と書いているため、コンパイル時に「安全ではありません」という警告が出てきます。(利用には問題ありません。)

Personal tools
Namespaces

Variants
Actions
Navigation
metabolites
Toolbox