Thanks to visit codestin.com
Credit goes to www.datacamp.com

ข้ามไปยังเนื้อหาหลัก

ลิงก์ลิสต์ในภาษา Python: บทเรียนพร้อมตัวอย่าง

เรียนรู้ทุกอย่างที่จำเป็นเกี่ยวกับลิงก์ลิสต์: ควรใช้เมื่อใด ประเภทต่างๆ และการนำไปใช้ใน Python
อัปเดตแล้ว 2 มิ.ย. 2569  · 9 นาที อ่าน

ลิงก์ลิสต์คือโครงสร้างข้อมูลที่มีบทบาทสำคัญในการจัดระเบียบและจัดการข้อมูล ประกอบด้วยชุดของโหนดที่ถูกเก็บไว้ตามตำแหน่งต่างๆ แบบสุ่มในหน่วยความจำ ช่วยให้จัดการหน่วยความจำได้อย่างมีประสิทธิภาพ โหนดแต่ละตัวในลิงก์ลิสต์มีองค์ประกอบหลักสองส่วน ได้แก่ ส่วนข้อมูล และการอ้างอิงไปยังโหนดถัดไปในลำดับ

หากแนวคิดนี้ดูซับซ้อนในตอนแรก ไม่ต้องกังวล!

เราจะอธิบายให้เข้าใจตั้งแต่พื้นฐานว่าลิงก์ลิสต์คืออะไร เหตุใดจึงใช้ และข้อดีเฉพาะตัวที่มี

ทำไมต้องลิงก์ลิสต์?

ลิงก์ลิสต์ถูกสร้างขึ้นเพื่อแก้ไขข้อเสียหลายประการของการเก็บข้อมูลในลิสต์และอาเรย์ทั่วไป ดังที่สรุปไว้ด้านล่าง:

แทรกและลบได้ง่าย

ในลิสต์ การแทรกหรือลบองค์ประกอบที่ตำแหน่งใดๆ นอกเหนือจากท้ายลิสต์ จำเป็นต้องเลื่อนรายการที่ตามมาทั้งหมดไปยังตำแหน่งใหม่ กระบวนการนี้มีความซับซ้อนเชิงเวลาเป็น O(n) และอาจทำให้ประสิทธิภาพลดลงอย่างมาก โดยเฉพาะเมื่อขนาดลิสต์ใหญ่ขึ้น หากยังไม่คุ้นเคยกับการทำงานหรือการนำลิสต์ไปใช้ สามารถอ่าน บทเรียนเกี่ยวกับลิสต์ใน Python ของเราได้

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

เมื่อมีการอ้างอิงตรงไปยังโหนดที่ตำแหน่งแทรกหรือลบแล้ว ตัวปฏิบัติการเองมีความซับซ้อนเชิงเวลา O(1) อย่างไรก็ตาม การค้นหาตำแหน่งนั้นยังต้องไล่ลำดับแบบ O(n) ดังนั้นประโยชน์ O(1) จึงใช้ได้เมื่อมีพอยน์เตอร์ไปยังโหนดที่เกี่ยวข้องอยู่แล้วเท่านั้น (เช่น เมื่อทำงานที่หัวลิสต์)

ขนาดยืดหยุ่น

ลิสต์ใน Python เป็นอาเรย์แบบไดนามิก ซึ่งหมายความว่าสามารถปรับขนาดได้อย่างยืดหยุ่น

แต่กระบวนการนี้เกี่ยวข้องกับการปฏิบัติการที่ซับซ้อนหลายอย่าง รวมถึงการจัดสรรอาเรย์ใหม่ไปยังบล็อกหน่วยความจำที่ใหญ่ขึ้น การจัดสรรใหม่เช่นนี้ไม่มีประสิทธิภาพเพราะต้องคัดลอกองค์ประกอบไปยังบล็อกใหม่ อาจทำให้จัดสรรพื้นที่เกินความจำเป็นในทันที

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

ใช้หน่วยความจำอย่างมีประสิทธิภาพ

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

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

ควรใช้ลิงก์ลิสต์เมื่อใด?

