Microsoft Word - NonGenList.doc

Similar documents
Microsoft Word - NonGenTree.doc

明解Javaによるアルゴリズムとデータ構造

新・明解Javaで学ぶアルゴリズムとデータ構造

明解Javaによるアルゴリズムとデータ構造

3 Java 3.1 Hello World! Hello World public class HelloWorld { public static void main(string[] args) { System.out.println("Hello World");

Javaによるアルゴリズムとデータ構造

Microsoft PowerPoint ppt

Prog1_15th

新・明解Javaで学ぶアルゴリズムとデータ構造

ALG ppt

untitled

新・明解Java入門

文字列操作と正規表現

アルゴリズムとデータ構造1

ALG2012-A.ppt

解きながら学ぶJava入門編

Exam : 1z1-809-JPN Title : Java SE 8 Programmer II Vendor : Oracle Version : DEMO Get Latest & Valid 1z1-809-JPN Exam's Question and Answers 1 from Ac

8 if switch for while do while 2

人工知能入門

untitled

基礎計算機演習 実習課題No6

Microsoft PowerPoint - lec06 [互換モード]

** 平成 16 年度 FE 午後問題 Java** 示現塾プロジェクトマネージャ テクニカルエンジニア ( ネットワーク ) など各種セミナーを開催中!! 開催日 受講料 カリキュラム等 詳しくは 今すぐアクセス!! 平成 16

スライド 1

Method(C 言語では関数と呼ぶ ) メソッドを使うと 処理を纏めて管理することができる 処理 ( メソッド ) の再実行 ( 再利用 ) が簡単にできる y 元々はC 言語の関数であり 入力値に対する値を 定義するもの 数学では F(x) = 2x + 1 など F(x)=2x+1 入力値 (

Java講座

226

目的 泡立ち法を例に Comparableインターフェイスの実装 抽象クラスの利用 型パラメタの利用 比較 入替 の回数を計測

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

3,, となって欲しいのだが 実際の出力結果を確認すると両方の配列とも 10, 2, 3,, となってしまっている この結果は代入後の配列 a と b は同じものになっていることを示している つまり 代入演算子 = によるの代入は全要素のコピーではなく 先をコピーする ため 代入後の a と b は

情報処理Ⅰ

ALG2012-C.ppt

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

デジタル表現論・第4回

アルゴリズムとデータ構造1

(Microsoft PowerPoint - \223\306\217KJAVA\221\346\202R\224\ ppt)

K227 Java 2

Java プログラミング Ⅰ 7 回目 switch 文と論理演算子 条件判断文 3 switch 文 switch 文式が case の値と一致した場合 そこから直後の break; までを処理し どれにも一致しない場合 default; から直後の break; までを処理する 但し 式や値 1

Microsoft PowerPoint - Pro110111

Java演習(4) -- 変数と型 --

DVIOUT-exer

問題1 以下に示すプログラムは、次の処理をするプログラムである

10/ / /30 3. ( ) 11/ 6 4. UNIX + C socket 11/13 5. ( ) C 11/20 6. http, CGI Perl 11/27 7. ( ) Perl 12/ 4 8. Windows Winsock 12/11 9. JAV

ALG ppt

Java プログラミング Ⅰ 7 回目 switch 文と論理演算子 今日の講義講義で学ぶ内容 switch 文 論理演算子 条件演算子 条件判断文 3 switch 文 switch 文 式が case のラベルと一致する場所から直後の break; まで処理しますどれにも一致致しない場合 def

<4D F736F F D2091E F196E291E889F090E C4816A82CC838C E646F6378>

やさしいJavaプログラミング -Great Ideas for Java Programming サンプルPDF

class IntCell { private int value ; int getvalue() {return value; private IntCell next; IntCell next() {return next; IntCell(int value) {this.value =

アルゴリズムとデータ構造1

2

Taro-リストⅠ(公開版).jtd

Java プログラミング Ⅰ 3 回目変 数 今日の講義講義で学ぶ内容 変数とは 変数の使い方 キーボード入力の仕方 変 数 変 数 一時的に値を記憶させておく機能 変数は 型 ( データ型 ) と識別子をもちます 2 型 ( データ型 ) 変数に記憶する値の種類変数の型は 記憶できる値の種類と範囲

Prog2_9th

Java (9) 1 Lesson Java System.out.println() 1 Java API 1 Java Java 1

Taro-リストⅢ(公開版).jtd

JavaプログラミングⅠ

JAVA とテンプレート

Prog1_6th

問 次の Fortran プログラムの説明及びプログラムを読んで、設問に答えよ。

Java 基礎問題ドリル ~ メソッドを理解する ~ 次のプログラムコードに 各設問の条件にあうメソッドを追加しなさい その後 そのメソッドが正しく動作することを検証するためのプログラムコードを main メソッドの中に追加しなさい public class Practice { // ここに各設問

1. はじめに 二分木ヒープ 様々なアルゴリズムにおいて ある要素の集合またはリストから 最小 な要素を取り 出す必要がある そのような場合に使われる標準的データ構造が二分木ヒープ (binary heap) である あるオブジェクトO を考える そのオブジェクトは ラベル O. label と値

オブジェクト指向プログラミング・同演習 5月21日演習課題

デジタル表現論・第6回

memo

2. データ構造ヒープに保存するデータは 番号付けられて保存される 従って リスト L として保存することとする 3. アルゴリズム 3.1. 要素の追加新しい要素の追加は リストの終端に置くことで開始する つまり 最下層の一番右 または新たに最下層を生成してその一番左となる この後 この要素を正し

Assignment_.java 課題 : 転置行列 / class Assignment_ public static void main(string[] args) int i,j; int[][] array = 1,,,,,,,,,,,,,1,1,; 行 列行列 i

プログラミング入門1

Java プログラミング Ⅰ 3 回目変数 変数 変 数 一時的に値を記憶させておく機能型 ( データ型 ) と識別子をもつ 2 型 ( データ型 ) 変数の種類型に応じて記憶できる値の種類や範囲が決まる 型 値の種類 値の範囲 boolean 真偽値 true / false char 2バイト文

Javaセキュアコーディングセミナー2013東京第1回 演習の解説

Quick Sort 計算機アルゴリズム特論 :2017 年度 只木進一

Javaセキュアコーディングセミナー東京 第2回 数値データの取扱いと入力値の検証 演習解説

JavaプログラミングⅠ

Javaプログラムの実行手順

Microsoft Word - keisankigairon.ch doc

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

PowerPoint Template

ただし 無作為にスレッドを複数実行すると 結果不正やデッドロックが起きる可能性がある 複数のスレッド ( マルチスレッド ) を安全に実行する ( スレッドセーフにする ) ためには 同期処理を用いるこ とが必要になる 同期処理は 予約語 synchronized で行うことができる ここでは sy

プログラミングI第10回

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

グラフと組み合わせ 課題 7 ( 解答例 ) 2013/5/27 1 列挙 n 個の文字の集合 { } S = a, a,, an の全てからなる文字列 つまり同じ文字を含まない 長さ n の文字列を列挙する 方法を考える 1. 何通りの文字列があるかを答えなさい また そのことが正しい

Javaセキュアコーディングセミナー東京 第3回 入出力(File, Stream)と例外時の動作 演習解説

2

問題1 以下に示すプログラムは、次の処理をするプログラムである

class IntCell { private int value ; int getvalue() {return value; private IntCell next; IntCell next() {return next; IntCell(int value) {this.value =

解答上の注意 1 解答は 解答 紙の問題番号に対応した解答欄にマークしなさい 2 選択肢は 問ごとに 意されています 問 1の選択肢は 問 2で使 しません 3 選択肢は量が多いため 探しやすさの観点よりグループ分けされています グループ分けに合わせて解答欄が区切られていますが 横 1 列で問題 1

Prog1_3rd

Prog1_10th

問題 01 以下は コンソールより年齢を入力させ その年齢にあった料金を表示するプログラムである 年齢ごとの金額は以下の通りである 年齢の範囲金額 0 歳以上 6 歳以下 120 円 7 歳以上 65 歳未満 200 円 65 歳以上無料 package j1.exam02; import java

I java A

できるプログラマーを本気で育てる Java 超 Webプログラマーへの第 歩 第 3 回コレクションと例外処理 テクノロジックアート 瀬嘉秀

Microsoft PowerPoint - prog03.ppt

JavaプログラミングⅠ

JavaプログラミングⅠ

JAVA入門

目 次 オブジェクト指向 1 3 オブジェクト指向 2 9 二分探索 14 二次元配列 16 ソート 18 ArrayList 25 解答 27 2

Microsoft PowerPoint - ●SWIM_ _INET掲載用.pptx

Microsoft Word - java a.doc

二分木ヒープとは 集合 リストから 最小な 要素を取り出す 二分木ヒープは そのための標準的データ構造 二分木ヒープを保存するデータ構造 二分木ヒープの操作のメソッド 対象となるデータクラス 識別のためのlabelフィールド 値を保持するvalueフィールド

プログラミングA

PowerPoint プレゼンテーション

Transcription:

ジェネリクスとコンパレータを使用しないリストのプログラム例 1. ポインタによる線形リスト LinkedListNG.java: ポインタによる線形リストのクラス LinkedListNG LinkedListTesterNG.java: LinkedListNG を利用するプログラム例 2. カーソルによる線形リスト AryLinkedListNG.java: カーソルによる線形リストのクラス AryLinkedListNG AryLinkedListTesterNG.java: AryLinkedListNG を利用するプログラム例 3. 循環 重連結リスト DblLinkedListNG.java: 循環 重連結リストのクラス DblLinkedListNG DblLinkedListTesterNG.java: DblLinkedListNG を利用するプログラム例

=== LinkedListNG.java ===================================================================== // ジェネリクスを使用しない線形リストクラスの例 // List.9-1 (pp.283-294) をジェネリクスおよびコンパレータを使用しない形に修正 // 主な修正点 // (1) LinkedList<E> -> LinkedListNG // (2) Node の data を Data クラスに固定 // class Data を簡略化して定義 (scandata, コンパレータを削除 ) // Node<E> -> Node // E -> Data // (3) メソッド search をキー毎に分離しコンパレータ不使用に // search() -> searchno(), searchname() public class LinkedListNG { //--- データ ( 会員番号 + 氏名 ) ---// public static class Data { private Integer no; // 会員番号 private String name; // 氏名 Data(Integer no, String name) { // コンストラクタ this.no = no; this.name = name; //--- 文字列表現を返す ---// public String tostring() { return "(" + no + ") " + name; //--- ノード ---// public class Node { private Data data; // データ private Node next; // 後続ポインタ ( 後続ノードへの参照 ) //--- コンストラクタ ---// Node(Data data, Node next) { this.data = data; this.next = next; private Node head; private Node crnt; // 先頭ノード // 着目ノード //--- コンストラクタ ---// LinkedListNG() { head = crnt = null; //--- ノードを番号で探索 ---// public Data searchno(integer key) {

Node ptr = head; // 現在走査中のノード while (ptr!= null) { if (ptr.data.no == key) { crnt = ptr; return ptr.data; ptr = ptr.next; return null; // 探索成功 // 後続ノードに着目 // 探索失敗 //--- ノードを名前で探索 ---// public Data searchname(string key) { Node ptr = head; // 現在走査中のノード while(ptr!= null) { if(ptr.data.name.compareto(key) == 0) {// 探索成功 crnt = ptr; return ptr.data; ptr = ptr.next; // 後続ノードに着目 return null; // 探索失敗 //--- 先頭にノードを挿入 ---// public void addfirst(data obj) { Node ptr = head; // 挿入前の先頭ノード head = crnt = new Node(obj, ptr); //--- 末尾にノードを挿入 ---// public void addlast(data obj) { if (head == null) // リストが空であれば addfirst(obj); // 先頭に挿入 else { Node ptr = head; while (ptr.next!= null) ptr = ptr.next; ptr.next = crnt = new Node(obj, null); //--- 先頭ノードを削除 ---// public void removefirst() { if (head!= null) head = crnt = head.next; // リストが空でなければ //--- 末尾ノードを削除 ---// public void removelast() { if (head!= null) {

if (head.next == null) // ノードが一つだけであれば removefirst(); // 先頭ノードを削除 else { Node ptr = head; // 走査中のノード Node pre = head; // 走査中のノードの先行ノード while (ptr.next!= null) { pre = ptr; ptr = ptr.next; pre.next = null; // pre は削除後の末尾ノード crnt = pre; //--- ノード p を削除 ---// public void remove(node p) { if (head!= null) { if (p == head) // p が先頭ノードであれば removefirst(); // 先頭ノードを削除 else { Node ptr = head; while (ptr.next!= p) { ptr = ptr.next; if (ptr == null) return; // p はリスト上に存在しない ptr.next = p.next; crnt = ptr; //--- 着目ノードを削除 ---// public void removecurrentnode() { remove(crnt); //--- 全ノードを削除 ---// public void clear() { while (head!= null) // 空になるまで removefirst(); // 先頭ノードを削除 crnt = null; //--- 着目ノードを一つ後方に進める ---// public boolean next() { if (crnt == null crnt.next == null) return false; // 進めることはできなかった crnt = crnt.next; return true;

//--- 着目ノードを表示 ---// public void printcurrentnode() { if (crnt == null) System.out.println(" 着目ノードはありません "); else System.out.println(crnt.data); //--- 全ノードを表示 ---// public void dump() { Node ptr = head; while (ptr!= null) { System.out.println(ptr.data); ptr = ptr.next; ===========================================================================================

=== LinkedListTesterNG.java ================================================================ // ジェネリクスを使用しない線形リストクラス LinkedListNG の利用例 // LinkedListTester.java (pp.295-297 List9-2) からの変更点 // Data クラスの定義を LinkedListNG に移動 // Data -> LinkedListNG.Data // 挿入 を scandata() を用いないように修正 // 探索 をコンパレータ不使用の形に修正 // メニューにリストの初期化を追加 import java.util.scanner; public class LinkedListTesterNG { static Scanner stdin = new Scanner(System.in); //--- メニュー列挙型 ---// enum Menu { ADD_FIRST( " 先頭にノードを挿入 "), ADD_LAST( " 末尾にノードを挿入 "), RMV_FIRST( " 先頭ノードを削除 "), RMV_LAST( " 末尾ノードを削除 "), RMV_CRNT( " 着目ノードを削除 "), CLEAR( " 全ノードを削除 "), SEARCH_NO( " 番号で探索 "), SEARCH_NAME(" 氏名で探索 "), NEXT( " 着目ノードを進める "), PRINT_CRNT( " 着目ノードを表示 "), DUMP( " 全ノードを表示 "), // *** ここに追加項目を挿入 INIT_LIST( " 初期化 "), // *** ここまで追加項目 TERMINATE( " 終了 "); private final String message; static Menu MenuAt(int idx) { for (Menu m : Menu.values()) if (m.ordinal() == idx) return m; return null; // 初期リストを作成 // 表示用文字列 // 序数が idx である列挙を返す Menu(String string) { message = string; String getmessage() { return message; // コンストラクタ // 表示用文字列を返す //--- メニュー選択 ---// static Menu SelectMenu() { int key;

do { for (Menu m : Menu.values()) { System.out.printf("(%d) %s ", m.ordinal(), m.getmessage()); if ((m.ordinal() % 3) == 2 && m.ordinal()!= Menu.TERMINATE.ordinal()) System.out.println(); System.out.print(":"); key = stdin.nextint(); while (key < Menu.ADD_FIRST.ordinal() key > Menu.TERMINATE.ordinal()); return Menu.MenuAt(key); public static void main(string[] args) { Menu menu; // メニュー LinkedListNG.Data data; // 追加用データ参照 LinkedListNG.Data ptr; // 探索用データ参照 Integer no; // 番号 ( 追加 検索用 ) String name; // 名前 ( 追加 検索用 ) LinkedListNG list = new LinkedListNG(); // リストを生成 do { switch (menu = SelectMenu()) { case ADD_FIRST : // 先頭にノードを挿入 System.out.println(" 先頭に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new LinkedListNG.Data(no, name); list.addfirst(data); case ADD_LAST : // 末尾にノードを挿入 System.out.println(" 末尾に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new LinkedListNG.Data(no, name); list.addlast(data); case RMV_FIRST : list.removefirst(); case RMV_LAST : list.removelast(); case RMV_CRNT : list.removecurrentnode(); // 先頭ノードを削除 // 末尾ノードを削除 // 着目ノードを削除

case SEARCH_NO : // 会員番号で探索 System.out.println(" 探索するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); ptr = list.searchno(no); if (ptr == null) System.out.println(" その番号のデータはありません "); else System.out.println(" 探索成功 :" + ptr); case SEARCH_NAME : // 氏名で探索 System.out.println(" 探索するデータを入力して下さい."); System.out.print(" 名前 :"); name = stdin.next(); ptr = list.searchname(name); if (ptr == null) System.out.println(" その名前のデータはありません "); else System.out.println(" 探索成功 :" + ptr); case NEXT : list.next(); // 着目ノードを後方に進める case PRINT_CRNT : // 着目ノードのデータを表示 list.printcurrentnode(); case DUMP : list.dump(); case CLEAR : list.clear(); // 全ノードをリスト順に表示 // 全ノードを削除 case INIT_LIST: // リストを初期化 list.clear(); data = new LinkedListNG.Data(1, " 武田信玄 "); list.addlast(data); data = new LinkedListNG.Data(2, " 上杉謙信 "); list.addlast(data); data = new LinkedListNG.Data(3, " 織田信長 "); list.addlast(data); data = new LinkedListNG.Data(4, " 豊臣秀吉 "); list.addlast(data); data = new LinkedListNG.Data(5, " 徳川家康 "); list.addlast(data); while (menu!= Menu.TERMINATE); ===========================================================================================

=== AryLinkedListNG.java =================================================================== // ジェネリクスを使用しない線形リストクラス ( 配列カーソル版 ) の例 // List.9-3 (pp.301-304) をジェネリクスおよびコンパレータを使用しない形に修正 // 主な修正点 // (1) AryLinkedList<E> -> AryLinkedListNG // (2) Node の data を Data クラスに固定 // class Data を簡略化して定義 (scandata, コンパレータを削除 ) // Node<E> -> Node // E -> Data // (3) メソッド search をキー毎に分離しコンパレータ不使用に // search() -> searchno(), searchname() // (4) deleteindex(), removefirst() の BUG FIX // public class AryLinkedListNG { //--- データ ( 会員番号 + 氏名 ) ---// public static class Data { private Integer no; // 会員番号 private String name; // 氏名 Data(Integer no, String name) { // コンストラクタ this.no = no; this.name = name; //--- 文字列表現を返す ---// public String tostring() { return "(" + no + ") " + name; //--- ノード ---// class Node { private Data data; // データ private int next; // リストの後続ポインタ private int dnext; // フリーリストの後続ポインタ //--- data と next を設定 ---// void set(data data, int next) { this.data = data; this.next = next; private Node[] n; // リスト本体 private int size; // リストの容量 ( 最大データ数 ) private int max; // 利用中の末尾レコード private int head; // 先頭ノード private int crnt; // 着目ノード private int deleted; // フリーリストの先頭ノード private static final int NULL = -1; // 後続ノードはない / リストは満杯

//--- コンストラクタ ---// public AryLinkedListNG(int capacity) { head = crnt = max = deleted = NULL; try { n = new Node[capacity]; for (int i = 0; i < capacity; i++) n[i] = new Node(); size = capacity; catch (OutOfMemoryError e) { // 配列の生成に失敗 size = 0; //--- 次に挿入するレコードのインデックスを求める ---// private int getinsertindex() { if (deleted == NULL) { // 削除レコードは存在しない if (max < size) return ++max; // 新しいレコードを利用 else return NULL; // 容量オーバ else { int rec = deleted; // フリーリストから deleted = n[rec].dnext; // 先頭 rec を取り出す return rec; //--- レコード idx をフリーリストに登録 ---// private void deleteindex(int idx) { if (deleted == NULL) { // 削除レコードは存在しない deleted = idx; // idx をフリーリストの n[idx].dnext = NULL; // 先頭に登録 else { int rec = deleted; // idx をフリーリストの deleted = idx; // 先頭に挿入 n[idx].dnext = rec; // BUG FIX //--- ノードを番号で探索 ---// public Data searchno(integer key) { int ptr = head; // 現在走査中のノード while (ptr!= NULL) { if (n[ptr].data.no == key) { crnt = ptr; return n[ptr].data; ptr = n[ptr].next; return null; // 探索成功 // 後続ノードに着目 // 探索失敗

//--- ノードを名前で探索 ---// public Data searchname(string key) { int ptr = head; // 現在走査中のノード while(ptr!= NULL) { if(n[ptr].data.name.compareto(key) == 0) {// 探索成功 crnt = ptr; return n[ptr].data; ptr = n[ptr].next; // 後続ノードに着目 return null; // 探索失敗 //--- 先頭にノードを挿入 ---// public void addfirst(data obj) { int ptr = head; // 挿入前の先頭ノード int rec = getinsertindex(); if (rec!= NULL) { head = crnt = rec; // 第 rec レコードに挿入 n[head].set(obj, ptr); //--- 末尾にノードを挿入 ---// public void addlast(data obj) { if (head == NULL) addfirst(obj); else { int ptr = head; while (n[ptr].next!= NULL) ptr = n[ptr].next; int rec = getinsertindex(); if (rec!= NULL) { n[ptr].next = crnt = rec; n[rec].set(obj, NULL); //--- 先頭ノードを削除 ---// public void removefirst() { if (head!= NULL) { int ptr = n[head].next; deleteindex(head); head = crnt = ptr; // リストが空であれば // 先頭に挿入 // 第 rec レコードに挿入 // リストが空でなければ // BUG FIX //--- 末尾ノードを削除 ---// public void removelast() { if (head!= NULL) {

if (n[head].next == NULL) // ノードが一つだけであれば removefirst(); // 先頭ノードを削除 else { int ptr = head; // 走査中のノード int pre = head; // 走査中のノードの先行ノード while (n[ptr].next!= NULL) { pre = ptr; ptr = n[ptr].next; n[pre].next = NULL; // pre は削除後の末尾ノード deleteindex(ptr); // BUG FIX crnt = pre; //--- レコード p を削除 ---// public void remove(int p) { if (head!= NULL) { if (p == head) removefirst(); else { int ptr = head; // p が先頭ノードであれば // 先頭ノードを削除 while (n[ptr].next!= p) { ptr = n[ptr].next; if (ptr == NULL) return; // p はリスト上に存在しない n[ptr].next = n[p].next; // BUG FIX deleteindex(p); // BUG FIX // n[ptr].next = n[p].next; // BUG FIX crnt = ptr; //--- 着目ノードを削除 ---// public void removecurrentnode() { remove(crnt); //--- 全ノードを削除 ---// public void clear() { while (head!= NULL) // 空になるまで removefirst(); // 先頭ノードを削除 crnt = NULL; //--- 着目ノードを一つ後方に進める ---// public boolean next() { if (crnt == NULL n[crnt].next == NULL)

return false; // 進めることはできなかった crnt = n[crnt].next; return true; //--- 着目ノードを表示 ---// public void printcurrentnode() { if (crnt == NULL) System.out.println(" 着目ノードはありません "); else System.out.println(n[crnt].data); //--- 全ノードを表示 ---// public void dump() { int ptr = head; while (ptr!= NULL) { System.out.println(n[ptr].data); ptr = n[ptr].next; ===========================================================================================

=== AryLinkedListTesterNG.java ============================================================= // ジェネリクスを使用しない線形リストクラス AryLinkedListNG の利用例 // LinkedListTesterNG.java からの変更点 // LinkedListTesterNG を AryLinkedListTesterNG に変更 // LinkedListNG を AryLinkedListNG に変更 import java.util.scanner; public class AryLinkedListTesterNG { static Scanner stdin = new Scanner(System.in); //--- メニュー列挙型 ---// enum Menu { ADD_FIRST( " 先頭にノードを挿入 "), ADD_LAST( " 末尾にノードを挿入 "), RMV_FIRST( " 先頭ノードを削除 "), RMV_LAST( " 末尾ノードを削除 "), RMV_CRNT( " 着目ノードを削除 "), CLEAR( " 全ノードを削除 "), SEARCH_NO( " 番号で探索 "), SEARCH_NAME(" 氏名で探索 "), NEXT( " 着目ノードを進める "), PRINT_CRNT( " 着目ノードを表示 "), DUMP( " 全ノードを表示 "), // *** ここに追加項目を挿入 INIT_LIST( " 初期化 "), // *** ここまで追加項目 TERMINATE( " 終了 "); private final String message; static Menu MenuAt(int idx) { for (Menu m : Menu.values()) if (m.ordinal() == idx) return m; return null; // 初期リストを作成 // 表示用文字列 // 序数が idx である列挙を返す Menu(String string) { message = string; String getmessage() { return message; // コンストラクタ // 表示用文字列を返す //--- メニュー選択 ---// static Menu SelectMenu() { int key; do { for (Menu m : Menu.values()) { System.out.printf("(%d) %s ", m.ordinal(), m.getmessage());

if ((m.ordinal() % 3) == 2 && m.ordinal()!= Menu.TERMINATE.ordinal()) System.out.println(); System.out.print(":"); key = stdin.nextint(); while (key < Menu.ADD_FIRST.ordinal() key > Menu.TERMINATE.ordinal()); return Menu.MenuAt(key); public static void main(string[] args) { Menu menu; // メニュー AryLinkedListNG.Data data; // 追加用データ参照 AryLinkedListNG.Data ptr; // 探索用データ参照 Integer no; // 番号 ( 追加 検索用 ) String name; // 名前 ( 追加 検索用 ) AryLinkedListNG list = new AryLinkedListNG(100); // リストを生成 do { switch (menu = SelectMenu()) { case ADD_FIRST : // 先頭にノードを挿入 System.out.println(" 先頭に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new AryLinkedListNG.Data(no, name); list.addfirst(data); case ADD_LAST : // 末尾にノードを挿入 System.out.println(" 末尾に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new AryLinkedListNG.Data(no, name); list.addlast(data); case RMV_FIRST : list.removefirst(); case RMV_LAST : list.removelast(); case RMV_CRNT : list.removecurrentnode(); // 先頭ノードを削除 // 末尾ノードを削除 // 着目ノードを削除 case SEARCH_NO : // 会員番号で探索 System.out.println(" 探索するデータを入力して下さい.");

System.out.print(" 番号 :"); no = stdin.nextint(); ptr = list.searchno(no); if (ptr == null) System.out.println(" その番号のデータはありません "); else System.out.println(" 探索成功 :" + ptr); case SEARCH_NAME : // 氏名で探索 System.out.println(" 探索するデータを入力して下さい."); System.out.print(" 名前 :"); name = stdin.next(); ptr = list.searchname(name); if (ptr == null) System.out.println(" その名前のデータはありません "); else System.out.println(" 探索成功 :" + ptr); case NEXT : list.next(); // 着目ノードを後方に進める case PRINT_CRNT : // 着目ノードのデータを表示 list.printcurrentnode(); case DUMP : list.dump(); case CLEAR : list.clear(); // 全ノードをリスト順に表示 // 全ノードを削除 case INIT_LIST: // リストを初期化 list.clear(); data = new AryLinkedListNG.Data(1, " 武田信玄 "); list.addlast(data); data = new AryLinkedListNG.Data(2, " 上杉謙信 "); list.addlast(data); data = new AryLinkedListNG.Data(3, " 織田信長 "); list.addlast(data); data = new AryLinkedListNG.Data(4, " 豊臣秀吉 "); list.addlast(data); data = new AryLinkedListNG.Data(5, " 徳川家康 "); list.addlast(data); while (menu!= Menu.TERMINATE); ===========================================================================================

=== DblLinkedListNG.java =================================================================== // ジェネリクスを用いない循環 重連結リストクラスの例 // List.9-5 (pp.312-321) をジェネリクスおよびコンパレータを使用しない形に修正 // 主な修正点 // (1) DblLinkedList<E> -> DblLinkedListNG // (2) Node の data を Data クラスに固定 // class Data を簡略化して定義 (scandata, コンパレータを削除 ) // Node<E> -> Node // E -> Data // (3) メソッド search をキー毎に分離しコンパレータ不使用に // search() -> searchno(), searchname() // (4) remove() のバグを FIX // import java.util.comparator; public class DblLinkedListNG { //--- データ ( 会員番号 + 氏名 ) ---// public static class Data { private Integer no; // 会員番号 private String name; // 氏名 Data(Integer no, String name) { // コンストラクタ this.no = no; this.name = name; //--- 文字列表現を返す ---// public String tostring() { return "(" + no + ") " + name; //--- ノード ---// class Node { private Data data; // データ private Node prev; // 先行ポインタ ( 先行ノードへの参照 ) private Node next; // 後続ポインタ ( 後続ノードへの参照 ) //--- コンストラクタ ---// Node() { data = null; prev = next = this; //--- コンストラクタ ---// Node(Data obj, Node prev, Node next) { data = obj; this.prev = prev; this.next = next;

private Node head; // 先頭ノード ( ダミーノード ) private Node crnt; // 着目ノード //--- コンストラクタ ---// public DblLinkedListNG() { head = crnt = new Node(); // ダミーノードを生成 //--- リストは空か ---// public boolean isempty() { return head.next == head; //--- ノードを番号で探索 ---// public Data searchno(integer key) { Node ptr = head.next; // 現在走査中のノード while (ptr!= head) { if (ptr.data.no == key) { crnt = ptr; return ptr.data; ptr = ptr.next; return null; // 探索成功 // 後続ノードに着目 // 探索失敗 //--- ノードを名前で探索 ---// public Data searchname(string key) { Node ptr = head.next; // 現在走査中のノード while(ptr!= head) { if(ptr.data.name.compareto(key) == 0) {// 探索成功 crnt = ptr; return ptr.data; ptr = ptr.next; // 後続ノードに着目 return null; // 探索失敗 //--- 着目ノードを表示 ---// public void printcurrentnode() { if (isempty()) System.out.println(" 着目ノードはありません "); else System.out.println(crnt.data); //--- 全ノードを表示 ---// public void dump() {

Node ptr = head.next; // ダミーノードの後続ノード while (ptr!= head) { System.out.println(ptr.data); ptr = ptr.next; //--- 全ノードを逆順に表示 ---// public void dumpreverse() { Node ptr = head.prev; // ダミーノードの先行ノード while (ptr!= head) { System.out.println(ptr.data); ptr = ptr.prev; //--- 着目ノードを一つ後方に進める ---// public boolean next() { if (isempty() crnt.next == head) return false; // 進めることはできなかった crnt = crnt.next; return true; //--- 着目ノードを一つ前方に進める ---// public boolean prev() { if (isempty() crnt.prev == head) return false; // 進めることはできなかった crnt = crnt.prev; return true; //--- 着目ノードの直後にノードを挿入 ---// public void add(data obj) { Node node = new Node(obj, crnt, crnt.next); crnt.next = crnt.next.prev = node; crnt = node; //--- 先頭にノードを挿入 ---// public void addfirst(data obj) { crnt = head; // ダミーノード head の直後に挿入 add(obj); //--- 末尾にノードを挿入 ---// public void addlast(data obj) { crnt = head.prev; // 末尾ノード head.prev の直後に挿入 add(obj);

//--- 着目ノードを削除 ---// public void removecurrentnode() { if (!isempty()) { crnt.prev.next = crnt.next; crnt.next.prev = crnt.prev; crnt = crnt.prev; //--- ノード p を削除 ---// public void remove(node p) { Node ptr = head.next; while (ptr!= head) { if (ptr == p) { // p を見つけた crnt = p; removecurrentnode(); ptr = ptr.next; // BUG FIX //--- 先頭ノードを削除 ---// public void removefirst() { crnt = head.next; // 先頭ノード head.next を削除 removecurrentnode(); //--- 末尾ノードを削除 ---// public void removelast() { crnt = head.prev; // 末尾ノード head.prev を削除 removecurrentnode(); //--- 全ノードを削除 ---// public void clear() { while (!isempty()) // 空になるまで removefirst(); // 先頭ノードを削除 ===========================================================================================

=== DblLinkedListTesterNG.java ============================================================= // ジェネリクスを使用しない循環 重連結リストクラス DblLinkedListNG の利用例 // LinkedListTesterNG.java からの変更点 // LnkedListTesterNG を DblLinkedListTesterNG に変更 // LnkedListNG を DblLinkedListNG に変更 // メニューおよび処理に ADD, PREV を追加 import java.util.scanner; public class DblLinkedListTesterNG { static Scanner stdin = new Scanner(System.in); //--- メニュー列挙型 ---// enum Menu { ADD_FIRST( " 先頭にノードを挿入 "), ADD_LAST( " 末尾にノードを挿入 "), RMV_FIRST( " 先頭ノードを削除 "), RMV_LAST( " 末尾ノードを削除 "), ADD( " 着目ノードの直後に挿入 "), RMV_CRNT( " 着目ノードを削除 "), CLEAR( " 全ノードを削除 "), SEARCH_NO( " 番号で探索 "), SEARCH_NAME(" 氏名で探索 "), NEXT( " 着目ノードを後方へ "), PREV( " 着目ノードを前方へ "), PRINT_CRNT( " 着目ノードを表示 "), DUMP( " 全ノードを表示 "), // *** ここに追加項目を挿入 INIT_LIST( " 初期化 "), // 初期リストを作成 // *** ここまで追加項目 TERMINATE( " 終了 "); private final String message; static Menu MenuAt(int idx) { for (Menu m : Menu.values()) if (m.ordinal() == idx) return m; return null; Menu(String string) { message = string; String getmessage() { return message; // 表示用文字列 // 序数が idx である列挙を返す // コンストラクタ // 表示用文字列を返す //--- メニュー選択 ---// static Menu SelectMenu() { int key;

do { for (Menu m : Menu.values()) { System.out.printf("(%d) %s ", m.ordinal(), m.getmessage()); if ((m.ordinal() % 3) == 2 && m.ordinal()!= Menu.TERMINATE.ordinal()) System.out.println(); System.out.print(":"); key = stdin.nextint(); while (key < Menu.ADD_FIRST.ordinal() key > Menu.TERMINATE.ordinal()); return Menu.MenuAt(key); public static void main(string[] args) { Menu menu; // メニュー DblLinkedListNG.Data data; // 追加用データ参照 DblLinkedListNG.Data ptr; // 探索用データ参照 Integer no; // 番号 ( 追加 検索用 ) String name; // 名前 ( 追加 検索用 ) DblLinkedListNG list = new DblLinkedListNG(); // リストを生成 do { switch (menu = SelectMenu()) { case ADD_FIRST : // 先頭にノードを挿入 System.out.println(" 先頭に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new DblLinkedListNG.Data(no, name); list.addfirst(data); case ADD_LAST : // 末尾にノードを挿入 System.out.println(" 末尾に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new DblLinkedListNG.Data(no, name); list.addlast(data); case ADD : // 着目ノードの直後にノードを挿入 System.out.println(" 着目ノードの直後に挿入するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); System.out.print(" 名前 :"); name = stdin.next(); data = new DblLinkedListNG.Data(no, name); list.add(data); case RMV_FIRST : list.removefirst(); // 先頭ノードを削除

case RMV_LAST : list.removelast(); case RMV_CRNT : list.removecurrentnode(); // 末尾ノードを削除 // 着目ノードを削除 case SEARCH_NO : // 会員番号で探索 System.out.println(" 探索するデータを入力して下さい."); System.out.print(" 番号 :"); no = stdin.nextint(); ptr = list.searchno(no); if (ptr == null) System.out.println(" その番号のデータはありません "); else System.out.println(" 探索成功 :" + ptr); case SEARCH_NAME : // 氏名で探索 System.out.println(" 探索するデータを入力して下さい."); System.out.print(" 名前 :"); name = stdin.next(); ptr = list.searchname(name); if (ptr == null) System.out.println(" その名前のデータはありません "); else System.out.println(" 探索成功 :" + ptr); case NEXT : list.next(); case PREV : list.prev(); // 着目ノードを後方に進める // 着目ノードを前方に進める case PRINT_CRNT : // 着目ノードのデータを表示 list.printcurrentnode(); case DUMP : list.dump(); case CLEAR : list.clear(); case INIT_LIST: list.clear(); // 全ノードをリスト順に表示 // 全ノードを削除 // リストを初期化

data = new DblLinkedListNG.Data(1, " 武田信玄 "); list.addlast(data); data = new DblLinkedListNG.Data(2, " 上杉謙信 "); list.addlast(data); data = new DblLinkedListNG.Data(3, " 織田信長 "); list.addlast(data); data = new DblLinkedListNG.Data(4, " 豊臣秀吉 "); list.addlast(data); data = new DblLinkedListNG.Data(5, " 徳川家康 "); list.addlast(data); while (menu!= Menu.TERMINATE); ===========================================================================================