You are on page 1of 21

44

บทที่ 3
โครงสร้ างข้อมูลลิงค์ลิสต์ (Link List)

ในการประมวลผลข้อมู ลบ่ อยครั้ง จะมี การท างานที่ เกี่ย วข้องกับ การจัด เก็บ ข้อมู ลและ
ประมวลผลข้อมู ลที่จัด เก็บ อยู่ ในลิ สต์ ซึ่ งวิ ธีการเก็ บ ข้อมู ลแบบลิ สต์วิ ธีการหนึ่ งคื อ จัด เก็ บ ใน
ลักษณะของอาร์เรย์ที่ได้กล่าวมาแล้วในบทที่ 2 โดยโครงสร้างข้อมูลในอาร์เรย์ จะเป็ นตาแหน่งที่
ต่อเนื่องกันของข้อมูลในหน่วยความจา ไม่ข้ นึ อยู่กับข้อมูลที่เก็บ ซึ่งเราสามารถคานวณหาตาแหน่ ง
ของข้อมู ลต่างๆในอาร์เรย์ได้ง่าย แต่อาร์ เรย์ก็มีขอ้ เสี ยบางประการ เช่นต้องเสี ยเวลามากในกรณี
ของการเพิ่ม หรื อลบอิ ลิเมนต์ออกจากอาร์ เรย์ โดยแสดงตัวอย่างดังรู ป ที่ 3.1 และ 3.2 อีกประการ
หนึ่ งอาร์เรย์มีการใช้พ้ืนที่ของหน่ วยความจาส่ วนหนึ่ งคงที่แน่ นอน เราไม่สามารถขยายพื้นที่ของ
อาร์เรย์ได้เมื่อต้องการ หรื อในทางตรงกันข้าม หากมีการนาข้อมูลเข้าสู่ อาร์เรย์จานวนน้อยกว่าที่เรา
จัดสรรเนื้อที่ในการเก็บข้อมูล ก็จะทาให้เสี ยเนื้อที่หน่วยความจาโดยไม่มีประโยชน์ ด้วยเหตุผลดังนี้
จึงเรี ยกโครงสร้างข้อมูลแบบอาร์เรย์ว่า โครงสร้างข้อมูลแบบสแตติก(Static Data Structure)

1) หาตาแหน่งที่ตอ้ งการเพิ่มข้อมูล

10 20 40 50 ...

30

2) จัดเตรี ยมเนื้อที่ว่าง

10 20 40 50 ...

30

3) เพิม่ ข้อมูลเข้าไปในอาร์เรย์

10 20 30 40 50 ...

รูปที่ 3.1 แสดงการเพิ่มข้ อมูลเข้ าไปในอาร์ เรย์


45

1) หาตาแหน่งที่ตอ้ งการลบข้อมูล

10 20 30 40 50 ...

2) มีเนื้อที่ว่าง

20

10 30 40 50 ...

3) หลังจากลบข้อมูลในอาร์เรย์

10 30 40 50 ...

รูปที่ 3.2 แสดงการลบข้ อมูลออกจากอาร์ เรย์

1. โครงสร้ างข้อมูลลิงค์ลิสต์ (Link List)


จากข้อเสี ยของการจัดเก็บข้อมูลแบบอาร์เรย์ ในภาวะการทางานแบบนี้โครงสร้างแบบลิงค์
ลิสต์จะสะดวกกว่า การเก็บข้อมูลโดยใช้ลิงค์ลิสต์น้ ีเราต้องใช้พ้นื ที่เพิ่มเติมอีกส่ วนหนึ่ง เป็ นส่ วน
ของพอยน์เตอร์ (pointer) เพื่อแสดงให้เห็นว่าโหนดทีต่ ่อจากโหนดนั้นคือโหนดใด ลักษณะของแต่
ละโหนดจึงประกอบด้วยช่อง 2 ช่อง โดยใช้อิลิเมนต์ที่มีฟิลด์สาหรับชี้ตาแหน่งของอิลิเมนต์ต่อไป
ซึ่งเรี ยกว่า ลิงค์ หรื อพอยน์เตอร์ (link or pointer) วิธีน้ ีจะไม่ใช้พ้นื ที่ของหน่วยความจาที่อยู่ติดกัน
ทาให้ง่ายต่อการเพิ่มหรื อลบอิลิเมนต์ในลิสต์ หากต้องการค้นหาข้อมูลเพื่อทาการแทรก หรื อลบ
เช่น ในโปรแกรมการพิมพ์เอกสาร เราจะไม่เก็บข้อมูลในอาร์เรย์ แต่จะเก็บในลักษณะของพอยน์
เตอร์ ซึ่งเรี ยกว่า “Link List” อย่างไรก็ดี ในบางครั้งก็ให้ความยุ่งยากแก่ผใู ้ ช้เนื่องจากจะซับซ้อน
กว่าการใช้โครงสร้างข้อมูลแบบอาร์เรย์ โดยข้อจากัดของการใช้อาร์เรย์คืออาร์เรย์มีขนาดคงที่ ถ้าเรา
46