แม้ว่าลิงก์ลิสต์จะมีข้อดีเหนือกว่าลิสต์และอาเรย์ทั่วไป เช่น ขนาดยืดหยุ่นและประสิทธิภาพด้านหน่วยความจำ แต่ก็มีข้อจำกัดเช่นกัน เนื่องจากต้องเก็บพอยน์เตอร์ของแต่ละองค์ประกอบเพื่ออ้างอิงไปยังโหนดถัดไป ทำให้การใช้หน่วยความจำต่อองค์ประกอบสูงขึ้น นอกจากนี้ โครงสร้างข้อมูลนี้ไม่รองรับการเข้าถึงข้อมูลโดยตรง การเข้าถึงองค์ประกอบใดๆ ต้องไล่ลำดับจากจุดเริ่มต้นของลิสต์ ส่งผลให้ความซับซ้อนเชิงเวลาของการค้นหาเป็น O(n)

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

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

ประเภทของลิงก์ลิสต์

ลิงก์ลิสต์มีสามประเภท โดยแต่ละแบบมีข้อดีเฉพาะสำหรับสถานการณ์ต่างๆ ได้แก่:

ลิงก์ลิสต์เชื่อมเดี่ยว (Singly-linked list)

Image of a singly linked list

ลิงก์ลิสต์เชื่อมเดี่ยว

ลิงก์ลิสต์เชื่อมเดี่ยวเป็นประเภทที่ง่ายที่สุด โดยโหนดแต่ละตัวเก็บข้อมูลบางส่วนและการอ้างอิงไปยังโหนดถัดไป สามารถไล่ลำดับได้ทางเดียวเท่านั้น คือจากหัวลิสต์ (โหนดแรก) ไปยังท้ายลิสต์ (โหนดสุดท้าย)

โหนดแต่ละตัวในลิงก์ลิสต์เชื่อมเดี่ยวมักประกอบด้วยสองส่วน:

  • Data: ข้อมูลจริงที่เก็บในโหนด
  • Next Pointer: การอ้างอิงไปยังโหนดถัดไป โดยปกติพอยน์เตอร์ของโหนดสุดท้ายจะถูกตั้งค่าเป็น null

เนื่องจากโครงสร้างข้อมูลแบบนี้ไล่ลำดับได้ทางเดียว การเข้าถึงองค์ประกอบใดๆ ตามค่า หรือดัชนี ต้องเริ่มจากหัวลิสต์และไล่ผ่านโหนดทีละตัวจนพบโหนดที่ต้องการ การดำเนินการนี้มีความซับซ้อนเชิงเวลา O(n) จึงไม่มีประสิทธิภาพสำหรับลิสต์ขนาดใหญ่

การแทรกและลบโหนดที่ต้นลิงก์ลิสต์เชื่อมเดี่ยวทำได้มีประสิทธิภาพมาก โดยมีความซับซ้อนเชิงเวลา O(1) อย่างไรก็ตาม การแทรกและลบตรงกลางหรือท้ายลิสต์ต้องไล่ลำดับจนถึงตำแหน่งนั้น จึงมีความซับซ้อนเชิงเวลา O(n)

การออกแบบของลิงก์ลิสต์เชื่อมเดี่ยวทำให้เหมาะสำหรับการดำเนินการที่เกิดขึ้นที่จุดเริ่มต้นของลิสต์

ลิงก์ลิสต์เชื่อมคู่ (Doubly-linked list)

Image of a doubly linked list

ลิงก์ลิสต์เชื่อมคู่

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

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

ลิงก์ลิสต์แบบวงกลม (Circular linked list)

Image of a circular linked list

ลิงก์ลิสต์แบบวงกลม

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

ลักษณะที่เป็นวัฏจักรของลิงก์ลิสต์แบบวงกลมเหมาะกับสถานการณ์ที่ต้องวนซ้ำอย่างต่อเนื่อง เช่น เกมกระดานที่วนจากผู้เล่นคนสุดท้ายกลับไปยังคนแรก หรือในอัลกอริทึมคอมพิวเตอร์อย่างการจัดตารางแบบรอบหมุน (round-robin scheduling)

สรุปความซับซ้อนเชิงเวลา

การเปรียบเทียบลิงก์ลิสต์กับลิสต์ของ Python แบบคร่าวๆ ช่วยให้เห็นภาพได้ชัดเจน:

การดำเนินการ ลิงก์ลิสต์เชื่อมเดี่ยว อาเรย์/ลิสต์ของ Python
เข้าถึงด้วยดัชนี O(n) O(1)
ค้นหาตามค่า O(n) O(n)
แทรกที่จุดเริ่มต้น O(1) O(n)
แทรกที่จุดสิ้นสุด O(n) O(1) แบบเฉลี่ยถ่วงเวลา
แทรกตรงกลาง O(n) O(n)
ลบที่จุดเริ่มต้น O(1) O(n)
ลบที่จุดสิ้นสุด O(n) O(1) แบบเฉลี่ยถ่วงเวลา

