36
Linked-list เป็ นโครงสร ้างที่ใช ้ในการจัดเก็บข ้อมูลอีกรูปแบบหนึ่งที่มีการนามาใช ้อย่างมาก Linked-List เป็ นโครงสร ้างที่ใช ้งานได ้ดีกว่า array เนื่องจากว่ามีความยืดหยุ่นในเรื่องของเนื้อทีในการเก็บข ้อมูล การจัดการกับข ้อมูลก็ทาได ้ดีกว่า ถ ้ามีการออกแบบการใช ้อย่างเหมาะสม ใน บทนี้เราจะมาทาความเข ้าใจกับการจัดเก็บข ้อมูลด ้วย Linked-List หลังจากจบบทเรียนนี้แล ้ว ผู ้อ่านจะได ้ทราบถึง o การออกแบบโครงสร ้างของ Node ที่ใช ้เป็ นตัวเก็บข ้อมูลและตัวเชื่อมใน Linked-List o การออกแบบโครงสร ้างของ Linked-List o การนาข ้อมูลเข ้า (insert) และออกจาก (remove) Linked-List o การใช ้ Linked-List เป็ นตัวจัดการข ้อมูลของ Stack และ Queue o การออกแบบและใช ้ Double-Ended Linked-List o การออกแบบและใช ้ Doubly-Linked-List o การใช ้ Linked-List ของ Java 2.1 Linked-List Linked-list เป็ นการนาเอาโครงสร ้างที่ (ส่วนใหญ่) เรียกว่า node มาต่อเชื่อมกันเป็ นลูกโซ่ ซึ่ง ข ้อดีของการนาเอา node มาต่อเชื่อมกันในลักษณะนี้ทาให ้การจัดเก็บมีความยืดหยุ่นมากยิ่งขึ้น เราสามารถที่จะเพิ่มจานวนของ node ได ้ตามใจโดยไม่ต ้องคานึงถึงขีดจากัดเหมือนกับการ จัดเก็บแบบ array (ยกเว ้นกรณีที่เราใช ้ memory ของระบบจนหมด!) ถ ้าผู ้อ่านลองนึกภาพถึง ขบวนรถไฟ ผู ้อ่านก็จะเห็นว่าที่จริงแล ้วขบวนรถไฟเป็ นการนาเอาตู ้โบกี้มาต่อเข ้าด ้วยกัน ขบวน จะสั้นหรือยาวก็ขึ้นอยู่กับจานวนโบกี้เหล่านี้ หากผู ้โดยสารที่อยู่ในโบกี้แรก ๆ ต ้องการจะไปยัง โบกี้สุดท ้ายก็ต ้องเดินผ่านโบกี้อื่น ๆ ระหว่างทางด ้วย เช่นเดียวกันกับการจัดเก็บข ้อมูลในรูปแบบ ของ Linked-List การเข ้าหา node แต่ละ node ก็ต ้องผ่าน node อื่น ๆ ด ้วย link ที่เชื่อมต่อ node เหล่านี้ไว Linked-list ประกอบด ้วย node หลาย ๆ node ซึ่งในหนึ่ง node จะมี field ที่เป็ นข ้อมูล (data) ซึ่งอาจมีหลายได ้ตัว แต่จะต ้องมี field อยู่หนึ่ง field ที่เป็ นตัวเชื่อม (link) ไปยัง node อื่น เช่น ที่เห็นในภาพที2.1

เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-list เปนโครงสรางทใชในการจดเกบขอมลอกรปแบบหนงทมการน ามาใชอยางมาก Linked-List เปนโครงสรางทใชงานไดดกวา array เนองจากวามความยดหยนในเรองของเนอทในการเกบขอมล การจดการกบขอมลกท าไดดกวา ถามการออกแบบการใชอยางเหมาะสม ในบทนเราจะมาท าความเขาใจกบการจดเกบขอมลดวย Linked-List หลงจากจบบทเรยนนแลว ผอานจะไดทราบถง o การออกแบบโครงสรางของ Node ทใชเปนตวเกบขอมลและตวเชอมใน Linked-List o การออกแบบโครงสรางของ Linked-List o การน าขอมลเขา (insert) และออกจาก (remove) Linked-List o การใช Linked-List เปนตวจดการขอมลของ Stack และ Queue o การออกแบบและใช Double-Ended Linked-List o การออกแบบและใช Doubly-Linked-List o การใช Linked-List ของ Java 2.1 Linked-List Linked-list เปนการน าเอาโครงสรางท (สวนใหญ) เรยกวา node มาตอเชอมกนเปนลกโซ ซงขอดของการน าเอา node มาตอเชอมกนในลกษณะนท าใหการจดเกบมความยดหยนมากยงข น เราสามารถทจะเพมจ านวนของ node ไดตามใจโดยไมตองค านงถงขดจ ากดเหมอนกบการจดเกบแบบ array (ยกเวนกรณทเราใช memory ของระบบจนหมด!) ถาผอานลองนกภาพถงขบวนรถไฟ ผอานกจะเหนวาทจรงแลวขบวนรถไฟเปนการน าเอาตโบกมาตอเขาดวยกน ขบวน

จะสนหรอยาวกข นอยกบจ านวนโบกเหลาน หากผโดยสารทอยในโบกแรก ๆ ตองการจะไปยงโบกสดทายกตองเดนผานโบกอ น ๆ ระหวางทางดวย เชนเดยวกนกบการจดเกบขอมลในรปแบบของ Linked-List การเขาหา node แตละ node กตองผาน node อน ๆ ดวย link ทเชอมตอ node เหลานไว Linked-list ประกอบดวย node หลาย ๆ node ซงในหนง node จะม field ทเปนขอมล (data) ซงอาจมหลายไดตว แตจะตองม field อยหนง field ทเปนตวเชอม (link) ไปยง node อน เชน

ทเหนในภาพท 2.1

Page 2: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

34

ภาพท 2.1 linked-list

การน าขอมลเขาส Linked-List ท าไดดวยการสราง node ขนใหมหนง node แลวจงท าการเชอม node ใหมนเขากบ node อน ๆ ทมอยใน Linked-List การเชอม node ตาง ๆ เขาดวยกนนน ทจรงแลวเปนการก าหนดใหตวแปรทมชนดเปน node ไดรบทอย (address) ในหนวยความจ าของ node ทตองการเชอม เชน สมมตวา node1 และ node2 เปน node ทเราสรางขน และเราตองการเชอม node ทงสองตวเขาดวยกน เรากอาจใชค าสง node1.next = node2 โดยทตวแปร next จะมทอยของ node2 เรามาดกนถงโครงสรางของ node ทเราไดพดถงเพอใหเกดความเขาใจในเรองของการเชอม node public class MyNode<T> {

private T data; //data

private MyNode<T> next; //connector (link)

}

เราก าหนดให field ทเปน data นนเกบขอมลทเปนอะไรกไดตามใจผใช (ซง field ทเปน data นจะมก field กได ในทนจะยกตวอยางของ node ทม data เพยงหนง field เทานน) สวน field ทสองเปน field ทมชนดเปนชนดเดยวกนกบตวของ class เอง ซงเราใชช อวา MyNode ต าราหลาย ๆ เลมเรยกโครงสรางแบบนวา โครงสรางทอางถงตวเอง (Self-referential Structure) เนองจากวา field next ของเรามชนดเปนตวของมนเองคอ MyNode และ field next ตวนแหละทจะเปนทเกบ address ของ node อนทมนชอย ยอนกลบไปด node1 และ node2 ของเรา ถา node1 อยในหนวยความจ าท 1024 และ node2 อยท 1032 และถาเราเชอม node2 เขากบ node1 field next ของ node1 จะมคาเทากบ 1032 ดงทแสดงใหดในภาพท 2.2

data

next

data

next next

data

null

head

378

next

924

next next

258

null

head

โครงสรางหลกของ Linked-List

ตวอยางของ Linked-List ทมขอมลอย 3 ตว

node

Page 3: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

35

ภาพท 2.2 การเชอม node

ในการจดเกบแบบ linked-list น ขอมลหรอ node ทเขามาหลงสดจะเปนขอมลตวแรกเมอมการดงออก ลองมาด code ของ node ทเราไดพดถง และน ามาใชในการสราง Linked-List ของเรา

1: /**

2: Basic structure for a node

3: Java has a Node class, so we use MyNode instead

4: */

5:

6: public class MyNode<T> {

7: private T data; //data

8: private MyNode<T> next; //connector (link)

9:

10: //default constructor

11: public MyNode() {

12: data = null;

13: next = null;

14: }

15:

16: //constructor that assigns data and links

17: //to the given node (n)

18: public MyNode(T obj, MyNode<T> n) {

19: data = obj;

20: next = n;

21: }

22:

23: //set this node to node n

24: public void setNext(MyNode<T> n) {

25: next = n;

26: }

27:

28: //set this node's data to d

29: public void setData(T d) {

30: data = d;

31: }

32:

node1

1032

node2

null

1024

1032

1028

1036

ต าแหนงในหนวยความจ า

ทอยของ node ท node นเช อมอย

(node2)

node1

next null

node2

node1 เชอมกบ node2 ผานทาง field next

ทอยของ node ทงสองในหนวยความจ า

ขอมลทเกบ

Page 4: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

36

33: //get node next to this node

34: public MyNode<T> getNext() {

35: return next;

36: }

37:

38: //get data of this node

39: public T getData() {

40: return data;

41: }

42: }

เราก าหนดใหม field อยสอง filed โดยก าหนดให field แรกเปน Object และ filed ทสองเปนตวเชอม (next) ซง filed ทสองนจะตองมชนดเดยวกนกบส งทมนจะตองเชอมดวย นนกคอ MyNode