จะใช้อาร์เรย์ขนาด 100 ช่อง เมื่อใช้หมด 100 ช่องก็ใช้อาร์เรย์น้ นั ไม่ได้ ถ้าไม่อนุญาตให้เคลียร์พ้นื ที่


อาร์เรย์เพื่อใช้ซ้ าถึงแม้อนุญาตให้เคลียร์พ้นื ที่อาร์เรย์เพื่อใช้ซ้ าก็ไม่เป็ นการสะดวก เนื่องจากอาจต้อง
ตรวจทุกช่องในอาร์เรย์เพื่อหาว่าช่องไหนสามารถใช้ซ้ าได้ นอกจากนี้การใช้พ้นื ที่ซ้ ายังต้องเลื่อน
ข้อมูลทั้งหมดไปอยู่ในส่ วนอาร์เรย์ อีกประการคือในภาวะการทางานแบบ real - time ที่ตอ้ งมีการ
นาข้อมูลเข้า (insertion) หรื อดึงข้อมูลออก (deletion) การใช้โครงสร้างข้อมูลแบบอาร์เรย์จึงไม่
สะดวกแก่การใช้งานเป็ นอย่างมาก

2. ตัวแปรชนิดพอยเตอร์ (Pointer Variable)


ตัวแปรชนิดพอยเตอร์ เป็ นตัวแปรที่ค่าของมันจะชี้หรื ออ้างถึงตาแหน่งของหน่วยความจา
(Memory Address) ซึ่งจะมีความแตกต่างจากตัวแปรพื้นฐาน เช่นตัวแปรจานวนเต็ม จานวนจริ ง
บูลลีน ฯลฯ หรื อชนิดโครงสร้าง เช่น อาร์เรย์ ฯลฯ ในการใช้ตวั แปรแบบพอยเตอร์ในภาษา C จะมี
รู ปแบบในการประกาศดังนี้ เช่น

int *pt ;

จากการประกาศจะเห็นว่า pt เป็ นตัวแปรพอยเตอร์ โดยในการประกาศต้องมีเครื่ องหมาย *


หน้าตัวแปร ซึ่งตัวแปร pt เป็ นตัวแปรที่ช้ ีไปยังหน่วยความจาที่เก็บข้อมูลชนิดจานวนเต็ม ซึ่งใน
การประมวลผลเราสามารถสร้างหน่วยความจาที่ใช้เก็บพอยเตอร์ได้ดงั นี้
500
pt 500

เมื่อประมวลผลคาสั่ง *pt = 10 ;
จะเกิดการจัดเก็บข้อมูลดังภาพ
500
pt 500 10

จากการทางานของตัวแปรแบบพอยเตอร์ จะเห็นว่าพอยเตอร์ไม่ได้ทาการเก็บค่าที่กาหนด
โดยตรงแต่จะใช้วิธีเก็บตัวชี้ ที่ใช้ช้ ี ไปยังหน่ วยความจาที่กาหนดค่าให้ ซึ่งเป็ นไปในลักษณะการ
กาหนดค่าให้โดยอ้อม
47

3. การแทนโครงสร้ างข้อมูลลิงค์ลิสต์
โครงสร้ างข้อมู ลแบบลิ งค์ลิ ส ต์เป็ นโครงสร้ างข้อ มู ล แบบรายการเชิ งเส้ น ที่ มี ลักษณะ
แตกต่างจากโครงสร้างข้อมู ลแบบรายการเชิ งเส้นที่ ผ่านมา เนื่ องจากการด าเนิ นการเพิ่ มหรื อลบ
ข้อมูลในโครงสร้างสามารถกระทาที่ขอ้ มูลตรงตาแหน่ งใด ๆ ในโครงสร้างก็ได้ ดังนั้นลักษณะ
ของโครงสร้างจึงมีความยืดหยุ่นกว่าและไม่มีขีดจากัดความจุของข้อมูลในโครงสร้าง เนื่องจากมี
การเรี ยกใช้ ห น่ วยความจ าแบบพลวั ต (Dynamic Memory Allocation) แต่ ข้ ั น ตอนในการ
ดาเนินการกับโครงสร้างจะมีความยุ่งยากซับซ้อนมากกว่า
นอกจากนี้ ข้อมู ลในโครงสร้ างไม่ จาเป็ นต้องอยู่ ในตาแหน่ งที่เก็บ ข้อมู ลแบบเรี ย งต่อกัน
แต่ใช้ หลักการของการเชื่อมโยงข้อมูลที่อยู่คนละที่ให้รวมเป็ นกลุ่มข้อมูลเดียวกันการแทน แบบ
ใช้พอยน์เตอร์ น้ ี ต้องมีพ้ืนที่เพิ่มเติมเป็ นส่ วนพอยน์เตอร์ (pointer) หรื อลิงค์ (link) เพื่อแสดงให้
เห็นชัดว่าโหนดที่ต่อจากโหนดนั้นคือโหนดใด ลักษณะของแต่ละโหนดจึงประกอบด้วยช่อง 2 ช่อง
ดังรู ปที่ 3.3
DATA LINK

รูปที่ 3.3 แสดงส่ วนประกอบของโหนดในลิงค์ลิสต์