ข้อสรุปหลัก: ลิงก์ลิสต์ได้เปรียบในการแทรกและลบที่หัวลิสต์ (O(1)) แต่เสียเปรียบในด้านอื่นๆ หากไม่ได้เพิ่มหรือลบองค์ประกอบที่จุดเริ่มต้นของโครงสร้างข้อมูลบ่อยๆ ลิสต์ปกติของ Python น่าจะเป็นตัวเลือกที่ดีกว่า

วิธีสร้างลิงก์ลิสต์ใน Python

เมื่อเข้าใจแล้วว่าลิงก์ลิสต์คืออะไร ทำไมเราจึงใช้ และมีรูปแบบใดบ้าง ต่อไปมาดูการนำโครงสร้างข้อมูลเหล่านี้ไปใช้ใน Python โน้ตบุ๊กสำหรับบทเรียนนี้มีให้ใน DataLab workbook นี้ หากสร้างสำเนาไว้ก็สามารถแก้ไขและรันโค้ดได้ เหมาะมากหากพบปัญหาในการรันโค้ดบนเครื่องของตนเอง!

เริ่มต้นสร้างโหนด

ตามที่ได้เรียนไปแล้ว โหนดคือองค์ประกอบในลิงก์ลิสต์ที่เก็บข้อมูลและการอ้างอิงไปยังโหนดถัดไป ต่อไปนี้คือตัวอย่างการกำหนดโหนดใน Python:

class Node:
    def __init__(self, data):
        self.data = data
        self.next = None

    def __repr__(self):
        return f"Node({self.data})"

โค้ดข้างต้นจะเริ่มต้นโหนดโดยทำสองอย่างหลักๆ คือ กำหนดค่าให้แอตทริบิวต์ “data” ของโหนดเพื่อแทนข้อมูลจริงที่โหนดควรเก็บ และแอตทริบิวต์ “next” แทนที่อยู่ของโหนดถัดไป โดยขณะนี้ตั้งค่าเป็น None เพื่อบ่งชี้ว่ายังไม่ลิงก์ไปยังโหนดอื่น เมื่อมีการเพิ่มโหนดใหม่ลงในลิงก์ลิสต์ แอตทริบิวต์นี้จะถูกอัปเดตให้ชี้ไปยังโหนดถัดไป

สร้างคลาสลิงก์ลิสต์

ถัดไป เราจำเป็นต้องสร้างคลาสลิงก์ลิสต์ ซึ่งจะรวบรวมการดำเนินการทั้งหมดในการจัดการโหนด เช่น การแทรกและการลบ เริ่มจากการเริ่มต้นลิงก์ลิสต์ก่อน:

class LinkedList:
    def __init__(self):
        self.head = None  # Initialize head as None

ด้วยการตั้งค่า self.head เป็น None เรากำหนดว่าลิงก์ลิสต์เริ่มต้นว่างเปล่าและยังไม่มีโหนดใดให้ชี้ถึง ต่อไปจะเติมรายการด้วยการแทรกโหนดใหม่

แทรกโหนดใหม่ที่จุดเริ่มต้นของลิงก์ลิสต์

ภายในคลาส LinkedList เราจะเพิ่มเมธอดเพื่อสร้างโหนดใหม่และวางไว้ที่จุดเริ่มต้นของลิสต์:

    def insertAtBeginning(self, new_data):
        new_node = Node(new_data)  # Create a new node 
        new_node.next = self.head  # Next for new node becomes the   current head
        self.head = new_node  # Head now points to the new node

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

ต่อไปเราจะเติมลิงก์ลิสต์นี้ด้วยชุดคำ เพื่อให้เห็นภาพการทำงานของการแทรกได้ชัดเจนขึ้น ก่อนอื่นมาสร้างเมธอดสำหรับไล่ลำดับและพิมพ์เนื้อหาของลิสต์:

    def printList(self):
        temp = self.head # Start from the head of the list
        while temp:
            print(temp.data,end=' ') # Print the data in the current node
            temp = temp.next # Move to the next node
        print()  # Ensures the output is followed by a new line