private T data; //data

private MyNode<T> next; //connector (link)

เราก าหนดใหม constructor สองตวรองรบการสราง object จาก class MyNode ของเรา โดยก าหนดใหตวแรกเปน constructor ทไมม parameter เพอการสราง node เปลาทไมตองมขอมล สวนตวทสองเราก าหนดให parameter ตวแรกเปน object ทตองการเกบไวใน node สวน parameter ตวทสองก าหนดใหเปน node ทตองเชอมตอดวย //default constructor

public MyNode() {

data = null;

next = null;

}

//constructor that assigns data and links to the given node (n)

public MyNode(T obj, MyNode<T> n) {

data = obj;

next = n;

}

สวน method ตวอน ๆ 4 ตวทเหนน เราเอาไวใชเพอ setNext() ก าหนดจดเชอมของ node getNext() หา node ถดไป

setData() ก าหนดขอมลทอยใน node getData() ดงขอมลออกจาก node เมอเราได MyNode แลว เรากตองออกแบบ Linked-list ส าหรบการน าขอมลเขา และการดงขอมลออก

1: /**

2: Basic structure for Linked List

3: Java has a LinkedList class, so we use MyLinkedList instead

4: */

5:

6: public class MyLinkedList<T extends Comparable<? super T>> {

7: private MyNode<T> head; //gateway node

8: private int count; //nodes in list

9:

10: //default constructor

11: public MyLinkedList() {

12: head = null;

13: count = 0;

14: }

15:

16: //check if list is empty

17: public boolean empty() {

18: return head == null;

19: }

20:

21: //return number of nodes

22: public int size() {

Page 5: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

37

23: return count;

24: }

25:

26: public void insert(T value) {

27: //create new node with given value and link head to

28: //this node, equivalent to the following statements

29: //MyNode temp = new MyNode(value, null);

30: //head.setNext(temp);

31: head = new MyNode<T>(value, head);

32: count++; //one more node added

33: }

34:

35: //remove node where head points to

36: public T remove() {

37: //cannot remove if list is empty

38: if(empty())

39: return null;

40: //point head to the node next to it

41: //using temp to retrieve data

42: MyNode<T> temp = head;

43: head = temp.getNext();

44: count--; //one less node

45: return temp.getData(); //return object removed

46: }

47:

48: //peek at data of node n

49: public T peek(int n) {

50: //traversing the list using temp

51: MyNode<T> temp = head;

52: for(int i = 0; i < n && temp != null; i++)

53: temp = temp.getNext();

54: return temp.getData();

55: }

56:

57: //display contents of list via System.out.println()

58: public String toString() {

59: StringBuffer buf = new StringBuffer();

60: buf.append("head->(" + peek(0));

61: for(int i = 1; i < size(); i++)

62: buf.append(", " + peek(i));

63: buf.append(")");

64: return new String(buf);

65: }

66:

67: //to display addresses of all nodes in list

68: //converting from Hex to Dec

69: //beginning address of MyNode start with MyNode@

70: //follow by Hex digits e.g. MyNode@13f5d07

71: public void address() {

72: MyNode<T> temp = head;

73: String thisNode, nextNode;

74: int numNode = 0, numNext = 0;

75: while(temp != null) {

76: //convert Node to String before

77: //convert it to int - starts at 5th index

78: thisNode = temp.toString();

79: numNode = Integer.parseInt(thisNode.substring(7), 16);

80: //avoiding null at last node

81: if(temp.getNext() != null) {

82: nextNode = temp.getNext().toString();

83: numNext = Integer.parseInt(nextNode.substring(7), 16);

84: }

85: System.out.print("This node: " + numNode);

86: System.out.println("\tNext node: " + numNext);

87: temp = temp.getNext();

88: }

89: }

90: }

method ทส าคญในการสราง linked-list กคอ method insert() และ method remove() ส าหรบ method insert() นน เราอาศย constructor ของ class Node เปน method หลกใน

Page 6: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

38

การ insert เราก าหนดใหมตวแปร count เพอเอาไวบอกจ านวนของ node ทงหมดทมอยใน linked-list 2.2 การน า node เขาส Linked-List ทางดานหนา public void insert(T value) {

//create new node with given value and link head to

//this node, equivalent to the following statements

//MyNode<T> temp = new MyNode<T>(value, null);

//head.setNext(temp);

head = new MyNode<T>(value, head);

count++; //one more node added

}

สงทเกดข นอนดบแรกใน method insert() คอ การสราง node ดวย object ทสงเขามา ประโยคทวา new MyNode(value, head) จะท าให field ทช อวา data ใน class MyNode มคาเปนคาเดยวกนกบคาของ value สวน field ทสองจะชไปยงทท head ชอย (อางถงส งเดยวกน) ซงถา Linked-List ของเราเปน List ใหมทไมม ขอมลอยเลย head จะมคาเปน null ดงนน ประโยค head = new MyNode<T>(value, head);

กเปนการก าหนดคาเกาท head ชอยใหกบ field ทช อวา next (ครงแรก head มคาเปน null – จงท าให node ใหมนมคา null อยใน field next) หลงจากนนจงก าหนดคาใหกบ head ใหม ซงกคอคาของ node ตวใหมนเอง ดงแสดงในภาพท 2.3

ภาพท 2.3 แสดงเมอสราง Linked-List ครงแรก และ เมอม node อย

และทกครงทมการสราง node ใหม เราจะเพมคาของ count ขนอกหนงคาเพอใชบอกจ านวนของ node ทมอยใน linked-list นน 2.3 การลบ node ออกจาก Linked-List ทางดานหนา การลบ node ออกจาก Linked-List เราตองตรวจสอบดวา linked-list ของเรามขอมลหรอไมถาไมมเรากสง null กลบเพอเปนการบอกวาไมสามารถทจะลบ node ได แตถามขอมล เรากท าการลบ node ออกดวยการก าหนดคาของ head ใหเปนคาของ node ทอยถดไป ดวยค าสง MyNode temp = head และค าสง head = temp.getNext() หลงจากนนเรากลดจ านวนของ node ลงดวย count-- เสรจแลวเรากสงขอมลของ node ทถกลบกลบออกไป ดงทเหนจาก code และภาพท 2.4 //remove node where head points to

public T remove() {

//cannot remove if list is empty

if(empty())

return null;

//point head to the node next to it

//using temp to retrieve data

null head

head 423

null

Linked-List ขณะทไมม node อยเลย

Linked-List ขณะทม node อย 1 node จากประโยค

head = new MyNode(value, head)

Page 7: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

39

MyNode<T> temp = head;

head = temp.getNext();

count--; //one less node

return temp.getData(); //return object removed

}

ภาพท 2.4 การลบ node ออกจาก Linked-List

เมอเราลบ node ออกจาก Linked-List เราไมตองกงวลถงการคน memory ของ node ทเราลบออก (temp) เพราะ java จะท าการตรวจสอบสวนของ memory ทไมไดใชงานดวย garbage collector และจะคน memory ทไมมการอางถงคนใหระบบเอง แตเราสามารถทจะท าใหการท างานของระบบดข น ดวยการท าให node ทไมไดใชงานแลวมคาเปน null นนกคอก าหนดให temp = null เพราะฉะนน remove() ของเรากตองเปลยนเปน //remove node where head points to

public T remove() {

//cannot remove if list is empty

if(empty())

return null;

//point head to the node next to it

//using temp to retrieve data

MyNode<T> temp = head;

head = temp.getNext();

count--; //one less node

T value = temp.getData(); //copy data from temp

temp = null; //make it null

return value; //return object removed

}

method peek() เอาไวใชในการดวาขอมล ณ ต าแหนงนน ๆ คออะไร เราจะใช method peek() ในการ display ขอมลของ node ทกตวทมอยใน Linked-list การเขยนกไมยาก เราเพยงแตสราง node ขนใหมหนง node และก าหนดให node ใหมนช ไปทท head ชอย (ดานหนาสดของ Linked-List) พรอมทงใช for loop และ parameter ของ method peek() เปนตวก าหนดการเขาหา เมอเราเจอต าแหนงทตองการ เรากสงขอมล ณ ต าแหนงนนกลบไปยงผเรยก //peek at data of node n

public T peek(int n) {

//traversing the list using temp

MyNode<T> temp = head;

for(int i = 0; i < n && temp != null; i++)

temp = temp.getNext();

return temp.getData();

}

458

null

temp

head 329

MyNode temp = head;

458

null

temp

head 329

head = temp.getNext();

Page 8: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

40

เราทดสอบ code ของเราดวยการ insert ขอมลทเปน int เขาส Linked-List เปนจ านวน 4 ตว และท าการลบออก 2 ตว

1: /**

2: Testing MyLinkedList

3: */

4:

5: class TestMyLinkedList {

6: public static void main(String[] args) {

7: MyLinkedList<Integer> list = new MyLinkedList<Integer>();

8:

9: //insert 4 ints

10: list.insert(34);

11: list.insert(67);

12: list.insert(12);

13: list.insert(78);

14: list.insert(32);

15: System.out.println(list);

16:

17: //remove first 2 items

18: list.remove();

19: list.remove();

20: System.out.println(list);

21: }

22: }

ผลลพธทไดจากการ run head->(32, 78, 12, 67, 34)

head->(12, 67, 34)