ข้อมูลที่สามารถจัดเก็บในเขตข้อมูล Data อาจจะเป็ นจานวนเต็ม(int) จานวนจริ ง (Real)


ตัวอักษร (character) หรื อ เรคคอร์ด (Record)

ตัวอย่างที่ 3.1 แสดงข้อมูลรายชื่อนักศึกษาโดยใช้ภาษาซี


struct datatype
{
char stuName[25];
int stuID;
float GPA;
char address;
};
48

ลักษณะโครงสร้างข้อมูลลิงค์ลิสต์ที่ประกอบด้วยโหนดหลายๆโหนดเชื่อมต่อกันสามารถดังรู ป ที่
3.4

Header D1 D2 D3 D4 NULL

รูปที่ 3.4 แสดงการเชื่ อมโยงโหนดในลิงค์ ลสิ ต์

จากรู ปที่ 3.4 พอยน์เตอร์ Header จะเป็ นตัวแปรที่ทาหน้าที่เก็บตาแหน่งที่อยู่ของโหนดแรก


ในโครงสร้าง และในส่วนของ LINK ของโหนดสุ ดท้ายจะเก็บค่า NULL เป็ นการแสดงถึงจุดสิ้ นสุ ด
ของรายการ ข้อมูลในโครงสร้างนี้ ณ ขณะนั้น ซึ่งอาจมีการเพิ่มหรื อลบข้อมูลในโครงสร้างได้อีก
โดยที่ไม่กระทบต่อข้อมูลตัวอื่น ๆ และสามารถเขียนแทนจุดสิ้ นสุ ดรายการข้อมูลในโครงสร้างด้วย
สัญลักษณ์ต่าง ๆ ดังรู ปที่ 3.5

D1 0 D1 -1 D1 NULL

รูปที่ 3. 5 แสดงรู ปโหนดสุ ดท้ ายที่จะเก็บค่ า NULL

* ถ้าในลิงค์ลิสต์ ไม่มีรายการของโหนดใด ๆ อยู่เลยจะหมายถึงโครงสร้างว่างเปล่า (Empty


List) และเขียนแทนสถานภาพดังกล่าวได้ดว้ ย START = NULL (START คือ ตาแหน่งที่อยู่ของ
สมาชิกตัวแรกในโครงสร้าง)
49

ตัวอย่างที่ 3.2 จงแสดงลาดับของข้อมูลในลิงค์ลิสต์ดว้ ยโครงสร้างอาร์เรย์


วิธีทา การใช้อาร์เรย์เป็ นโครงสร้างสาหรับเก็บข้อมูลลิงค์ลิสต์น้ นั จะต้องสร้างอาร์เรย์เพิ่มขึ้นอีก
1 ชุด

start 6

Item Name Next


1 Ying 7
2
3 Yee 11
4 Yaa 12
5
6 Ple 3
7 Pop 4
8 Kee 1
9 Keff 0 จุดสิ้นสุดรายการข้อมูล
10
11 Ben 8
12 Dome 9

รูปที่ 3.6 แสดงลิงค์ลิสต์ข้อมูลด้ วยอาร์ เรย์

จากโครงสร้างในรู ปที่ 3.6 แสดงลาดับของข้อมูลได้ดงั นี้ Ple , Yee , Ben , Kee , Ying ,
Pop , Yaa , Dome และ Keff แต่การแทนข้อมูลในลักษณะนี้มีขอ้ จากัดที่ตวั โครงสร้าง กล่าวคือ
จากัดจานวนของสมาชิกไว้เท่ากับขนาดของอาร์เรย์
การแทนลิงค์ลิสต์อีกวิธีหนึ่ง คือการประกาศจองหน่วยความจาเป็ นเรคอร์ด ซึ่งประกอบ
ด้วยส่วนที่เป็ นข้อมูล และส่วนที่เป็ นพอยน์เตอร์
50

START
Ple Yee Ben Kee

Ying Pop Yaa Dome

Keff NULL

รูปที่ 3.7 แสดงรายการเชื่ อมโยงโหนด

4. การเข้าถึงข้อมูลในโครงสร้ างข้อมูลลิงค์ ลิสต์


การเข้าถึงข้อมู ลในโครงสร้างลิ งค์ลิส ต์ จะต้องอาศัย พอยน์ เตอร์ เป็ นตัว ท่ องเข้าไปใน
โครงสร้าง ถ้าสมมติให้พอยน์เตอร์ดงั กล่าวคือ pt และทาหน้าที่ช้ ีตาแหน่งแอดเดรสของโหนดใน
โครงสร้ างแล้ว เมื่ อต้องการไปยังโหนดถัด ไปก็ ใ ห้ ท าการเลื่ อนต าแหน่ งของพอยน์ เตอร์ โดย
ตาแหน่งของโหนดถัดไปพิจารณาจากส่ วนของ LINK ในโหนดปัจจุบนั ดังแสดงในรู ป 3.8

pt

… DATA 4 DATA 5 DATA 6 DATA 7 DATA 8 NULL