เมธอดข้างต้นจะพิมพ์เนื้อหาของลิงก์ลิสต์ มาลองใช้เมธอดที่กำหนดไว้เพื่อเติมลิสต์ด้วยชุดคำว่า “the quick brown fox”

if __name__ == '__main__':
    # Create a new LinkedList instance
    llist = LinkedList()

    # Insert each letter at the beginning using the method we created
    llist.insertAtBeginning('fox') 
    llist.insertAtBeginning('brown') 
    llist.insertAtBeginning('quick')  
    llist.insertAtBeginning('the')  

    # Now 'the' is the head of the list, followed by 'quick', then 'brown' and 'fox'

    # Print the list
    llist.printList()

โค้ดด้านบนควรจะแสดงผลลัพธ์ดังนี้:

"the quick brown fox"

แทรกโหนดใหม่ที่จุดสิ้นสุดของลิงก์ลิสต์

เราจะสร้างเมธอดชื่อ insertAtEnd ภายในคลาส LinkedList เพื่อสร้างโหนดใหม่ที่ท้ายลิสต์ หากลิสต์ว่าง โหนดใหม่จะกลายเป็นหัวลิสต์ ไม่เช่นนั้นจะถูกต่อท้ายโหนดสุดท้ายปัจจุบัน มาดูตัวอย่างการทำงานจริง:

    def insertAtEnd(self, new_data):
        new_node = Node(new_data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node

เมธอดข้างต้นเริ่มจากการสร้างโหนดใหม่ จากนั้นตรวจสอบว่าลิสต์ว่างหรือไม่ หากว่างจะกำหนดให้โหนดใหม่เป็นหัวลิสต์ มิฉะนั้นจะไล่ลิสต์เพื่อหาโหนดสุดท้ายแล้วตั้งพอยน์เตอร์ของโหนดนั้นให้ชี้ไปยังโหนดใหม่

ต่อไปเพิ่มเมธอดนี้ในคลาส LinkedList และใช้เพื่อเพิ่มคำที่ท้ายลิสต์ ให้ปรับฟังก์ชันหลักดังนี้:

if __name__ == '__main__':
    llist = LinkedList()

    # Insert words at the beginning
    llist.insertAtBeginning('fox')
    llist.insertAtBeginning('brown')
    llist.insertAtBeginning('quick')
    llist.insertAtBeginning('the')

    # Insert a word at the end
    llist.insertAtEnd('jumps')

    # Print the list
    llist.printList()

สังเกตว่าเราเพียงเรียกเมธอด insertAtEnd เพื่อพิมพ์คำว่า “jumps” ที่ท้ายลิสต์ โค้ดด้านบนควรแสดงผลลัพธ์ดังนี้:

"the quick brown fox jumps"

ลบโหนดจากจุดเริ่มต้นของลิงก์ลิสต์

การลบโหนดแรกของลิงก์ลิสต์ทำได้ง่าย เพราะเพียงชี้หัวลิสต์ไปยังโหนดที่สอง วิธีนี้ทำให้โหนดแรกไม่เป็นส่วนหนึ่งของลิสต์อีกต่อไป เพิ่มเมธอดต่อไปนี้ในคลาส LinkedList เพื่อทำสิ่งนี้:

def deleteFromBeginning(self):
    if self.head is None:
        return "The list is empty" # If the list is empty, return this string
    self.head = self.head.next  # Otherwise, remove the head by making the next node the new head

ลบโหนดจากจุดสิ้นสุดของลิงก์ลิสต์

การลบโหนดสุดท้ายของลิงก์ลิสต์ต้องไล่ลิสต์เพื่อหาโหนดรองสุดท้าย แล้วเปลี่ยนพอยน์เตอร์ next ของมันเป็น None วิธีนี้ทำให้โหนดสุดท้ายไม่เป็นส่วนหนึ่งของลิสต์ คัดลอกและวางเมธอดต่อไปนี้ลงในคลาส LinkedList:

def deleteFromEnd(self):
    if self.head is None:
        return "The list is empty" 
    if self.head.next is None:
        self.head = None  # If there's only one node, remove the head by making it None
        return
    temp = self.head
    while temp.next.next:  # Otherwise, go to the second-last node
        temp = temp.next
    temp.next = None  # Remove the last node by setting the next pointer of the second-last node to None

เมธอดข้างต้นเริ่มจากตรวจสอบว่าลิงก์ลิสต์ว่างหรือไม่ หากว่างจะส่งข้อความแจ้งกลับไป หากลิสต์มีเพียงโหนดเดียวก็ลบโหนดนั้นออก สำหรับลิสต์ที่มีหลายโหนด เมธอดจะหาโหนดรองสุดท้ายแล้วอัปเดตการอ้างอิงโหนดถัดไปให้เป็น None

ต่อไปมาอัปเดตฟังก์ชันหลักเพื่อลบองค์ประกอบจากต้นและท้ายของลิงก์ลิสต์:

if __name__ == '__main__':
    llist = LinkedList()

    # Insert words at the beginning
    llist.insertAtBeginning('fox')
    llist.insertAtBeginning('brown')
    llist.insertAtBeginning('quick')
    llist.insertAtBeginning('the')

    # Insert a word at the end
    llist.insertAtEnd('jumps')

    # Print the list before deletion
    print("List before deletion:")
    llist.printList()

    # Deleting nodes from the beginning and end
    llist.deleteFromBeginning()
    llist.deleteFromEnd()

    # Print the list after deletion
    print("List after deletion:")
    llist.printList()

โค้ดด้านบนจะพิมพ์ลิสต์ก่อนและหลังการลบ เพื่อแสดงให้เห็นการทำงานของการแทรกและการลบในลิงก์ลิสต์ ควรเห็นผลลัพธ์ดังนี้หลังจากรันโค้ด:

List before deletion:
the quick brown fox jumps 
List after deletion:
quick brown fox

การค้นหาค่าที่ต้องการในลิงก์ลิสต์

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

def search(self, value):
    current = self.head  # Start with the head of the list
    position = 0  # Counter to keep track of the position
    while current: # Traverse the list
        if current.data == value: # Compare the list's data to the search value
            return f"Value '{value}' found at position {position}" # Print the value if a match is found
        current = current.next
        position += 1
    return f"Value '{value}' not found in the list" 

เพื่อค้นหาค่าเฉพาะในลิงก์ลิสต์ที่เราสร้างไว้ ให้ปรับปรุงฟังก์ชันหลักเพื่อรวมเมธอดค้นหาที่เพิ่งสร้าง:

if __name__ == '__main__':
    llist = LinkedList()

    # Insert words at the beginning
    llist.insertAtBeginning('fox')
    llist.insertAtBeginning('brown')
    llist.insertAtBeginning('quick')
    llist.insertAtBeginning('the')

    # Insert a word at the end
    llist.insertAtEnd('jumps')

   # Print the list before deletion
    print("List before deletion:")
    llist.printList()

    # Deleting nodes from beginning and end
    llist.deleteFromBeginning()
    llist.deleteFromEnd()

    # Print the list after deletion
    print("List after deletion:")
    llist.printList()
    
        # Search for 'quick' and 'lazy' in the list
    print(llist.search('quick'))  # Expected to find
    print(llist.search('lazy'))   # Expected not to find

โค้ดด้านบนจะแสดงผลลัพธ์ดังนี้:

List before deletion:
the quick brown fox jumps 
List after deletion:
quick brown fox 
Value 'quick' found at position 0
Value 'lazy' not found in the list

คำว่า “quick” ถูกค้นพบสำเร็จในลิงก์ลิสต์ เนื่องจากอยู่ในตำแหน่งแรกของลิสต์ ส่วนคำว่า “lazy” ไม่ได้เป็นส่วนหนึ่งของลิสต์ จึงไม่พบ

ข้อคิดส่งท้าย

หากอ่านมาถึงตรงนี้ ขอแสดงความยินดี! ตอนนี้มีความเข้าใจพื้นฐานของลิงก์ลิสต์อย่างมั่นคงแล้ว ทั้งโครงสร้าง ประเภท วิธีเพิ่มและลบองค์ประกอบ ตลอดจนการไล่ลำดับ

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

สร้างโปรเจกต์ของตนเอง

ลงมือปฏิบัติจริงด้วยการผสานลิงก์ลิสต์เข้ากับโปรเจกต์ด้านการเขียนโค้ดหรือวิทยาการข้อมูล ลิงก์ลิสต์ถูกใช้ในการพัฒนาระบบไฟล์ สร้างแฮชเทเบิล และแม้แต่ระบบนำทาง GPS และเกมกระดาน หากต้องการเริ่มต้นโปรเจกต์ของตนเอง ลองดู โปรเจกต์วิทยาการข้อมูล แบบมีแนะแนวของเราที่สอนการแก้ปัญหาจริงใน Python, R และ SQL ได้ฟรี

เรียนรู้โครงสร้างข้อมูลและอัลกอริทึม

การเรียนรู้โครงสร้างข้อมูลอื่นๆ เช่น ต้นไม้ (trees), สแต็ก (stacks) และคิว (queues) เป็นขั้นตอนต่อเนื่องตามธรรมชาติจากการเข้าใจลิงก์ลิสต์ โครงสร้างเหล่านี้ต่อยอดจากหลักการของลิงก์ลิสต์ ช่วยให้แก้ปัญหาการคำนวณที่หลากหลายได้อย่างมีประสิทธิภาพ ตัวอย่างเช่น ต้นไม้และต้นไม้ค้นหาแบบทวิภาค (binary search trees) ขยายแนวคิดของลิงก์ลิสต์ไปสู่รูปแบบลำดับชั้น ทำให้โหนดหนึ่งเชื่อมต่อกับองค์ประกอบหลายตัวในโครงสร้างข้อมูลได้

หากแนวคิดเหล่านี้ยังไม่คุ้นเคย ไม่ต้องกังวล! Datacamp มีคอร์สเต็มรูปแบบเกี่ยวกับ โครงสร้างข้อมูลและอัลกอริทึม ใน Python ที่จะพาคุณเรียนรู้หัวข้อเหล่านี้อย่างละเอียด เริ่มจากโครงสร้างข้อมูลอย่างสแต็ก ต้นไม้ แฮชเทเบิล คิว และกราฟ จากนั้นจะค่อยๆ เข้าใจอัลกอริทึมการค้นหาและการเรียงลำดับ ช่วยให้เป็นนักเขียนโปรแกรมและผู้แก้ปัญหาที่มีประสิทธิภาพมากขึ้น

สำรวจแนวคิดลิงก์ลิสต์ขั้นสูง

เราได้ลงมือทำลิงก์ลิสต์เชื่อมเดี่ยวในบทเรียนนี้ ครอบคลุมการดำเนินการเช่น การแทรก การลบ และการไล่ลำดับ

สามารถต่อยอดความรู้นี้ด้วยการเรียนรู้การนำลิงก์ลิสต์เชื่อมคู่และแบบวงกลมไปใช้ นอกจากนี้ยังมีสกิปป์ลิสต์ (skip list) ซึ่งเป็นส่วนขยายของลิงก์ลิสต์ที่ช่วยเร่งการค้นหาโดยเข้าถึงองค์ประกอบได้รวดเร็วยิ่งขึ้น

การเรียนรู้โครงสร้างข้อมูลขั้นสูงเหล่านี้จะยกระดับทักษะทางเทคนิคและเพิ่มขีดความสามารถในการเขียนโปรแกรมอย่างมาก เตรียมพร้อมรับมือโจทย์ที่ซับซ้อนยิ่งขึ้นในสาขาต่างๆ เช่น วิทยาการข้อมูล การพัฒนาซอฟต์แวร์ และวิศวกรรมการเรียนรู้ของเครื่อง

หากต้องการบทนำการเขียนโปรแกรมที่เป็นมิตรกับผู้เริ่มต้นก่อนลงมือกับหัวข้อขั้นสูง ลองสำรวจเส้นทางอาชีพ Python Programmer ของเรา ซึ่งมีชุดคอร์สที่จะสอนพื้นฐานของภาษาให้

หัวข้อ

เรียนรู้ Python อย่างต่อเนื่อง!

Tracks

พื้นฐานข้อมูลด้วย Python

28 ชม.
พัฒนาทักษะด้านข้อมูลของคุณ เรียนรู้การจัดการและการแสดงผลข้อมูล และประยุกต์ใช้การวิเคราะห์ขั้นสูงเพื่อการตัดสินใจที่ขับเคลื่อนด้วยข้อมูล
ดูรายละเอียดCodestin Search App
เริ่มหลักสูตร

Tracks

การเขียนโปรแกรม Python

19 ชม.
ยกระดับทักษะการเขียนโปรแกรมของคุณ เรียนรู้วิธีเพิ่มประสิทธิภาพโค้ด เขียนฟังก์ชันและการทดสอบ และใช้เทคนิควิศวกรรมซอฟต์แวร์ตามแนวปฏิบัติที่ดีที่สุด
ดูเพิ่มเติมCodestin Search App