• 検索結果がありません。

Microsoft Word - NonGenList.doc

N/A
N/A
Protected

Academic year: 2021

シェア "Microsoft Word - NonGenList.doc"

Copied!
24
0
0

読み込み中.... (全文を見る)

全文

(1)

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

(2)

=== 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) {

(3)

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) {

(4)

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; }

(5)

//--- 着目ノードを表示 ---// 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; } } } ===========================================================================================

(6)

=== 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) { // 序数が idx である列挙を返す for (Menu m : Menu.values())

if (m.ordinal() == idx) return m; return null; } Menu(String string) { // コンストラクタ message = string; } String getMessage() { // 表示用文字列を返す return message; } } //--- メニュー選択 ---// static Menu SelectMenu() { int key;

(7)

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); break;

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); break; case RMV_FIRST : // 先頭ノードを削除 list.removeFirst(); break; case RMV_LAST : // 末尾ノードを削除 list.removeLast(); break; case RMV_CRNT : // 着目ノードを削除 list.removeCurrentNode(); break;

(8)

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); break; 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); break; case NEXT : // 着目ノードを後方に進める list.next(); break; case PRINT_CRNT : // 着目ノードのデータを表示 list.printCurrentNode(); break; case DUMP : // 全ノードをリスト順に表示 list.dump(); break; case CLEAR : // 全ノードを削除 list.clear(); break; 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); break;

}

} while (menu != Menu.TERMINATE); }

}

(9)

=== 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; // フリーリストの先頭ノード

(10)

//--- コンストラクタ ---//

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; // 探索失敗 }

(11)

//--- ノードを名前で探索 ---// 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) { // 第 rec レコードに挿入 n[ptr].next = crnt = rec; n[rec].set(obj, NULL); } } } //--- 先頭ノードを削除 ---// public void removeFirst() {

if (head != NULL) { // リストが空でなければ int ptr = n[head].next;

deleteIndex(head); // BUG FIX head = crnt = ptr;

} }

//--- 末尾ノードを削除 ---// public void removeLast() { if (head != NULL) {

(12)

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) // p が先頭ノードであれば removeFirst(); // 先頭ノードを削除 else { int ptr = head; 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() {

(13)

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; } } } ===========================================================================================

(14)

=== 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) { // 序数が idx である列挙を返す for (Menu m : Menu.values())

if (m.ordinal() == idx) return m; return null; } Menu(String string) { // コンストラクタ message = string; } String getMessage() { // 表示用文字列を返す return message; } } //--- メニュー選択 ---// static Menu SelectMenu() { int key;

do {

for (Menu m : Menu.values()) {

(15)

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); break;

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); break; case RMV_FIRST : // 先頭ノードを削除 list.removeFirst(); break; case RMV_LAST : // 末尾ノードを削除 list.removeLast(); break; case RMV_CRNT : // 着目ノードを削除 list.removeCurrentNode(); break; case SEARCH_NO : // 会員番号で探索 System.out.println("探索するデータを入力して下さい.");

(16)

System.out.print("番号:"); no = stdIn.nextInt(); ptr = list.searchNo(no); if (ptr == null) System.out.println("その番号のデータはありません。"); else System.out.println("探索成功:" + ptr); break; 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); break; case NEXT : // 着目ノードを後方に進める list.next(); break; case PRINT_CRNT : // 着目ノードのデータを表示 list.printCurrentNode(); break; case DUMP : // 全ノードをリスト順に表示 list.dump(); break; case CLEAR : // 全ノードを削除 list.clear(); break; 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); break;

}

} while (menu != Menu.TERMINATE); }

}

(17)

=== 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; }

(18)

}

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() {

(19)

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);

(20)

//--- 着目ノードを削除 ---// 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(); break; }

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(); // 先頭ノードを削除 }

}

(21)

=== 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) { // 序数が idx である列挙を返す for (Menu m : Menu.values())

if (m.ordinal() == idx) return m; return null; } Menu(String string) { // コンストラクタ message = string; } String getMessage() { // 表示用文字列を返す return message; } } //--- メニュー選択 ---// static Menu SelectMenu() { int key;

(22)

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); break;

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); break;

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); break;

case RMV_FIRST : // 先頭ノードを削除 list.removeFirst();

(23)

case RMV_LAST : // 末尾ノードを削除 list.removeLast(); break; case RMV_CRNT : // 着目ノードを削除 list.removeCurrentNode(); break; 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); break; 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); break; case NEXT : // 着目ノードを後方に進める list.next(); break; case PREV : // 着目ノードを前方に進める list.prev(); break; case PRINT_CRNT : // 着目ノードのデータを表示 list.printCurrentNode(); break; case DUMP : // 全ノードをリスト順に表示 list.dump(); break; case CLEAR : // 全ノードを削除 list.clear(); break; case INIT_LIST: // リストを初期化 list.clear();

(24)

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); break;

}

} while (menu != Menu.TERMINATE); }

}

参照

関連したドキュメント

あらまし MPEG は Moving Picture Experts Group の略称であり, ISO/IEC JTC1 におけるオーディオビジュアル符号化標準の

平成 26 年の方針策定から 10 年後となる令和6年度に、来遊個体群の個体数が現在の水

北海道の来遊量について先ほどご説明がありましたが、今年も 2000 万尾を下回る見 込みとなっています。平成 16 年、2004

当監査法人は、我が国において一般に公正妥当と認められる財務報告に係る内部統制の監査の基準に

Medial

〒020-0832 岩手県盛岡市東見前 3-10-2

(1) 会社更生法(平成 14 年法律第 154 号)に基づき更生手続開始の申立がなされている者又は 民事再生法(平成 11 年法律第

異世界(男性) 最凶の支援職【話術士】である俺は世界最強クランを従える 5 やもりちゃん オーバーラップ 100円