หลังการเลื่อนไปข้อมูลตัวถัดไป
ก่อนการเลื่อนไปข้อมูลตัวถัดไป

รูปที่ 3.8 แสดงการเปลี่ยนพอยน์ เตอร์ เพือ่ ไปยังโหนดถัดไป pt=link[pt]

การเข้าถึงข้อมูลในโครงสร้างเรี ยกว่า การทา Traversing หมายถึง การท่องเข้าไปยังโหนด


ข้อมูลทุก ๆ โหนดตลอดโครงสร้าง ซึ่งอาศัยพอยน์เตอร์เป็ นตัวดาเนินการชี้ตาแหน่งของข้อมูลใน
โครงสร้าง
51

5. การดาเนินการกับโครงสร้ างข้อมูลลิงค์ลิสต์
5.1 การสร้ างโหนดและกาหนดโครงสร้ าง
การสร้างโหนด คือ การเตรี ยมโครงสร้างระเบียบสาหรับจัดเก็บข้อมูล เช่น ถ้าต้องการ
จัดเก็บข้อมูลจานวนเต็ม โครงสร้างของโหนดจะมีลกั ษณะดังรู ปที่ 3.9

ลั ก ษณ ะของโหนด

DATA LINK

ส่ วนที่ เ ก็ บ ข้ อ มู ล ส่ วนที่ เ ก็ บ ตำ แหน่ งที่ อ ยู่ ข องโหนดถั ด ไป

รูปที่ 3.9 แสดงโครงสร้ างของโหนดสาหรับเก็บข้ อมูลจานวนเต็ม

เมื่อกาหนดโครงสร้างของโหนดแล้ว ก็สามารถกาหนดพอยน์เตอร์ และเขียนส่ วนของ


โปรแกรมแสดงการกาหนดโครงสร้างด้วยภาษาซี ดังนี้

ตัวอย่างที่ 3.2 แสดงส่วนของโปรแกรมเพื่อกาหนดโครงสร้างโหนดด้วยภาษาซี


int *a, *b; /* ตัวแปร a และ b เป็ นตัวแปร พอยเตอร์ */
a = new int; /* สร้างหน่วยความจาเก็บข้อมูลเพื่อเตรี ยมเก็บค่าชนิดจานวนเต็ม
โดยเข้าถึงได้โดยพอยเตอร์ เท่านั้น */
*a = 9; /* นาค่า 9 ไปเก็บยังหน่วยความจา ที่ช้ ดี ว้ ยพอยเตอร์ a */
a = b; /* พอยเตอร์ a และ b ชี้ไปที่หน่วยความจาที่เก็บค่า 9 */

5.2 หน่วยความจาว่าง (Storage Pool)


Storage Pool หรื อ Free List หมายถึง เนื้อที่ว่างในหน่วยความจา จานวนหนึ่งมีลกั ษณะ
เป็ นโหนดเก็บอยู่ในโครงสร้างข้อมูลลิงค์ลิสต์ หรื ออาจเรี ยกได้ว่าเป็ น Free Stack ทั้งนี้เพราะ
ลักษณะการเรี ยกใช้ Storage Pool เหมือนกับการดาเนินการกับโครงสร้างข้อมูลสแตกกล่าวคือ ทุก
ครั้งที่มีการเพิ่มสมาชิกใหม่ในโครงสร้างข้อมูลลิงค์ลิสต์ชุดหนึ่งจะต้องดึงเอาโหนดว่าง 1 โหนด
ออกมาจาก Storage Pool ดังกล่าวและโหนดว่างนั้นจะต้องเป็ นโหนดแรกใน Storage Pool ด้วย
จากนั้นจึงใส่ ค่าข้อมูลลงไปในส่วนของ Data Field ของโหนดนี้ หลังจากนั้นจึงจะนาโหนดดังกล่าว
เชื่อมโยงเข้าไปไว้ในโครงสร้างข้อมูลที่ตอ้ งการ ในทานองเดียวกันทุกครั้งที่มีการลบสมาชิกตัวใด
52

ตัวหนึ่งออกจากโครงสร้างข้อมูล จะต้องนาโหนดที่ถูกลบนี้ ใส่ คืนใน Storage Pool ไว้เป็ นโหนด


แรกใน Storage Pool เสมอ สามารถแสดงการดึงโหนดจากโครงสร้างของ Storage Pool ได้ดงั รู ปที่
3.10

START
p q

DATA 1 DATA 2 DATA 3 DATA 4 DATA 5 NULL

()
AVAIL

NULL
Storage Pool
()

เส้นที่แสดงรายการเชื่อมโยงเดิม
AVAIL คือ พอยน์เตอร์ ตาแหน่งของโหนดแรกใน Storage Pool
p คือ พอยน์เตอร์ที่ช้ ีโหนดก่อนโหนดที่จะเพิ่มเข้ามาใหม่
q คือ พอยน์เตอร์ที่ช้ ีโหนดหลังโหนดที่จะเพิ่มเข้ามาใหม่

รูปที่ 3.10 แสดงโครงสร้ างลิงค์ ลิสต์ ของ Storage Pool


53

Storage Pool : โหนดทีว่ ่าง (ยังไม่ได้นามาใช้งาน)