ม method อกหนงตวทเราไดเขยนขนเพอใชในการตรวจสอบทอยในหนวยความจ าของ node ตาง ๆ ทอยใน Linked-List นนกคอ method address() ซงอาจไมคอยมความจ าเปนเทาไร แตผเขยนเหนวาในบางครงถาเราใหมตอเรองของ Self-referential Structure วธการดต าแหนงของตวแปรในหนวยความจ ากชวยท าใหเกดความเขาใจทดข น วธการกไมมอะไรเลย เราเพยงแตสง node นน ๆ ไปใหชองสงขอมลออก (System.out.println()) เทานนเอง Java กจะแสดงทอยของ node นน ๆ ใหเราเอง ดงทเหนจากผลลพธของการเรยกใช address() ดานลางน (เพอใหงายตอการอาน เราจงเปลยนทอยของ node ทเปนเลขฐานสบหก ใหเปนเลขในฐานสบ) public void address() {

MyNode<T> temp = head;

String thisNode, nextNode;

int numNode = 0, numNext = 0;

while(temp != null) {

//convert Node to String before

//convert it to int - starts at 5th index

thisNode = temp.toString();

numNode = Integer.parseInt(thisNode.substring(7), 16);

//avoiding null at last node

if(temp.getNext() != null) {

nextNode = temp.getNext().toString();

numNext = Integer.parseInt(

nextNode.substring(7), 16);

}

System.out.print("This node: " + numNode);

System.out.println("\tNext node: " + numNext);

temp = temp.getNext();

}

}

หลงจากทเรยก address() ในโปรแกรมตรวจสอบทเราเขยนขน เราไดผลลพธดงน Insert 10 random Integers

head->(54)

head->(54, 42)

head->(86, 54, 42)

head->(86, 54, 42, 2)

head->(86, 86, 54, 42, 2)

Page 9: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

41

head->(86, 86, 54, 42, 2, 35)

head->(70, 86, 86, 54, 42, 2, 35)

head->(70, 86, 86, 54, 42, 2, 35, 16)

head->(88, 70, 86, 86, 54, 42, 2, 35, 16)

head->(88, 70, 86, 86, 54, 42, 2, 35, 16, 10)

This node: 20929799 Next node: 16032330

This node: 16032330 Next node: 13288040

This node: 13288040 Next node: 27355241

This node: 27355241 Next node: 30269696

This node: 30269696 Next node: 24052850

This node: 24052850 Next node: 26022015

This node: 26022015 Next node: 3541984

This node: 3541984 Next node: 4565111

This node: 4565111 Next node: 20392474

This node: 20392474 Next node: 20392474

จะเหนวาคาทอยใน filed next ของ node จะมคาเปนทอยของ node ถดไป จนกระทงถง node สดทายทมคาเปน null จากผลลพธเราจะเหนคา 20392474 เหมอนกนสามตวโดยเฉพาะ field next ของ node สดทายเราจะเหนวามคาเทากบตวมนเอง(ผเขยนคดวา Java อางถง null ดวยการอางถงตวเองของ node เพอใหรวาไมม node ใด ๆ เชอมตอกบ node นอก ถาเราไมเปลยนทอยของ node ใหเปนเลขฐานสบ เราจะเหนขอมล ณ ต าแหนงนเปน null) การน าขอมลเขาส Linked-List ไมจ าเปนทจะตองน าเขาทางดานหนาเสมอไป เราอาจน าขอมลเขาทางดานหลงของ Linked-List กได เชนเดยวกนกบการน าขอมลออก เรากสามารถทจะดงขอมลออกจากทางดานหลงของ Linked-List ได 2.4 การน า node เขาส Linked-List ทางดานหลง วธการทจะน าขอมลเขาทางดานหลงของ Linked-List นน เราจะตองหาต าแหนงของ node สดทายใหเจอเสยกอน โดยเราสามารถทจะท าไดดวยการใช node ชวคราวท าหนาทเปนตวเดนเขาหา node ทกตว เพอท าการตรวจสอบวา node ทเราเขาหาอยตวนม field next ทมคาเปน null หรอไม ซงถาใช แสดงวาเราเจอ node สดทายแลว เรากท าการเพม node ใหมใหกบ Linked-List ดวยการเชอม node สดทายเขากบ node ใหมน ดงทเหนในภาพท 2.5

ภาพท 2.5 การน าขอมลเขาส Linked-list ทางดานหลง

cur จะชไปท node สดทายทอยใน list กอนการเชอมกบ tmp

458

null

head 329

cur

cur.setNext(tmp);

null

458

head 329

tmp

899

MyNode tmp = new MyNode(obj, cur.getNext());

List กอนการน าขอมลเขา

List หลงจากการน าขอมลเขา

address ทเกดจากการก าหนดของ Java ใหกบ node ทง 10 ตวทเราสรางข น

ผอานควรสงเกตถง address ทอยใน next ของ node กอนหนา กบ address

ของ node ถดไป

Page 10: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

42

//insert data at the end of list

public void insertEnd(T obj) {

//list empty - just call insert()

if(empty())

insert(obj);

else {

//there is at least one node in the list,

//we must locate the last node

MyNode<T> cur = head;

while(cur.getNext() != null)

cur = cur.getNext();

//create new node with given data

//and set current node to point to this new node

MyNode<T> tmp = new MyNode<T>(obj, cur.getNext());

cur.setNext(tmp);

count++; //one more node added

}

}

เราเรมตนดวยการตรวจสอบวา Linked-List ของเรามขอมลหรอไม ถาไมม เรากเรยก insert() ท าหนาทใสขอมลใหเรา แตถามขอมลอยแลว เรากใช cur เปนตวเดนเขาหา Linked-List จนกวาจะเจอ null ซงถาเจอ cur จะชอยท node สดทายและ filed next ของ cur จะชท null หลงจากนนเรากสราง node ใหมชอ tmp ดวยขอมลทเราตองการใสพรอมทง field next ของ cur หลงจากทเราได node ใหมแลวเรากก าหนดให cur ชไปท node ใหมน เราทดสอบ insertEnd() ดวยการเปลยนโปรแกรม TestMyLinkedList.java ใหสราง Integer 10 ตวโดยจะเรยกใช insert() ถา index ของ for loop เปนเลขค และเรยก insertEnd() ถา index เปนเลขค ดงทเหนดานลางน

1: /**

2: Testing MyLinkedList

3: */

4:

5: class TestMyLinkedList {

6: public static void main(String[] args) {

7: MyLinkedList<Integer> list = new MyLinkedList<Integer>();

8:

9: //insert 10 integers

10: for(int i = 0; i < 10; i++) {

11: //at even location

12: if(i % 2 == 0)

13: list.insert(i);

14: //at odd location

15: else

16: list.insertEnd(i);

17:

18: System.out.println(list);

19: }

20: }

21: }

ผลลพธทไดคอ head->(0)

head->(0, 1)

head->(2, 0, 1)

head->(2, 0, 1, 3)

head->(4, 2, 0, 1, 3)

head->(4, 2, 0, 1, 3, 5)

head->(6, 4, 2, 0, 1, 3, 5)

head->(6, 4, 2, 0, 1, 3, 5, 7)

head->(8, 6, 4, 2, 0, 1, 3, 5, 7)

head->(8, 6, 4, 2, 0, 1, 3, 5, 7, 9)

สงทเราตองค านงถงกคอ ต าแหนงทตองน า node เขาส Linked-List ในการ insert แบบน node

ทวานกคอ node ทายสดของ Linked-List หรอจะพดใหถกตองกคอ node ทมคาเทากบ null

Page 11: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

43

เราหาต าแหนงของ node นไดดวยการตรวจสอบ field ทช อวา next ของทก node ใน Linked-List วามคาเทากบ null หรอไม ดวยการใช loop และ method getNext() 2.5 การลบ node ออกจาก Linked-List ทางดานหลง การลบ node ออกจาก Linked-List ทางดานหลงกคลายกบการเพม node เราตองหาต าแหนงทายสดของ Linked-List ใหเจอกอนทจะท าการยาย pointer ทเกยวของ ภาพท 4.6 แสดงการหา node สดทายดวย node ชวคราวทช อ temp พรอมทงการก าหนดคา next ของ temp ใหมคาเทากบ null (ผานทาง temp)

ภาพท 2.6 การลบ node สดทายทอยใน Linked-List

code ของการลบ node ออกจากทางดานหลงมดงน //remove node at end of list

public T removeEnd() {

//list is empty

if(empty())

return null;

//only one object in the list

if(head.getNext() == null)

return remove();

//locate the last node

MyNode<T> temp = head;

while(temp.getNext().getNext() != null)

temp = temp.getNext();

//save value of this object

T obj = temp.getNext().getData();

//set next field of the node before last node to null

temp.setNext(temp.getNext().getNext());

count--; //one less node

return obj;

}

ขนตอนการท างานของ code กไมยาก เราเรมทการตรวจสอบวา Linked-List ของเรามขอมล หรอไม ถาไมมเรากสง null กลบออกไป ขนตอนตอไปเรากตรวจสอบวา Linked-List มขอมลอยเพยงตวเดยวหรอไม ซงถาใช เรากเรยก method remove() แบบปกตทเราเขยนกอนหนาน ถาเราผานสองขนตอนนโดยไมมการประมวลผลเลย แสดงวา Linked-List ของเรามขอมลอยาง

head 345 678

null

123

temp

while/loop จะยตการท างานเมอ

temp.getNext().getNext() == null เปนจรง

head 345 678

null

123

temp

หลงจากทเจอ node กอน node สดทายเรากลบ node สดทายดวยประโยค

temp.setNext(temp.getNext().getNext());

Page 12: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

44

นอยสองตว เรากใช temp เปนตวพาเราเขาหา node ทตองการ (หลงจากทก าหนดให temp = head แลว) ดวยค าสง while(temp.getNext().getNext() != null)

temp = temp.getNext();

เมอเจอแลวเรากเกบคาของ node นไว ดวยค าสง T obj = temp.getNext().getData();

