ジェネリクスとコンパレータを使用しないリストのプログラム例 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); ===========================================================================================