NULL
AVAIL NEW Node(Get Node)
Step(1) : NEW AVAIL
NULL
AVAIL NEW
Step(2) : Avail Link(Avail)
NULL
Step(3): Link(NEW) NULL AVAIL
NULL NULL
NEW
AVAIL

รูปที่ 3.11 แสดงขั้นตอนการขอโหนดใหม่ จาก Storage Pool

5.3 การเพิ่มข้อมูลในโครงสร้ างข้ อมูลลิงค์ลิสต์


เมื่อกาหนดโครงสร้างข้อมูลเป็ นที่เรี ยบร้อยแล้วก็สามารถทาการเพิ่มข้อมูลในโครงสร้าง
ได้โดยการขอโหนดว่างจาก Storage Pool และนามาเชื่อมโยงกับรายการข้อมูลที่มีอยู่เดิมใน
โครงสร้างตรงตาแหน่งที่ตอ้ งการ ดังแสดงด้วยแผนภาพในรู ปที่ 3.12
START

NULL

NEW NEW Storage Pool

รูปที่ 3.12 แสดงการเพิ่มโหนดใหม่ ในโครงสร้ างข้ อมูลรายการเชื่ อมโยง


54

การเพิ่มข้อมูลในโครงสร้างสร้างข้อมูลรายการเชื่อมโยง อาจเกิดในลักษณะต่างกัน ซึ่งพอ


สรุ ปได้เป็ น 3 ลักษณะ ได้แก่
1. การเพิม่ ข้อมูลที่จุดเริ่ มต้นของโครงสร้าง
2. การเพิ่มข้อมูลต่อจากโหนดที่กาหนด
3. การเพิ่มข้อมูลเป็ นโหนดสุ ดท้ายของโครงสร้าง

5.3.1 การเพิ่มข้อมูลที่จุดเริ่มต้ นของโครงสร้ าง

START

NULL

NEW NEW Storage Pool

รูปที่ 3.13 แสดงการเพิ่มข้ อมูลที่จุดเริ่มต้ นของโครงสร้ าง

ขั้นตอนการเพิ่มข้อมูลในโครงสร้ างรายการเชื่ อมโยง


Algorithm INSFIRST (DATA , LINK , START , AVAIL) ขั้นตอนนี้เป็ นการเพิ่มข้อมูลที่
ตาแหน่งเริ่ มต้นของโครงสร้าง
1. [ตรวจสอบพื้นที่ว่าง]
If AVAIL = NULL then
Write (“Overflow”)
Return
2. [ขอโหนดแรกมาจาก Storage Pool]
Set NEW = AVAIL
AVAIL = LINK [AVAIL]
3. [นาข้อมูลเข้าไปในโหนดใหม่]
Set DATA[NEW] = ITEM
55

4. [กาหนดโหนดใหม่เป็ นโหนดเริ่ มต้น]


Set LINK[NEW] = START
5. [เปลี่ยนจุดเริ่ มต้นไปที่โหนดทีเ่ พิม่ มาใหม่]
Set START = NEW
6. Exit

5.3.2 การเพิ่มข้อมูลต่อจากโหนดทีก่ าหนด


สมมติให้ PT คือ พอยน์เตอร์ที่ช้ ีทตี่ าแหน่งของโหนดที่กาหนดในโครงสร้าง หรื อ
ถ้ากรณีที่ PT = NULL หมายถึงขณะนั้นโครงสร้างไม่มีขอ้ มูลใดอยู่เลย (ว่างเปล่า) การเพิ่มข้อมูล
X ในโครงสร้างเป็ นโหนดใหม่ที่ต่อจากโหนดที่กาหนด หรื อถ้า PT = NULL โหนดที่ถูกเพิม่ เข้า
ไปคือข้อมูลโหนดแรกในโครงสร้างนัน่ เอง
กาหนดให้ X คือโหนดใหม่ซ่ ึงอยู่ที่ตาแหน่ง NEW ถ้า PT = NULL แล้ว X จะถูกเพิ่มเข้า
เป็ นโหนดแรกในโครงสร้าง ดังขั้นตอนวิธีต่อไปนี้

Algorithm INSPT (DATA , LINK , START , AVAIL , PT , X) ขั้นตอนนี้เป็ นการแทรกโหนด X


เป็ นโหนดแรกเมื่อ PT = NULL
1. [ตรวจสอบพื้นที่ว่าง]
If AVAIL = NULL then Write (“OVERFLOW”) and Exit.
2. [ขอโหนดแรกมาจาก Storage Pool]
Set NEW = AVAIL
AVAIL = LINK [AVAIL]
3. [นาข้อมูลใส่ลงในโหนดที่ขอมาจากข้อ 2]
Set DATA[NEW] = X
4. [ตรวจสอบว่าเป็ นโหนดแรกใช่หรื อไม่]
If PT = NULL then
Set LINK[NEW] = START
START = NEW
Else [Insert after node with location PT.]
Set LINK[NEW] = LINK[PT]
LINK[PT] = NEW
5. Exit.
56