และท าการยาย pointer ใหไปชท null ซงท าไดดวยการใชค าสง temp.setNext(temp.getNext().getNext());

และเมอทดลอง run ดวยโปรแกรมทเหนน

1: /**

2: Testing MyLinkedList

3: */

4:

5: import static java.lang.System.out;

6:

7: class TestMyLinkedList {

8: public static void main(String[] args) {

9: MyLinkedList<Integer> list = new MyLinkedList<Integer>();

10:

11: //insert 10 integers

12: for(int i = 0; i < 10; i++) {

13: //at even location

14: if(i % 2 == 0)

15: list.insert(i);

16: //at odd location

17: else

18: list.insertEnd(i);

19:

20: out.println(list);

21: }

22:

23: //remove 5 integers

24: for(int i = 0; i < 5; i++) {

25: //at even location

26: if(i % 2 == 0)

27: out.println("Removed: " + list.remove());

28: //at odd location

29: else

30: out.println("Removed: " + list.removeEnd());

31:

32: out.println(list);

33: }

34: }

35: }

ผลลพธทไดคอ head->(0)

head->(0, 1)

head->(2, 0, 1)

head->(2, 0, 1, 3)

head->(4, 2, 0, 1, 3)

head->(4, 2, 0, 1, 3, 5)

head->(6, 4, 2, 0, 1, 3, 5)

head->(6, 4, 2, 0, 1, 3, 5, 7)

head->(8, 6, 4, 2, 0, 1, 3, 5, 7)

head->(8, 6, 4, 2, 0, 1, 3, 5, 7, 9)

Removed: 8

head->(6, 4, 2, 0, 1, 3, 5, 7, 9)

Removed: 9

head->(6, 4, 2, 0, 1, 3, 5, 7)

Removed: 6

head->(4, 2, 0, 1, 3, 5, 7)

Page 13: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

45

Removed: 7

head->(4, 2, 0, 1, 3, 5)

Removed: 4

head->(2, 0, 1, 3, 5)

code ของ class MyLinkedList ทเขยนขนนสามารถทจะท างานไดทงทางดานหนาและดานหลง แตมขดจ ากด คอ การเพมหรอลบ node ทางดานหลง จะตองใชเวลาในการเดนทางเขาหา list ดงนนเพอใหการท างานมประสทธภาพมากขน เราจงก าหนดใหม pointer อกหนงตวชไปท node สดทายทอยใน list เราเรยก Linked-List แบบนวา Double-Ended Linked-List 2.6 การสราง Double-Ended Linked-List การออกแบบ Double-Ended Linked-List นน สวนใหญจะใช pointer 2 ตวเปนตวจ าต าแหนงของ node ทอยดานหนาและ node ทอยทายสด (มกจะเรยกวา head และ rear) ท าใหการน าขอมลเขาและดงออกเปนไปไดโดยงาย ภาพท 2.7 แสดงโครงสรางของ Double-Ended Linked-List

ภาพท 2.7 Double-Ended Linked-List

เราดดแปลง class MyLinkedList ใหม node 2 ตวคอ head และ rear พรอมกบก าหนดใหทงสองมคาเปน null ใน constructor เราออกแบบการน าเขาใหมดวยการสราง method insertFirst() และ insertLast() ทท าหนาทในการน าขอมลเขาทางดานหนา และทางดานหลงตามล าดบ สวน method อน ๆ กเหมอนเดม ยกเวน toString() ทเราเพม "<-last" ในตวแปร buf ส าหรบการแสดงต าแหนงของ node สดทายทอยใน list ลองมาด code ของ insertFirst()

และ insertLast() กน public void insertFirst(T item) {

//no item yet in list

if(empty()) {

head = new MyNode<T>(item, head);

rear = head;

}

//some items are already in list

else

head = new MyNode<T>(item, head);

count++; //one more node added

}

การท างานของ insertFirst() กไมยากอะไร หลงจากทตรวจสอบแลววา list ไมมขอมลอย เรากสราง node ขนใหมพรอมทงก าหนดให head ชไปท node น พรอมทงก าหนดให rear มคาเทากบ head (เรมตนทเดยวกน) แตถา list มขอมลอยแลว เรากสราง node ใหมเชนเดยวกบทเราท ากบ Linked-List ทมการเขาออกทางดานหนาดานเดยว สวน code ของ insertLast() กมดงน public void insertLast(T item) {

MyNode<T> temp = new MyNode<T>(item, null);

rear.setNext(temp); //connect current node to new node

rear = temp; //reset rear to this new node

count++;

}

head

345 678

null

123

rear

Page 14: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

46

เนองจากวาเรารวา rear ชอยท node สดทายเสมอ ดงนนเรากเพยงแตสราง node ใหมทม field next มคาเปน null ตอมาเรากก าหนดให field next ของ node ท rear ชอยมคาเทากบ node ใหมทเราสรางขน พรอมกบก าหนดให rear ชไปท temp หลงจากนน method ตวอน ๆ กเหมอน ๆ กบทผานมา ดงทแสดงไวใน class DoubledEndedLinkesList น

1: /**

2: Doubled-Ended LinkedList

3: */

4:

5: class DoubleEndedLinkedList<T extends Comparable<? super T>> {

6: private MyNode<T> head, rear;

7: private int count;

8:

9: //default constructor

10: DoubleEndedLinkedList() {

11: head = rear = null;

12: count = 0;

13: }

14:

15: //insert where head is

16: public void insertFirst(T item) {

17: //no item yet in list

18: if(empty()) {

19: head = new MyNode<T>(item, head);

20: rear = head;

21: }

22: //some items are already in list

23: else

24: head = new MyNode<T>(item, head);

25: count++; //one more node added

26: }

27:

28: //insert where rear is

29: public void insertLast(T item) {

30: MyNode<T> temp = new MyNode<T>(item, null);

31: rear.setNext(temp); //connect current node to new node

32: rear = temp; //reset rear to this new node

33: count++;

34: }

35:

36: //check if list is empty

37: public boolean empty() {

38: return head == null;

39: }

40:

41: //return number of nodes

42: public int size() {

43: return count;

44: }

45:

46: //peek at data of node n

47: private T peek(int n) {

48: //traversing the list using temp

49: MyNode<T> temp = head;

50: for(int i = 0; i < n && temp != null; i++)

51: temp = temp.getNext();

52: return temp.getData();

53: }

54:

55: //display contents of list via System.out.println()

56: public String toString() {

57: StringBuffer buf = new StringBuffer();

58: buf.append("head->(" + peek(0));

59: for(int i = 1; i < size(); i++)

60: buf.append(", " + peek(i));

61: buf.append(")<-last");

62: return new String(buf);

63: }

64: }

เมอทดสอบ code ทเขยนขนใหมดวยโปรแกรม TestDBEndedLinkedList.java ทเหนน

Page 15: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

47

1: /**

2: Testing Double-Ended LinkedList

3: */

4:

5: class TestDBEndedLinkedList {

6: public static void main(String[] args) {

7: DoubleEndedLinkedList<Integer> list = new

DoubleEndedLinkedList<Integer>();

8:

9: //populate linked-list with 10 random Integers

10: System.out.println("Insert 10 random Integers");

11: for(int i = 0; i < 10; i++) {

12: int item = (int)(Math.random() * 100);

13: if(i % 2 == 0) {

14: list.insertFirst(item);

15: System.out.println(list);

16: }

17: else {

18: list.insertLast(item);

19: System.out.println(list);

20: }

21: }

22: }

23: }

ผลลพธทไดคอ Insert 10 random Integers

head->(19)<-last

head->(19, 63)<-last

head->(15, 19, 63)<-last

head->(15, 19, 63, 80)<-last

head->(48, 15, 19, 63, 80)<-last

head->(48, 15, 19, 63, 80, 99)<-last

head->(18, 48, 15, 19, 63, 80, 99)<-last

head->(18, 48, 15, 19, 63, 80, 99, 3)<-last

head->(54, 18, 48, 15, 19, 63, 80, 99, 3)<-last

head->(54, 18, 48, 15, 19, 63, 80, 99, 3, 10)<-last

มกระบวนการอน ๆ ทเราสามารถน ามาประยกตใชกบการท างานกบ Linked-List ไดอกหลายกระบวนการ เชน การลบทางดานหนา และทางดานหลงของ Linked-List การ insert ขอมลเขา

ส Linked-List แบบทตองค านงถงต าแหนงทเหมาะสมของขอมล (ordered list) ในทนจะทงไว เปนแบบฝกหด และกรณศกษาของผอานตอไป ซงอาจดดแปลงจาก method insertInorder() ของ Doubly-Linked-List ทเราจะพดถงตอไป หลงจากทเราไดพดถงการใช Linked-List เปนตวจดการกบขอมลของ Stack และ Queue เรยบรอยแลว 2.7 Doubly-Linked-List

Doubly-Linked-List เปน list ทผใชสามารถทจะเขาและออกไดทงสองทาง ทงทางดานหนาและทางดานหลง การทเขาหา list ไดสองทางท าใหการท างานเกยวกบ list มความยดหยนสงยงข น ในการออกแบบและเขยน code เราจ าเปนทจะตองม pointer สองตวทท าหนาทเปนตวบอกต าแหนงของ node แรก และ node สดทายทอยใน list นอกจากนเรายงจ าเปนทจะตองม link จาก node สดทายไปยง node อน ๆ ทอยทางดานหนาของ list เพอใชเปนสะพานเชอมในการเขาหาขอมลจากดานหลงไปดานหนา ดงนนโครงสรางของ node ของเราตองมการเพมตวเชอมอกหนงตว เราใหชอตวเชอมนวา previous ดงทแสดงใหดในภาพท 2.8

