Aritalab:Lecture/Programming/Java/LinkedList

From Metabolomics.JP
< Aritalab:Lecture | Programming | Java(Difference between revisions)
Jump to: navigation, search
m
m
Line 1: Line 1:
二重リンクリスト
+
==Double-linked List==
 +
二重リンクリストは最も単純なデータ構造の一つで、スタックやキューの実装として利用できます。
 +
<center>
 +
{| class="wikitable"
 +
! 名称 || 利用するメソッド
 +
|-
 +
| スタック || push(), pop()
 +
|-
 +
| キュー || append(), pop()
 +
|}
 +
</center>
 +
ここでは、C&#43;&#43;のテンプレートに相当するJavaのジェネリック機能を用いたプログラムを紹介します。
 +
ジェネリック型がわかりにくい人は、プログラム中の<tt>GENTYPE</tt>をすべて<tt>Object</tt>に置き換え、<tt><GENTYPE></tt>を全て消去すれば<tt>Object</tt>型を用いた実装になります。
  
;File LinkedList.java
+
;ジェネリック機能を用いた二重リンクリスト LinkedList.java
 
<pre>
 
<pre>
class ListRep { // publicなclassではないのでList.java中に書ける。
+
class ListRep<GENTYPE> {
   Object obj;
+
   GENTYPE obj;
   ListRep(Object o) { obj = o; } // コンストラクタ
+
   ListRep(GENTYPE o) { obj = o; }
 
   ListRep prev;
 
   ListRep prev;
 
   ListRep next;
 
   ListRep next;
   public Object inf() { return obj; }
+
   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(Object o)
+
   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:
 
   }
 
   }
  
   Object pop()
+
   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&#43;&#43;;
 +
  }
 +
 
 +
  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"); }
+
       System.err.println("Error: empty list (function pop)");
 +
      return null;
 +
    }
 
   }
 
   }
  
   void append(Object o)
+
   GENTYPE peek()
   { ListRep r = new ListRep(o);
+
   { if (head != null)
    if (size > 0) tail.next = r; else head = r;
+
      return (GENTYPE)head.inf();
    r.prev = tail;
+
    else {
    tail = r;
+
      System.err.println("Error: empty list (function peek)");
     size&#43;&#43;;
+
      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 < 10; 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(L.pop());
+
       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()と参照した値をキャストするため「安全ではありません」という警告が出ています。

Personal tools
Namespaces

Variants
Actions
Navigation
metabolites
Toolbox