จากขั้นตอนวิธี INSPT สามารถแสดงลาดับการทางานได้ดงั รู ปที่ 3.14

DATA LINK
รูปที่ 3.14 แสดงขั้นตอนการเพิ่มข้ อมูลต่อจากโหนดที
1 Storage Pool
NEW
่กาหนดX NULL
2 DATA(NEW) = X

DATA DATA DATA DATA NULL

p = PT
3 q = Link(p)
4 Link(p) = NEW
DATA LINK

NEW X NULL

DATA DATA DATA DATA NULL

p = PT q
5 Link(NEW) = q
DATA LINK

NEW X

DATA DATA DATA DATA NULL

p q

รูป 3.14 แสดงการเพิ่มข้อมูลต่ อจากโหนดที่กาหนด


57

5.3.3 การเพิ่มข้อมูลเป็ นโหนดสุ ดท้ ายของโครงสร้ าง

DATA LINK
1 Storage Pool
2 DATA(NEW) = X NEW X NULL

DATA DATA DATA NULL

3 q = Link(p) = NEW DATA LINK

NEW X NULL

DATA DATA DATA

รูปที่ 3.15 แสดงขั้นตอนการเพิ่มข้อมูลเป็ นโหนดสุ ดท้ ายของโครงสร้ าง

5.4 การลบข้อมูลจากโครงสร้ างข้อมูลลิงค์ลิสต์


การลบข้อมูลจากโครงสร้างข้อมูลลิงค์ลิสต์ หมายถึง การดึงเอาโหนดที่ตอ้ งการลบออก
จากรายการเชื่อมโยงชุดเดิม ดังนั้นการเปลี่ยนแปลงที่เกิดขึ้นคือ การเปลี่ยนค่าของพอยน์เตอร์ และ
เมื่อทาการลบข้อมูลออกจากโครงสร้างแล้วจะต้องคืนโหนดที่ถูกลบให้กบั Storage Pool เพื่อที่จะ
ได้สามารถนาหน่วยความจาส่ วนนั้นไปใช้งานต่อไป ลักษณะการลบข้อมูลออกจากโครงสร้าง
ข้อมูลรายการเชื่อมโยงสามารถแสดงได้ ดังรู ปที่ 3.16
58

START
p N q

NULL

START )

p N q

NULL

รูปที่ 3.16 แสดงการลบโหนดออกจากโครงสร้ างข้ อมูลรายการเชื่ อมโยง

START
p N q

NULL

AVAIL NULL

Storage Pool

รูปที่ 3.17 แสดงการลบโหนดและส่ งโหนดนั้นคืนกลับ Storage Pool

การลบข้อมูลออกจากโครงสร้างรายการเชื่อมโยง อาจเกิดขึ้นได้หลายลักษณะ เช่นเดียวกับ


การเพิ่มข้อมูล แต่พอสรุ ปได้ดงั นี้
1. การลบโหนดแรก
2. การลบโหนดที่อยู่หลังโหนดที่กาหนด
3. การลบโหนดสุ ดท้าย
59

ขั้นตอนการลบโหนด
Algorithm DEL(DATA, LINK , START, AVAIL,PT, PTF)
1. [Delete first node] {กรณี ที่ 1 ลบโหนดแรก}
If PTF =NULL then
Set START = LINK[START]
Else {กรณีที่ 2 และ 3 การลบโหนดที่อยู่หลังโหนดที่กาหนด}
Set LINK[PTF] = LINK[PT] [Delete node N]
2. [Return Delete node to the AVAIL list]
Set LINK[PT] = AVAIL
AVAIL = PT
3. [Finish algorithm]
Exit.

6. ประเภทของโครงสร้ างข้อมูลลิงค์ ลสิ ต์


โครงสร้างข้อมูลลิงค์ลิสต์ แบ่งเป็ น 2 กลุ่มใหญ่ ๆ ได้แก่
1) โครงสร้างข้อมูลลิงค์ลิสต์ แบบ Singly Linked List (SLL)
2) โครงสร้างข้อมูลลิงค์ลิสต์ แบบ Doubly Linked List (DLL)

6.1 โครงสร้ างข้อมูลลิงค์ลิสต์ แบบ Singly Linked List (SLL) แบ่งออกเป็ น 2 ประเภท
• โครงสร้างข้อมูลลิงค์ลิสต์แบบ Ordinary Singly Linked List (OSLL) โครงสร้างลิงค์
ลิสต์แบบ OSLL คือ โครงสร้างข้อมูลลิงค์ลิสต์ที่มีลกั ษณะของโหนดต่อเชื่อมกันไปในทิศทาง
เดียวกันเหมือนกับโครงสร้างข้อมูลลิงค์ลิสต์ที่กล่าวมาแล้วตั้งแต่ตน้
• โครงสร้างข้อมูลลิงค์ลิสต์แบบ Circular Singly Linked List (CSLL) มีลกั ษณะคล้าย
กับแบบ OSLL ยกเว้นพอยน์เตอร์ NULL ของโหนดสุ ดท้ายสามารถชี้กลับมายังตาแหน่งเริ่ มต้น
ของโครงสร้างข้อมูลได้ ดังรู ปที่ 3.18
60