Page 16: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

48

ภาพท 2.8 โครงสรางของ node ส าหรบ Doubly-Linked-List

ภาพท 2.9 โครงสรางของ Doubly-Linked-List

เราตองการทจะแยกแยะเรองของ Doubly Linked-List ออกจาก Linked-List แบบอน ๆ ดงนนเราจงออกแบบโครงสราง node ใหมโดยใชชอวา DBLNode สวนโครงสรางของ Doubly Linked-List เองเรากใชช อวา DoublyLinkedList กอนอนเรามาดกนถงโครงสรางของ node ทเราไดปรบปรงเพอใชกบ Doubly Linked-List

1: /**

2: basic node structure for doubly linked-list

3: */

4:

5: public class DBLNode<T> {

6: private T data; //data

7: private DBLNode<T> previous; //link to node before

8: private DBLNode<T> next; //link to node after

9:

10: //default constructor

11: public DBLNode() {

12: data = null;

13: previous = next = null;

14: }

15:

16: //constructor that assigns data

17: public DBLNode(T obj) {

18: data = obj;

19: previous = next = null;

20: }

21:

22: //set this node's next link to node n

23: public void setNext(DBLNode<T> n) {

24: next = n;

25: }

26:

27: //set this node's previous link to node n

28: public void setPrevious(DBLNode<T> n) {

29: previous = n;

30: }

31:

32: //set this node's data to d

33: public void setData(T d) {

34: data = d;

next

null

325

null

previous

null

949

previous

next

325

previous

next

first

last

null

789

previous

next

Page 17: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

49

35: }

36:

37: //get node next to this node

38: public DBLNode<T> getNext() {

39: return next;

40: }

41:

42: //get node before this node

43: public DBLNode<T> getPrevious() {

44: return previous;

45: }

46: //get data of this node

47: public T getData() {

48: return data;

49: }

50: }

เราม pointer 2 ตวคอ next และ previous ใน class DBLNode เพอใชส าหรบการเขาหาทงทางดานหนาและทางดานหลง สวน method อน ๆ กยงคงคลายกบ class Node ทเราออกแบบมากอนหนาน เพยงแตเปลยนชอ และการท างานบางอยาง เราไดออกแบบ method หลก ๆ ทเราตองการใชกบ Doubly Linked-List ตามความเหมาะสมดงน

insertFirst() น าขอมลเขาทางดานหนา insertLast() น าขอมลเขาทางดานหลง insertAfter() น าขอมลเขาถดจาก node ทก าหนดให insertInorder() น าขอมลเขาดวยการจดเรยงจากนอยไปหามาก removeFirst() ดงขอมลออกทางดานหนา removeLast() ดงขอมลออกทางดานหลง

กอนอนเรามาดการน าขอมลเขาดวย insertFirst() 2.7.1 การน าขอมลเขาทางดานหนา public void insertFirst(T item) {

DBLNode<T> temp = new DBLNode<T>(item);

if(empty()) //empty

last = temp; //last points at temp

else

first.setPrevious(temp); //set previous to temp

temp.setNext(first); //set temp.next to first

first = temp; //set first to temp

count++; //one more node added

}

การ insert ขอมลเขาทางดานหนาของ list ขนตอนแรกเรากสราง node ใหมดวยขอมลทสงมาให หลงจากนนเราตรวจสอบดวา list ของเราม node อยหรอไม ถาไมมเรากให last ชไปท node ใหมน พรอมกบก าหนดให node ใหมนช ไปท first และให first ชไปท node ใหมนดวยเหมอนกน แตถา list ของเราม node อยแลว (อยางนอยหนง node) เรากก าหนดให pointer ทช อวา previous ของ node แรกสดทอยใน list ชไปท node ใหมน และให node ใหมนช ไปทเดยวกนกบท first ชอย (node แรกสด) พรอมกบก าหนดให first ชไปท node ใหมนดวย ดงแสดงในภาพท 2.10

Page 18: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

50

ภาพท 2.10 การ insert node เขาทางดานหนาของ Doubly Linked-List

2.7.2 การน าขอมลเขาทางดานหลง การ insert ของ node ทางดานหลงกคลาย ๆ กนกบการ insert ทางดานหนา ดงแสดงใน code ทเหนน public void insertLast(T item) {

DBLNode<T> temp = new DBLNode<T>(item);

if(empty()) //empty

first = temp; //set first to temp

else {

last.setNext(temp); //set last.next to temp

temp.setPrevious(last); //set temp.previous to last

}

last = temp; //set last to temp

count++; //one more node added

}

เราเรมดวยการสราง node ใหม แลวจงตรวจสอบดวา list ของเรามขอมลอยหรอไม ถาไมมเรากก าหนดให first และ last ชไปท node ใหมน แตถามเราตองก าหนดให field next ของ last ช

ไปท node ใหมพรอมกบให field previous ของ node ใหมชไปท last หลงจากนนกให last ช

ไปท node ใหมน (ภาพท 2.11)

List กอนทจะมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

null

temp

458

previous

next null

null

789

previous

next

325

previous

next

first last

null

3 1

2

null

null

789

previous

next

325

previous

next

first

last

temp

458

previous

next 1. first.setPrevious(temp);

2. temp.setNext(first); 3. first = temp;

List หลงจากการโยกยาย pointer ใหมการเชอมตอ

กบ node temp

Page 19: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

51

ภาพท 2.11 การ insert ทางดานหลงของ Doubly Linked-List

2.7.3 การลบ node ออกทางดานหนา การลบ node ออกจาก list ทางดานหนานนเราจะตองตรวจสอบวา list มขอมลหรอไม ถา list ของเราไมมขอมลเลยเรากก าหนดให last เทากบ null ซงมคาเทากบการสราง list ครงแรกของเรานนเอง แตถามขอมลอย เรากก าหนดให previous ของ node แรกสดชไปท null และให first ชไปยงทท field next ของ node first เคยชอย ดงทแสดงใหดจาก code ขางลางน (ดภาพท 2.12 ประกอบ) public T removeFirst() {

DBLNode<T> temp = first; //set temp to first

if(first.getNext() == null) //basically empty

last = null;

else

//set previous of node after first to null

first.getNext().setPrevious(null);

first = first.getNext(); //set first to that node

count--;

return temp.getData();

}

List หลงจากการโยกยาย pointer ใหมการเชอมตอกบ node temp

List กอนทจะมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

null

789

previous

next

325

previous

next

first last

null

temp

458

previous

next null

null

3

null

first last

1. last.setNext(temp);

2. temp.setPrevious(last); 3. last = temp;

temp

2

1

null

789

previous

next

325

previous

next

458

previous

next

Page 20: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

52

ภาพท 2.12 การลบ node ออกจากดานหนาของ Doubly Linked-List

2.7.4 การลบ node ออกทางดานหลง การลบออกจากทางดานหลงกคลายกบทางดานหนา เราตองค านงถงกรณท list ของเรามทงขอมลและไมมขอมล ถา list ไมมขอมลการลบกเพยงแตก าหนดให first มคาเทากบ null หลงจากนนกก าหนดให last ชไปยง node ทอยกอนหนานน แตถา list มขอมลอยเรากก าหนดให field next ของ node ทอยกอน node สดทายเปน null หลงจากนนกให last ชไปทท field previous ของ last เคยชอย (node ทอยกอนหนา last นนเอง) ด code ทใหพรอมภาพท 2.13 ประกอบ public T removeLast() {

DBLNode<T> temp = last; //set temp to last

if(first.getNext() == null) //empty

first = null;

else

//set next of node before last to null

last.getPrevious().setNext(null);

last = last.getPrevious(); //set last to that node

count--;

return temp.getData();

}

List กอนทจะมการลบ node ออกจากทางดานหนา

null

null

789

previous

next

325

previous

next

first last

2. first = first.getNext();

1. first.getNext().setPrevious(null)

null

789

previous

next

325

previous

next

first

last

null

List หลงจากทมการโยกยาย pointer เพอลบ node

null

Page 21: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

53

ภาพท 2.13 การลบ node ออกจากทางดานหลง

เมอทดลอง run ดวยโปรแกรมน

1: /**

2: Testing DoublyLinkedList

3: */

4:

5: class TestDoublyLinkedList {

6: public static void main(String[] args) {

7: DoublyLinkedList<Integer> list = new DoublyLinkedList<Integer>();

8:

9: //insert 10 random Integers

10: System.out.println("Insert 10 random Integers");

11: for(int i = 0; i < 10; i++) {

12: int item = (int)(Math.random() * 100 + 1);

13: if(i % 2 == 0)

14: list.insertFirst(item);

15: else

16: list.insertLast(item);

17: list.displayForward();

18: }

19:

20: //remove 5 items

21: System.out.println("Removed 5 Integers randomly");

22: for(int i = 0; i < 5; i++) {

23: if(i % 2 == 0)

24: list.removeFirst();

25: else

26: list.removeLast();

27: list.displayBackward();

28: }

29: }

30: }

ผลลพธทได คอ Insert 10 random Integers

null

null

789

previous

next

325

previous

next

first last

List กอนทจะมการลบ node ออกจากทางดานหลง

2. last = last.getPrevious(); 1. last.getPrevious().setNext(null);

null

null

789

previous

next

325

previous

next first

last

List หลงจาการลบ node ออกจากทางดานหลง

null

Page 22: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

54

first->{27}<-last

first->{27, 61}<-last

first->{60, 27, 61}<-last

first->{60, 27, 61, 76}<-last

first->{42, 60, 27, 61, 76}<-last

first->{42, 60, 27, 61, 76, 64}<-last