LINK DATA LINK DATA LINK


HEAD

รูปที่3.18 แสดงลักษณะของ Circular Singly Linked List

LINK
HEAD LINK(HEAD)=HEAD

รูปที่ 3.19 แสดงลักษณะของ Circular Singly Linked List แบบที่มี Head Node

START DATA LINK DATA LINK DATA LINK

รูปที่3.20 แสดงลักษณะของ Empty Circular Singly Linked List

ลักษณะที่สาคัญของ CLL
เมื่อมีการดาเนินการอย่างใดอย่างหนึ่งกับสมาชิ กทุกตัวในโครงสร้างข้อมูลแบบ CLL
สามารถตั้งต้นที่สมาชิกตัวไหนก่อนก็ได้

Algorithm TRVCLL ขั้นตอนวิธีน้ ีเป็ นการท่องเข้าไปในโครงสร้างข้อมูลแบบ CLL ที่มีโหนด


HEAD
1. [กาหนดค่าเริ่ มต้นให้กบั พอยน์เตอร์ PT]
Set PT = LINK[START]
2. Repeat Step 3 and 4 while PT  START
3. Apply Process to INFO[PT]
4. Set PT = LINK[PT]
5. Exit
61

6.2 โครงสร้ างข้อมูลลิงค์ลิสต์ แบบโยงคู่ (Doubly Linked List : DLL)


จากรู ปแบบของลิงค์ลิตส์แบบวงกลม จะมีการเข้าถึงข้อมูลในโหนดใดๆก็ได้ดว้ ยการใช้
พอยน์เตอร์ โดยไม่มีความจาเป็ นจะต้องเริ่ มต้นจากโหนดแรกเสมอ จึงมีขอ้ ดีเมื่อเทียบกับลิงค์ลิตส์
แบบเชิงเส้น(Linear Linklist) แต่ลิงค์ลิสต์แบบวงกลมก็ยงั มีขอ้ จากัดในการนามาประยุกต์ใช้ในบาง
กรณี เป็ นต้นว่าหากเราต้องการลบโหนดในลิสต์ ซึ่งมีพอยน์เตอร์เพียงพอยน์เตอร์เดียวชี้ไปยัง
โหนดที่ตอ้ งการลบโดยมีมีพอยน์เตอร์อีกตัวชี้อยู่ที่โหนดก่อนหน้า การลบโหนดนั้นๆ ก็ไม่สามารถ
ทาได้ ทั้งนี้เพราะไม่สามารถเปลี่ยนฟิ ลด์ LINK ของโหนดก่อนหน้าให้ช้ ีไปยังโหนดที่อยู่ถดั จาก
โหนดที่ตอ้ งการลบ
ในอีกกรณี บางครั้งเรามีความจาเป็ นต้องจัดการกับลิงค์สิสต์ในลักษณะกลับหลัง โดยเริ่ ม
จากโหนดท้ายสุดมายังโหนดแรกสุดตามลาดับ เช่น โหนดในลิงค์ลิสต์ได้มีการเชื่อมโยงกันโดย
เรี ยงลาดับคะแนนเฉลี่ยสะสมของนักศึกษาจากน้อยไปมาก ผูส้ อนอาจต้องการให้พิมพ์คะแนนของ
นักศึกษาจากมากไปหาน้อยก็ได้ ซึ่งกรณี น้ ีแม้ว่าลิงค์ลิสต์แบบโยงเดี่ยวก็สามารถจัดการได้ แต่ก็
ยุ่งยากซับซ้อนกว่า ดังนั้นหากเรามีลิสต์ที่สามารถเข้าถึงข้อมูลแบบ 2 ทิศทาง คือ สามารถเข้าถึง
ข้อมูลแบบเดินหน้าจากโหนดแรกสุ ดไปยังโหนดอื่นๆ ด้านหลัง และในทางกลับกั นก็สามารถ
เข้าถึงข้อมูลแบบถอยหลัง นัน่ คือจากโหนดหลังสุ ดย้อนกลับมายังโหนดอื่นๆด้านหน้า ก็สามารถ
แก้ปัญหาข้างต้นได้โดยง่าย
โครงสร้างรายการเชื่อมโยงแบบนี้เป็ นโครงสร้างที่แต่ละโหนดมีพอยน์เตอร์สองทิศทาง
อันประกอบด้วยพอยเตอร์ที่ใช้ช้ ีตาแหน่งใน 2 ทิศทางได้แก่ LLINK และ RLINK ซึ่งทาหน้าที่ช้ ี
ไปยังโหนดด้านซ้ายและด้านขวาของโหนดนั้นตามลาดับโดยลิงค์ลิสต์แบบโยงคู่เป็ นลิสต์ที่แต่ละ
โหนดต้องประกอบด้วย 3 ฟิ ลด์ ดังโครงสร้างของโหนดในรู ปที่ 3.21

LLINK DATA RLINK

รูปที่ 3.21 แสดงโครงสร้ างของโหนดในโครงสร้ างแบบ DLL

DATA คือ ข้อมูลที่เก็บอยู่ในโหนด