first->{66, 42, 60, 27, 61, 76, 64}<-last

first->{66, 42, 60, 27, 61, 76, 64, 95}<-last

first->{86, 66, 42, 60, 27, 61, 76, 64, 95}<-last

first->{86, 66, 42, 60, 27, 61, 76, 64, 95, 17}<-last

Removed 5 Integers randomly

last->{17, 95, 64, 76, 61, 27, 60, 42, 66}<-first

last->{95, 64, 76, 61, 27, 60, 42, 66}<-first

last->{95, 64, 76, 61, 27, 60, 42}<-first

last->{64, 76, 61, 27, 60, 42}<-first

last->{64, 76, 61, 27, 60}<-first

2.7.5 การน าขอมลเขาหลง node ทก าหนดให ยงเหลอ method อกสองตวทเราตองพดถง นนกคอ insertAfter() และ insertInorder() ในการน าขอมลเขาของทงสอง method เราตองท าการคนหาต าแหนงท node ใหมจะตองไปอย เพราะฉะนนการน าขอมลเขาแบบนจะเสยเวลาพอสมควรถา list มขนาดใหญ เรามาดกนถงการน าขอมลเขาดวย insertAfter() กอนทเราจะไปดการน าขอมลเขาดวย insertInorder()

public void insertAfter(T key, T obj) {

boolean noItem = false;

//serching for key if found -> noItem = false

//if not found -> noItem = true

DBLNode<T> current = first;

while(current != null) {

if(current.getData().equals(key))

break;

current = current.getNext();

}

noItem = (current == null) ? true : false;

if(noItem)

System.out.println("Sorry - given key doesn't exist!");

else {

DBLNode<T> temp = new DBLNode<T>(obj);

if(current == last) { //if this is the last node

last = temp; //set last to temp

}

else {

//set temp.next to current.next then

//set previous of node after current to temp

temp.setNext(current.getNext());

current.getNext().setPrevious(temp);

}

temp.setPrevious(current);//set temp.previous to current

current.setNext(temp); //set current.next to temp

}

}

สงทเราตองท ากอนคอ คนหา node ทมขอมลตามทก าหนดไวในตวแปร key เราเรมตนดวยการก าหนดให current เปนตวเขาหา list ใหเรา โดยก าหนดให current ชไปทท first ชอยและใช while/loop เปนตวประมวลผล ถาเราเขาหา list จน current มคาเทากบ null แสดงวา node ทเราคนหาไมมอยใน list เรากไมน าขอมลใหมเขา แตถาม node ตามทก าหนดจรงเรากจะน าขอมลใหมเขาส list แตเราจะตองตรวจสอบกอนวา node ทมขอมลอยนเปน node สดทายหรอ node ทอยระหวาง node อน ๆ ในกรณทเปน node สดทายเรากก าหนดให last ชไปท node ใหมน (temp) DBLNode<T> temp = new DBLNode<T>(obj);

if(current == last) { //if this is the last node

last = temp; //set last to temp

}

Page 23: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

55

แตถาเปน node ทอยระหวาง node เราตองท าการยาย pointer ใหอยในต าแหนงทเหมาะสมดงทแสดงไวในภาพท 2.14 และ code ทตามมา

ภาพท 2.14 การน า node เขาส list ระหวาง node 2 node

else {

//set temp.next to current.next then

//set previous of node after current to temp

temp.setNext(current.getNext());

current.getNext().setPrevious(temp);

}

temp.setPrevious(current); //set temp.previous to current

current.setNext(temp); //set current.next to temp

เมอเรารวา current ชอยท node ตามทก าหนดไว เรากก าหนดให next ของ temp ชไปท node ทอยถดจาก current หลงจากนนกก าหนดให previous ของ node ทอยหลง current ช

ไปท temp กระบวนการหลงจากนนกเหมอนกนกบทท ากอนหนานคอ ก าหนดให previous ของ temp ชไปท current และก าหนดให next ของ current ชไปท temp 2.7.6 การน าขอมลเขาแบบจดเรยง ในการน าขอมลเขาโดยมการจดเรยงนน เราตองคนหาต าแหนงทเหมาะสมของขอมล ซงหลงจากทหาเจอแลว เรากตองตรวจสอบดวาต าแหนงทหาเจอนนอย ณ ต าแหนงใด ใน 3 กรณน (ยกเวนกรณท list ไมมขอมลใด ๆ อยเลย – เราเรยกใช insertFirst() ไดทนท)

o ต าแหนงทตองใสอยดานหนาของ list

List หลงจาการ insert ระหวาง node 2 node

null

null

789

previous

next

325

previous

next

first last

List กอนทจะมการ insert ระหวาง node 2 node

3 4 2 1

1. temp.setNext(current.getNext());

2. current.getNext().setPrevious(temp); 3. temp.setPrevious(current()); 4. current.setNext(temp);

null

null

789

previous

next

325

previous

next first

last

888

previous

next

temp

current

Page 24: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

56

o ต าแนงทตองใสอยทายสดของ list o ต าแหนงทตองใสอยระหวาง node เราใชตวแปร cur เปนตวเดนเขาหา list เพอหาต าแหนงทเหมาะสมในการน าขอมลเขา โดยกอนอนเราจะก าหนดให cur = first หลงจากนนเดนเขาหา list ดวยการใช loop //search for proper position to insert

DBLNode<T> cur = first;

T x = item; //for comparison

while(cur != null) {

//if item to insert is greater than item at current

//position, move cur forward

if(x.compareTo(cur.getData()) > 0)

cur = cur.getNext();

//stop moving cur if item is less than or equal to

//item at current position which can be either

//before first node or between 2 nodes

else

break;

//if we exit the loop with cur equals to null

//item must be larger than others in list

}

เราจะยตการท างานและออกจาก loop ถาขอมลทตองการน าเขานอยกวาขอมล ณ ต าแหนงท cur ชอย เพราะฉะนนถาเราหลดออกจาก loop ในขณะท cur = first แสดงวาเราจะตองน าขอมลเขาส list ทางดานหนา (แตกอนทเราจะน าขอมลเขาเราตองสราง node ใหมดวยขอมลนนกอน ดวยประโยค DBLNode<T> temp = new DBLNode<T>(item);

หลงจากนนเรากท าการเชอม node ใหมนเขากบ list ของเราดวยการช first ไปท temp (node

ใหม) พรอมทงก าหนดให field next ของ first ชไปท cur หลงจากนนกก าหนดให field previous ของ cur ชไปท temp ดง code ทเหนน (ดภาพท 2.15 ประกอบ) //insert before first node

if(cur == first) {

first = temp;

first.setNext(cur);

cur.setPrevious(temp);

}

Page 25: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

57

ภาพท 2.15 การน าขอมลเขาทางดานหนา

ในกรณท cur = null แสดงวาเราตองน าขอมลเขาทางทายสดของ list ซงท าไดงาย ๆ คอก าหนดให field next ของ last ชไปท temp พรอมกบก าหนดให field previous ของ temp ช

ไปท last หลงจากนนกก าหนดให last ชไปท temp ดงทแสดงไวในสวนของ code ทเหนน (ดภาพท 2.16 ประกอบ) //insert at last

else if(cur == null) {

last.setNext(temp);

temp.setPrevious(last);

last = temp;

}

temp

List กอนทจะมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

null

null

444

previous

next

789

previous

next

first last

234

previous

next null

null

3 2

1 null

null

444

previous

next

789

previous

next

first

last

temp

234

previous

next

List หลงจากทมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

cur

1. first = temp; 2. first.setNext(cur);

3. cur.setPrevious(temp);

Page 26: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

58

ภาพท 2.16 การน าขอมลเขาส List ทางดานหลง

กรณสดทายทเราตองน าขอมลเขากคอ กรณท cur ไมเทากบ first และไมเทากบ null ส าหรบการน าเขาขอมลทตองแทรกระหวาง node น เรารวา cur นนชอยท node หลง node ทตองการน าเขา (temp) เพราะฉะนนเรากก าหนดให field next ของ temp ชไปท cur และก าหนดให field next ของ node ทจะอยกอน temp ใหชไปท temp พรอมกบก าหนดให field previous ของ temp ชไปท node ทจะตองอยกอน temp หลงจากนนกก าหนดให field previous ของ

cur ชไปท temp ดงทแสดงไวใน code ทใหน (ดภาพท 2.17 ประกอบ) //insert between two nodes

else {

temp.setNext(cur);

cur.getPrevious().setNext(temp);

temp.setPrevious(cur.getPrevious());

cur.setPrevious(temp);

}

3

2

1

List หลงจากการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

temp

444

previous

next

789

previous

next

first

last

850

previous

next null

null

cur

null

1. last.setNext(temp); 2. temp.setPrevious(last); 3. last = temp;

List กอนทจะมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

null

444

previous

next

789

previous

next

first last

temp

null

850

previous

next null

null

Page 27: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

59

ภาพท 2.17 การน าขอมลเขาส list ระหวาง node

เราไดพดถงการน าขอมลเขาส list ในรปแบบของการจดเรยงเรยบรอยแลวทงสามกรณ ทงนก

ข นอยกบผอานวาจะเขยน code ในลกษณะใด สาเหตทพดเชนนกเพราะวา Doubly Linked-List ของเรานนม pointer อยสองตวคอ next และ previous ซงท าใหเราสามารถทจะเขาหา node ตาง ๆ ผานทาง pointer ทงสองตว ตวอยางเชน ในกรณของการน าขอมลเขาทางดานหนาของ list เราเรยกใชประโยค first = temp ตามดวย first.setNext(cur) ซงเราอาจเปลยนประโยคทสองใหเปน temp.setNext(cur) กได เพราะทง first และ temp มคาเทากน (ชไปทเดยวกน) ส าหรบ code ทงหมดของ insertInOrder() มดงน

1. temp.setNext(cur); 2. cur.getPrevious().setNext(temp);

3. temp.setPrevious(cur.getPrevious()); 4. cur.setPrevious(temp):

2 3 1 4

temp

List หลงจากทมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

null

444

previous

next

789

previous

next

first last

537

previous

next

null

cur

List กอนทจะมการโยกยาย pointer ใหมการเชอมตอกบ node ใหมทตองการ insert (temp)

null

444

previous

next

789

previous

next

first last

temp

null

537

previous

next null

null

Page 28: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

60

public void insertInOrder(T item) {

//list is empty just call insertFirst()

if(empty())

insertFirst(item);

else {

//search for proper position to insert

DBLNode<T> cur = first;

T x = item; //for comparison

while(cur != null) {

//if item to insert is greater than item at current

//position, move cur forward

if(x.compareTo(cur.getData()) > 0)

cur = cur.getNext();

//stop moving cur if item is less than or equal to

//item at current position which can be either

//before first node or between 2 nodes

else

break;

//if we exit the loop with cur equals to null

//item must be larger than others in list

}

DBLNode<T> temp = new DBLNode<T>(item);

//insert before first node

if(cur == first) {

first = temp;

first.setNext(cur);

cur.setPrevious(temp);

}

//insert at last

else if(cur == null) {

last.setNext(temp);

temp.setPrevious(last);

last = temp;

}

//insert between two nodes

else {

temp.setNext(cur);

cur.getPrevious().setNext(temp);

temp.setPrevious(cur.getPrevious());

cur.setPrevious(temp);

}

count++; //one more node added

}

}

โปรแกรมตอไปนทดสอบการน าขอมลเขาดวยการเรยกใช insertInOrder() และ insertAfter()

1: /**

2: Testing DoublyLinkedList

3: */

4:

5: class TestDoublyLinkedList {

6: public static void main(String[] args) {

7: DoublyLinkedList<Integer> list = new DoublyLinkedList<Integer>();

8: int[] num = {23, 45, 10, 89, 75, 99, 94, 34, 54, 5};

9:

10: //insert data in num[] to list

11: for(int i = 0; i < 10; i++) {

12: list.insertInOrder(num[i]);

13: list.displayForward();

14: }

15: //insert 77 after 34

16: list.insertAfter(34, 77);

17: list.displayForward();

18: }

19: }

ผลลพธทไดคอ first->{23}<-last

first->{23, 45}<-last

first->{10, 23, 45}<-last

Page 29: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

61

first->{10, 23, 45, 89}<-last

first->{10, 23, 45, 75, 89}<-last

first->{10, 23, 45, 75, 89, 99}<-last

first->{10, 23, 45, 75, 89, 94, 99}<-last

first->{10, 23, 34, 45, 75, 89, 94, 99}<-last

first->{10, 23, 34, 45, 54, 75, 89, 94, 99}<-last

first->{5, 10, 23, 34, 45, 54, 75, 89, 94, 99}<-last

first->{5, 10, 23, 34, 77, 45, 54, 75, 89, 94, 99}<-last

method อกสองตวทเรายงไมไดพดถงกคอ displayForward() และ displayBackward() ซงเปน method ส าหรบการแสดงขอมลทอยใน Linked-List ทงจากดานหนาไปยงดานหลง และจากดานหลงไปดานหนา code ของ method ทงสองกเขยนไมยาก ดงทจะแสดงใหดตอไปน

public void displayForward() {

if(empty())

System.out.println("Sorry - list is empty!");

else {

DBLNode<T> current = first;

System.out.print("first->{" + current.getData());

current = current.getNext();

while(current != null) {

System.out.print(", " + current.getData());

current = current.getNext();

}

System.out.println("}<-last");

}

}

public void displayBackward() {

if(empty())

System.out.println("Sorry - list is empty!");

else {

DBLNode<T> current = last;

System.out.print("last->{" + current.getData());

current = current.getPrevious();

while(current != null) {

System.out.print(", " + current.getData());

current = current.getPrevious();

}

System.out.println("}<-first");

}

}

ผอานควรทดสอบการท างานของ Doubly linked-List เพอท าความเขาใจกบสวนประกอบตาง ๆ ใหมากยงข น Code ทงหมดของ DoublyLinkedList.java

1: /**

2: Basic structure for Doubly LinkedList

3: */

4:

5: public class DoublyLinkedList<T extends Comparable<? super T>> {

6: private DBLNode<T> first; //points to first node

7: private DBLNode<T> last; //points to last node

8: private int count; //items in list

9:

10: //default constructor

11: public DoublyLinkedList() {

12: first = last = null;

13: count = 0;

14: }

15:

16: //empty when first == null or last == null

17: //either case is ok

18: public boolean empty() {

19: return first == null;

20: }

21:

22: //number of nodes in list

23: public int size() {

Page 30: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

62

24: return count;

25: }

26:

27: //insert at front of list

28: public void insertFirst(T item) {

29: DBLNode<T> temp = new DBLNode<T>(item);

30: if(empty()) //empty

31: last = temp; //last points at temp

32: else

33: first.setPrevious(temp); //set previous to temp

34: temp.setNext(first); //set temp.next to first

35: first = temp; //set first to temp

36: count++; //one more node added

37: }

38:

39: //insert at where last is

40: public void insertLast(T item) {

41: DBLNode<T> temp = new DBLNode<T>(item);

42: if(empty()) //empty

43: first = temp; //set first to temp

44: else {

45: last.setNext(temp); //set last.next to temp

46: temp.setPrevious(last); //set temp.previous to last

47: }

48: last = temp; //set last to temp

49: count++; //one more node added

50: }

51:

52: //insert after given key value

53: public void insertAfter(T key, T obj) {

54: boolean noItem = false;

55: //serching for key if found -> noItem = false

56: //if not found -> noItem = true

57: DBLNode<T> current = first;

58: while(current != null) {

59: if(current.getData().equals(key))

60: break;

61: current = current.getNext();

62: }

63: noItem = (current == null) ? true : false;

64:

65: if(noItem)

66: System.out.println("Sorry - given key doesn't exist!");

67: else {

68: DBLNode<T> temp = new DBLNode<T>(obj);//get new node

69: if(current == last) { //if this is the last node

70: last = temp; //set last to temp

71: }

72: else {

73: //set temp.next to current.next then

74: //set previous of node after current to temp

75: temp.setNext(current.getNext());

76: current.getNext().setPrevious(temp);

77: }

78: temp.setPrevious(current); //set temp.previous to current

79: current.setNext(temp); //set current.next to temp

80: }

81: }

82:

83: //inorder insertion (ascending)

84: public void insertInOrder(T item) {

85: //list is empty just call insertFirst()

86: if(empty())

87: insertFirst(item);

88: else {

89: //search for proper position to insert

90: DBLNode<T> cur = first;

91: T x = item; //for comparison

92: while(cur != null) {

93: //if item to insert is greater than item at current

94: //position, move cur forward

95: if(x.compareTo(cur.getData()) > 0)

96: cur = cur.getNext();

97: //stop moving cur if item is less than or equal to

Page 31: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

63

98: //item at current position which can be either

99: //before first node or between 2 nodes

100: else

101: break;

102: //if we exit the loop with cur equals to null

103: //item must be larger than others in list

104: }

105: DBLNode<T> temp = new DBLNode<T>(item);

106: //insert before first node

107: if(cur == first) {

108: first = temp;

109: first.setNext(cur);

110: cur.setPrevious(temp);

111: }

112: //insert at last

113: else if(cur == null) {

114: last.setNext(temp);

115: temp.setPrevious(last);

116: last = temp;

117: }

118: //insert between two nodes

119: else {

120: temp.setNext(cur);

121: cur.getPrevious().setNext(temp);

122: temp.setPrevious(cur.getPrevious());

123: cur.setPrevious(temp);

124: }

125: count++; //one more node added

126: }

127: }

128:

129: //remove from front

130: public T removeFirst() {

131: DBLNode<T> temp = first; //set temp to first

132: if(first.getNext() == null) //basically empty

133: last = null;

134: else

135: //set previous of node after first to null

136: first.getNext().setPrevious(null);

137: first = first.getNext(); //set first to that node

138: count--;

139: return temp.getData();

140: }

141:

142: //remove at last

143: public T removeLast() {

144: DBLNode<T> temp = last; //set temp to last

145: if(first.getNext() == null) //empty

146: first = null;

147: else

148: //set next of node before last to null

149: last.getPrevious().setNext(null);

150: last = last.getPrevious(); //set last to that node

151: count--;

152: return temp.getData();

153: }

154:

155:

156: public void displayForward() {

157: if(empty())

158: System.out.println("Sorry - list is empty!");

159: else {

160: DBLNode<T> current = first;

161: System.out.print("first->{" + current.getData());

162: current = current.getNext();

163: while(current != null) {

164: System.out.print(", " + current.getData());

165: current = current.getNext();

166: }

167: System.out.println("}<-last");

168: }

169: }

170:

171: public void displayBackward() {

Page 32: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

64

172: if(empty())

173: System.out.println("Sorry - list is empty!");

174: else {

175: DBLNode current = last;

176: System.out.print("last->{" + current.getData());

177: current = current.getPrevious();

178: while(current != null) {

179: System.out.print(", " + current.getData());

180: current = current.getPrevious();

181: }

182: System.out.println("}<-first");

183: }

184: }

185:

186: //search for given object

187: public boolean search(T key) {

188: DBLNode<T> temp = null;

189: if(empty()){

190: System.err.println("ERROR! List is empty.");

191: System.exit(1);

192: }

193: else {

194: temp = first;

195: while(temp != null) {

196: if(temp.getData().equals(key))

197: break;

198: temp = temp.getNext();

199: }

200: }

201: return (temp == null) ? false : true;

202: }

203: }

2.8 การใช class LinkedList ท Java มให

ในการท างานบางครงเราอาจตองใชโครงสรางทไดถกออกแบบไวแลวจากผเขยนภาษาทางดานการโปรแกรม เนองจากสาเหตอะไรกตามแต (เชน ขเกยจเขยนใหม เปนตน) เชนการจดเกบขอมลดวย Linked-List ดงเชนทเราไดท ามาแลวกอนหนาน Java ม class LinkedList ทเราสามารถเรยกใชได ดงตวอยางการใชทเหนน เราจะเรยกใช method บางตวดงน add(Object o) น า Object o เขาส LinkedList ทางดานหลง

addFirst(Object o) น า Object o เขาส LinkedList ทางดานหนา addLast(Object o) น า Object o เขาส LinkedList ทางดานหลง removeFirst() ดง Object o ออกจาก LinkedList ทางดานหนา removeLast() ดง Object o ออกจาก LinkedList ทางดานหลง

remove(index i) ดง Object ออกจาก LinkedList ท index i set(index i, Object O) ก าหนดให Object ท index i มคาเปน Object O

โปรแกรมตวอยางทเหนท าการสราง myList จาก LinkedList โดยก าหนดใหมขอมลแบบ random อย 10 ตว ดวยการใช add() หลงจากนนกเพมขอมลอกสองตวดวย addFirst() และ addLast() และเมอท าการแสดงผลเสรจแลวเรากลบขอมลออกสามตวดวย removeFirst(), removeLast(), และ remove()

1: /**

2: Testing LinkedList class from Java

3: */

4:

5: import java.util.LinkedList;

6:

7: public class TestJavaLinkedList {

8: public static void main(String[] args) {

9: //create an empty LinkedList

10: LinkedList<Integer> myList = new LinkedList<Integer>();

11: //populate LinkedList with random numbers

12: for(int i = 0; i < 10; i++) {

13: int num = (int)(Math.random() * 100 + 1);

14: myList.add(num);

15: }

16: System.out.println("Content: ");

17: print(myList);

Page 33: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

65

18:

19: //add 55 to front of LinkedList

20: myList.addFirst(55);

21: //add 99 to end of LinkedList

22: myList.addLast(new Integer(99));

23: System.out.println("Content after added 55 and 99: ");

24: print(myList);

25:

26: //remove first item in LinkedList

27: myList.removeFirst();

28: //remove last item in LinkedList

29: myList.removeLast();

30: System.out.println("Content after removed first and last: ");

31: print(myList);

32:

33: //remove second item from last

34: myList.remove(myList.size() - 2);

35: System.out.println("Content after removed second item from last: ");

36: print(myList);

37:

38: //set first item to 111

39: myList.set(0, new Integer(111));

40: System.out.println("Content after replaced first item to 111: ");

41: print(myList);

42: }

43:

44: //print items in list

45: public static void print(LinkedList<Integer> list) {

46: if(list.size() == 0) {

47: System.err.println("List is empty!");

48: return;

49: }

50: Integer item = list.get(0);

51: System.out.print("(" + item);

52: for(int i = 1; i < list.size(); i++) {

53: item = list.get(i);

54: System.out.print(", " + item);

55: }

56: System.out.println(")");

57: }

58: }

ผลลพธทไดจากการ run โปรแกรม LinkedListTest.java คอ Content:

(76, 79, 19, 89, 39, 10, 75, 17, 76, 59)

Content after added 55 and 99:

(55, 76, 79, 19, 89, 39, 10, 75, 17, 76, 59, 99)

Content after removed first and last:

(76, 79, 19, 89, 39, 10, 75, 17, 76, 59)

Content after removed second item from last:

(76, 79, 19, 89, 39, 10, 75, 17, 59)

Content after replaced first item to 111:

(111, 79, 19, 89, 39, 10, 75, 17, 59)

ยงม method อกหลายตวใน class LinkedList ทมากบ Java ทงนจะทงไวใหผอานไดท าการตรวจสอบการใช method เหลานนดวยตวเอง

Page 34: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

66

สรป เราไดพดถงโครงสรางหลกของ node ทใชในการสราง linked-list ตงแต list ทางเดยว list ทม pointer คอยจ าต าแหนงของ node สดทาย รวมไปถงการออกแบบและใชงาน Doubly Linked-List เราไดพดถงการน าขอมลเขา การดงขอมลออก การแสดงขอมลทมอยใน list และตวอยางการใชงานในรปแบบตาง ๆ โดยสรปแลวเราไดพดถง การออกแบบ node ของ Linked-List ทางเดยว การออกแบบโครงสรางของ Linked-List ทางเดยว การน าขอมลเขา (insert) และการน าขอมลออก (remove) การออกแบบและใชงาน Double-Ended Linked-List ทม pointer 2 ตวทช ไปยง node

แรก และ node สดทาย

การออกแบบ node ของ Doubly Linked-List การออกแบบโครงสรางของ Doubly Linked-List การน าขอมลเขา และออกจาก Doubly Linked-List ตวอยางการใชงานของ Linked-List ในรปแบบตาง ๆ ตวอยางการใช method ตาง ๆ บางตวจาก class LinkedList ท Java มให แบบฝกหด

1. จงเขยนโปรแกรมทท าหนาทสลบขอมล (node) ทกตวทมอยใน linked-list จากดานหนา

ไปดานหลง 2. จงเขยน method ทสงคา true ใหผเรยกถาขอมลทอยใน linked-list ไดถกจดเรยงไวจาก

นอยไปหามาก และสงคา false ถาไมไดถกจดเรยงไว 3. จงเขยน method ทน าขอมลเขาส linked-list (list ทางเดยว) แบบม order (จากนอยไปหา

มาก) ใหเขยนโปรแกรมทดสอบ 4. จาก concept เดยวกนกบ circular array จงเขยนโปรแกรมทใช circular list ในการจดเกบ

ขอมล 5. จากขอ 4 จงเขยน method ท remove node ออกจาก circular list 6. จงเขยน method ทหาจ านวนของ node ทมอยใน circular list (ทสรางข นในขอ 4) 7. จากขอ 6 ใหเขยน method ทท าการคนหา node ทมขอมลนอยทสด 8. จงเขยน method ทคนหาขอมล ใน list ทางเดยวทมการจดเกบแบบเรยงล าดบจากนอยไป

หามากดวย binary search 9. จงเขยน method ทหา node จากต าแหนงของ node ทก าหนดให ใน circular list เชน ถา

ก าหนดใหต าแหนงของ node เปน 8 method นจะสงคาของ node ณ ต าแหนงท 9 (ต าแหนงถดไป - วนกลบ) ไปใหผเรยก ใหเขยนโปรแกรมทดสอบ

10. จงเขยน method ท insert node ระหวาง node ทก าหนดให 2 node ของ ordered

circular list 11. จงเขยน method ท display ขอมลของ circular list จากดานหลงไปดานหนา 12. จงเขยน method ท display ขอมลของ circular list เฉพาะ node ทอยในต าแหนงค

เทานน 13. จงเขยนโปรแกรมทใชโครงสรางของ Doubly Linked-List ในการบวกเลขทมจ านวนหลก

มาก ๆ เชน 20 – 30 หลกโดยใหแตละ node ของ Doubly Linked-List นนเกบตวเลขเพยงหนงตว (digit เดยว)

Page 35: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

บทท 2 Linked-List

67

14. จากขอก าหนดในขอ 13 จงเขยน method ทท าหนาทลบเลข 2 ตว 15. จาก Linked-List ทางเดยวทเราเขยนขน จงเพม method ส าหรบการดงขอมลออกจากทาง

ดานหนาของ list และ method ทดงขอมลออกจากทางดานหลง พรอมทงเขยนโปรแกรมทดสอบ

16. Java ม method toArray() ใน class LinkedList จงเขยน method ทท าหนาทในลกษณะ

เดยวกนใหกบ class LinkedList ทเราไดเขยนขนในบทน ใหเขยนโปรแกรมทดสอบ method ดงกลาว

17. จงเขยน method ทท าการยายขอมลทมคามากทสดใน list ไปยง node สดทายของ list

18. จงออกแบบโครงสรางของ Linked-List ทม node แรกสดไวเกบจ านวนของ node ทงหมดทมอยใน Linked-List สวนการน าขอมลเขาใหเรมจาก node ถดไป ถาไมมขอมลอยเลย คาของ node จะเปนศนย ใหเขยนโปรแกรมทดสอบ

19. จงเขยน method ทลบ node หลงจาก node ทก าหนดให เชน ถา node ทก าหนดใหมคา

เทากบ 13 node ทจะถกลบคอ node ทอยถดไปจาก node 13 และหากวา node 13 เปน node สดทายใน list กไมตองท าอะไร

20. จากขอ 19 ถา node นนเปน node สดทาย ใหท าการลบออกทนท 21. จงออกแบบ Doubly-Linked-List ทเปน Circular List โดยก าหนดให field next ของ

node สดทายชไปท node แรกและ field previous ของ node แรกชไปท node สดทาย ดงภาพ

first

Page 36: เป็นโครงสรา้งที่ใชใ้นการจัดเก็บขอ้มูลอีกรูปแบบหนงึ่ที่มก ...sci.feu.ac.th/faa/dsa/bookPDFs/chap2-LinkedList.pdf ·

Linked-List บทท 2

68