LLINK คือ พอยเตอร์ที่ช้ ีไปยังโหนดซ้ายมือ
RLINK คือ พอยเตอร์ที่ช้ ีไปยังโหนดขวามือ
62

˜
head ˜ Ying
˜
Ple Pop
˜
Yee ˜
˜ ˜ ˜

p q

รูปที่ 3.22 แสดงตัวอย่ างลิงค์ลิสต์ แบบโยงคู่

การประกาศลิงค์ลิตส์ แบบโยงคู่
#define STRING25 25
typedef struct pt
{
char info [string20]
struct pt *rlink, *llink;
}
pt;
pt *head , *start , *p , *q ;

6.2.1 การแทรกโหนดในลิงค์ ลสิ ต์ แบบโยงคู่ (Inserting Nodes into a Doubly Linked


List)
การแทรกโหนดในลิสต์แบบโยงคู่ค่อนข้างซับซ้อนกว่าลิสต์แบบโยงเดี่ยว เพราะ
จาเป็ นต้องพิจารณาพอยน์เตอร์หลายตัวด้วยกัน
start

˜
head ˜ Ying
˜
Ple Pop
˜
Yee ˜
˜ ˜ ˜

3 4
2 1
˜ Ben ˜

รูปที่ 3.23 แสดงตัวอย่ างการแทรกโหนดในลิสต์ แบบโยงคู่


63

สามารถใช้พอยน์เตอร์เพียงตัวเดียว คือ start เพื่อท่องเข้าไปในลิสต์ และการแทรก


โหนด p หน้าโหนด start จาเป็ นต้องใช้ 4 คาสั่ง ดังนี้
p -> rlink = start;
p -> llink = start -> llink;
start -> llink -> rlink = p;
start -> llink -> p;

ลาดับของคาสั่งข้างต้นมีความสาคัญ จึงต้องระมัดระวังเป็ นพิเศษ เช่น หากเราเปลี่ยนฟิ ลด์


start ->llink ก่อนคาสั่งอื่น จะมีผลให้ไม่สามารถอ้างถึงโหนดที่อยู่ก่อนหน้า start ได้

6.2.2 การลบโหนดในลิงค์ ลิสต์ แบบโยงคู่ (Deleting Nodes from a Doubly Linked


List)
ในทานองเดียวกันกรณี การแทรกโหนด เราสามารถใช้เพียงพอยน์เตอรเดียว คือ
start เพื่อท่องเข้าไปหาโหนดที่ตอ้ งการลบ เมื่อพบแล้วให้ใช้ฟิลด์ llink ของโหนดที่
ต้องการลบคือ โหนด start จัดการเปลี่ยนค่าในฟิ ลด์ rlink ของโหนดก่อนหน้าให้ยา้ ยข้าม
โหนดที่ไม่ตอ้ งการไปชี้ยงั โหนดถัดไป ดังรู ปที่ 3.24
2

˜ ˜
˜ Ying ˜
Ple ˜
Pop ˜

start

รูปที่ 3.24 แสดงตัวอย่ างการแทรกโหนดในลิสต์ แบบโยงคู่

ต้องใช้ 2 คาสั่งเพื่อการลบโหนด start คือ


Start -> llink -> rlink = start -> rlink;
Start -> rlink -> llink = start -> llink;
64

แบบฝึ กหัดบทที่ 3

1. ให้บอกข้อดี ข้อเสียของโครงสร้างข้อมูลแบบอาร์เรย์ และโครงสร้างข้อมูลแบบลิงค์ลิสต์

2. พอยเตอร์ (Pointer) คืออะไร มีการทางานอย่างไร ยกตัวอย่างการประกาศใช้ตวั แปร Pointer ใน


ภาษา C

3. เรานาพอยเตอร์มาใช้ในโครงสร้างข้อมูลแบบลิงค์ลิสต์ลกั ษณะใด วาดรู ปและอธิบายมาให้


เข้าใจ

4. โหนด (Node) ในลิงค์ลิสต์คืออะไร วาดรู ปและอธิบายมาให้เข้าใจ

5. หน่วยความจาว่าง (Storage Pool) คืออะไร มีวิธีในการนามาใช้ในโครงสร้างข้อมูลลิงค์ลิสต์


อย่างไร

6. วาดรู ปและอธิบายขั้นตอนการเพิ่มข้อมูลเข้าในลิงค์ลิสต์ดงั ต่อไปนี้


• เพิม่ ข้อมูลที่จุดเริ่ มต้นของโครงสร้าง
• เพิ่มข้อมูลที่โหนดสุ ดท้ายของโครงสร้าง

7. วาดรู ปและอธิบายขั้นตอนการลบข้อมูลออกจากลิงค์ลิสต์

8. บอกข้อดีของการใช้โครงสร้างข้อมูลแบบ Circular Singly Linked List

9. โครงสร้างข้อมูลลิงค์ลิสต์แบบโยงคู่มีลกั ษณะอย่างไร วาดรู ปและอธิบาย พร้อมทั้งยกตัวอย่าง


ข้อดีของลิงค์ลิสต์แบบโยงคู่

©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©

You might also like