منبع اصلی نوشتار زیر در این لینک قرار دارد

لیست پیوندی در پایتون – Linked List in Python

سال‌های خیلی دور دو مطلب در مورد لیست پیوندی یک طرفه و لیست پیوندی دو طرفه در سی‌پلاس‌پلاس نوشتم. می‌توانید در دو لینک‌ زیر، آن دو مطلب را مشاهده بفرمایید.

لیست پیوندی یک طرفه در ++C

لیست پیوندی دو طرفه در ++C

همچنین مطالب دیگری در زمینه لیست پیوندی داریم که برای شما بسیار مفید خواهند بود:

 

اما امروز می‌خواهم در مورد لینک لیست در پایتون بنویسم. مفهوم لیست پیوندی در تمام زبان‌های برنامه نویسی به یک شکل است. به همین دلیل با مراجعه به دو آدرس بالا می‌توانید با مفاهیم لیست پیوندی یک طرفه آشنا شوید بخضوص که تصویرهای خوبی دارند.

 

برای تعریف یک لیست پیوندی ابتدا به یک کلاس گره (Node) نیاز داریم تا داده‌هایمان را در آن ذخیره کنیم و همچنین آدرس به گره بعدی را نگه داریم. برای این منظور کد پایتون زیر را نوشته‌ایم:

class Node:

    def __init__(self, data=None, next=None):
        # Data on node
        self.data = data

        # Next node
        self.next = next

    def set_data(self, data):
        self.data = data

    def set_next_node(self, node):
        self.next = node

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next

این کلاس دو ویژگی برای ذخیره داده‌ و آدرس گره بعدی دارد. همچنین چهار عملگر برای خواند و نوشتن آن دو ویژگی دارد.

 

اکنون که یک کلاس برای گره‌ها تعریف کردیم. حالا می‌توانیم کلاس لیست پیوندی را بنویسیم. تنها ویژگی‌ای که کلاس لینک لیست نیاز دارد، یک اشاره‌گر به گره اول لیست‌پیوندی است. در زیر این قسمت از کد کلاس را مشاهده می‌کنید.

class LinkedList:

    def __init__(self, node=None):
        self.head = node

حالا که ویژگی کلاس Link List را تعریف کردیم، به ترتیب به عملگرهای (متد) این کلاس می‌پردازیم. اولین عملگری که برای کلاس لیست پیوندی می‌نویسیم، یک تابع برای شماردن تعداد گره‌های درون لیست است. این کار را با استفاده از کد زیر انجام می‌دهیم:

def size(self):

        # counter
        counter = 0
        # start form head of linked list
        pointer = self.head

        while pointer is not None:
            # count
            counter += 1
            # go to next node
            pointer = pointer.get_next()

        return counter

در این کد مقدار شمارنده را برابر صفر می‌گذاریم. سپس از اشاره‌گر به اول لیست شروع می‌کنیم و در ادامه به آدرس گره بعدی می‌رویم و این کار را تا زمانی که به آخر لیست برسیم ادامه می‌دهیم. زمانی به آخر لیست می رسیم که آدرس بعدی گره بعدی یک گره برابر با None یا پوچ باشد.

 

متد بعدی، تابعی برای اضافه کردن یک گره به لیست پیوندی است. برای این کار تابع زیر را نوشته‌ایم:

def insert_node(self, data):

        # start from head of linked list
        pointer = self.head

        # if linked list is empty
        if pointer is None:
            self.head = Node(data=data)
            return

        # find last node in the linked list
        while pointer.get_next() is not None:
            pointer = pointer.get_next()

        # link last node on list to new node
        pointer.set_next_node(Node(data=data))

در این تابع یک داده به عنوان ورودی به متد داده می‌شود که این داده هر نوعی (type) می‌تواند باشد. سپس از گره اول لیست شروع به حرکت می‌کند و هر بار با استفاده از آدرس گره بعدی که در گره موجود است به گره بعد می‌رود. این کار تا زمانی که به آخر لیست پیوندی برسیم ادامه خواهد یافت. سپس با استفاده از داده یک گره ساخته می‌شود و آدرس گره بعدی گره‌ی آخر برابر با آدرس گره‌ی آخر قرار داده می‌شود. اینگونه گره‌ای جدید به لیست اضافه می‌شود.

 

تابع بعدی، تابع جست و جو درون لیست پیوندی است. با این تابع می‌تواینم درون لینک لیست را برای پیدا کردن یک گره با داده‌ای مشخص بگردیم. برای این کار متد زیر را برای کلاس لیست پیوندی نوشته‌ایم:

def search(self, data):
        # counter
        counter = 0

        # start form head of linked list
        pointer = self.head

        while pointer is not None:
            # count
            counter += 1

            if pointer.get_data() == data:
                # if found
                return counter-1, pointer
            # go next node
            pointer = pointer.get_next()

        # If not found
        return None, None

مانند تابع‌های قبل از گره‌ای نخست شروع می‌کنیم و مرتب به گره‌ی بعد می‌رویم تا زمانی که به آخر لیست پیوندی برسیم و یا گره‌ای را پیدا کنیم که داده‌های مد نظر را داشته باشد. در صورت پیدا شدن اندیس گره در لیست پیوندی و یک اشاره‌گر به گره برگردانده می‌شود.

تابع بعدی، تابع حذف یک گره با استفاده از اندیس آن گره در لیست پیوندی است. برای این کار متد زیر را نوشته‌ایم:

def delete(self, node_index):

        # counter
        counter = -1

        # pointer to the previous node
        pre_pointer = None

        # start form head of linked list
        pointer = self.head

        while counter + 1 != node_index and pointer is not None:

            # set previous pointer
            pre_pointer = pointer

            # go next node
            pointer = pointer.get_next()

            # increment counter
            counter += 1

        if pointer is self.head:
            # delete first node
            self.head = pointer.get_next()
            del pointer
        elif pointer.get_next() is None:
            # delete last object
            pre_pointer.set_next_node(node=None)
            del pointer
        else:
            # node in middle
            pre_pointer.set_next_node(node=pointer.get_next())
            del pointer

برای این کار ابتدا یک اشاره گر به گره اول قرار می‌دهیم. هر بار یک گره به جلو می‌رویم تا به گره‌ با اندیس مورد نظر برسیم. همچنین هر بار که اشاره‌گر را جلو می‌بریم یک اشاره گر دیگر استفاده می‌کنیم تا مقدار قبلی اشاره‌گر را نگه داریم. بعد از پیدا کردن گره مورد نظر، با توجه به موقعیت گره که می‌تواند در ابتدا، وسط و انتهای لیست پیوندی باشد عمل می‌‌کنیم. اگر گره در ابتدا باشد اشاره‌گر لیست پیوندی که به خانه اول اشاره می‌کند باید عوض شود تا به خانه بعدی اشاره کند. در صورتی که گره مورد نظر، گره انتهایی باشد، اشاره‌گر به گره بعدی، گره یکی به آخر را باید برابر با None و یا پوچ قرار دهیم. در صورتی که گره مورد نظر یک گره در اواسط لیست پیوندی باشد، باید گره قبل از آن را به گره بعد از آن وصل کرد. مانند شکل زیر:

 

متد آخر نیز برای چاپ اطلاعات درون لیست پیوندی به ترتیب محل قرارگیری آن‌ها درون لیست پیوندی است:

def print(self):
        # counter
        counter = 0
        # start form head of linked list
        pointer = self.head

        while pointer is not None:
            # count
            counter += 1

            # print data of Node
            print("Node {}\'th Data: {}".format(counter, pointer.get_data()))

            # go to next node
            pointer = pointer.get_next()

        return counter

 

اکنون که کد لیست پیوندی در پایتون را نوشتیم، متد‌های نوشته شده را تست می‌کنید. ابتدا یک شی از لیست پیوندی ایجاد می‌کنیم:

# create an object
    ll_obj = LinkedList()

سپس یک گره (Node) به لیست پیوندی اضافه می‌کنیم و بعد از آن لیست‌پیوندی و اندازه آن را چاپ می‌کنیم:

# add 1'th node to linked list
    ll_obj.insert_node(data=[3, 7])

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)

خروجی این قسمت از کد برابر می‌شود با

Node 1'th Data: [3, 7]
Size of Linked List: 1

در ادامه ۵ گره دیگر با مقدارهای متفاوت به لیست پیوندی اضافه می‌کنیم و در گام لیست‌ پیوندی و اندازه‌اش را چاپ می‌کنیم:

#########################################################
    # add 2'th node to linked list
    ll_obj.insert_node(data="open-mind.ir")

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 3'th node to linked list
    ll_obj.insert_node(data=['Rostam', 'Ferdosi', 'Bahram'])

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 4'th node to linked list
    ll_obj.insert_node(data={'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'})

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 5'th node to linked list
    ll_obj.insert_node(data=3.14)

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 6'th node to linked list
    ll_obj.insert_node(data=[[6, 7], [2, 4]])

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################

خروجی این تکه کد برابر زیر است:

====================
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Size of Linked List: 2

====================
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Size of Linked List: 3

====================
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 4'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Size of Linked List: 4

====================
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 4'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 5'th Data: 3.14
Size of Linked List: 5
====================
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 4'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 5'th Data: 3.14
Node 6'th Data: [[6, 7], [2, 4]]
Size of Linked List: 6

اکنون مقدار‌های مختلف را در لیست پیوندی جست‌وجو می‌کنیم تا اندیس گره‌های متناظر با آن‌ها را در صورت موجود بودن پیدا کنیم:

# search
    idx_in_ll, pointer = ll_obj.search(data=[1, 3])
    print('Search Result:')
    print('Index in Linked List {}.'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data=['Rostam', 'Ferdosi', 'Bahram'])
    print('Search Result:')
    print('Index in Linked List {}.'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data=3.14)
    print('Search Result:')
    print('Index in Linked List {}.'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data={'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'})
    print('Search Result:')
    print('Index in Linked List {}.\n'.format(idx_in_ll))
    print('=' * 20)

خروجی این تکه کد را در زیر مشاهده می‌کنید:

====================
Search Result:
Index in Linked List None.
====================
Search Result:
Index in Linked List 2.
====================
Search Result:
Index in Linked List 4.
====================
Search Result:
Index in Linked List 3.

اکنون نوبت تست عملگر حذف یک گره با استفاده از اندیس آن گره در لیست پیوندی است. به این منظور هر بار یک گره با اندیس مشخص را انتخاب می‌کنیم و آن را حذف می‌کنیم و لیست پیوندی قبل و بعد از حذف آن گره را در هر گام نشان می‌دهیم.

#########################################################
    # delete
    # print linked list
    print('Before delete 6\'th node')
    ll_obj.print()
    print("Size of Linked List: {}\n".format(ll_obj.size()))

    # delete 5'th node
    ll_obj.delete(node_index=5)

    # print linked list
    print('After delete 6\'th node')
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # delete
    # print linked list
    print('Before delete 1\'th node')
    ll_obj.print()
    print("Size of Linked List: {}\n".format(ll_obj.size()))

    # delete 5'th node
    ll_obj.delete(node_index=0)

    # print linked list
    print('After delete 1\'th node')
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # delete
    # print linked list
    print('Before delete 2\'th node')
    ll_obj.print()
    print("Size of Linked List: {}\n".format(ll_obj.size()))

    # delete 5'th node
    ll_obj.delete(node_index=1)

    # print linked list
    print('After delete 2\'th node')
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################

خروجی این تکه کد در زیر آورده شده است:

====================
Before delete 6'th node
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 4'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 5'th Data: 3.14
Node 6'th Data: [[6, 7], [2, 4]]
Size of Linked List: 6

After delete 6'th node
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 4'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 5'th Data: 3.14
Size of Linked List: 5

====================
Before delete 1'th node
Node 1'th Data: [3, 7]
Node 2'th Data: open-mind.ir
Node 3'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 4'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 5'th Data: 3.14
Size of Linked List: 5

After delete 1'th node
Node 1'th Data: open-mind.ir
Node 2'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 3'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 4'th Data: 3.14
Size of Linked List: 4

====================
Before delete 2'th node
Node 1'th Data: open-mind.ir
Node 2'th Data: ['Rostam', 'Ferdosi', 'Bahram']
Node 3'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 4'th Data: 3.14
Size of Linked List: 4

After delete 2'th node
Node 1'th Data: open-mind.ir
Node 2'th Data: {'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'}
Node 3'th Data: 3.14
Size of Linked List: 3

====================

 

خوب لیست پیوندیمان را در Python ایجاد کردیم و آن را تست کردیم. این لینک لیست یک نمونه ساده بود و حالا می‌توانید با آن سر و کله بزنید و امکانات بیشتری به آن اضافه کنید.

 

کد کلی برنامه لیست پیوندی در پایتون را در زیر مشاهده می‌فرمایید:

class Node:

    def __init__(self, data=None, next=None):
        # Data on node
        self.data = data

        # Next node
        self.next = next

    def set_data(self, data):
        self.data = data

    def set_next_node(self, node):
        self.next = node

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next


class LinkedList:

    def __init__(self, node=None):
        self.head = node

    def size(self):

        # counter
        counter = 0
        # start form head of linked list
        pointer = self.head

        while pointer is not None:
            # count
            counter += 1
            # go to next node
            pointer = pointer.get_next()

        return counter

    def insert_node(self, data):

        # start from head of linked list
        pointer = self.head

        # if linked list is empty
        if pointer is None:
            self.head = Node(data=data)
            return

        # find last node in the linked list
        while pointer.get_next() is not None:
            pointer = pointer.get_next()

        # link last node on list to new node
        pointer.set_next_node(Node(data=data))

    def search(self, data):
        # counter
        counter = 0

        # start form head of linked list
        pointer = self.head

        while pointer is not None:
            # count
            counter += 1

            if pointer.get_data() == data:
                # if found
                return counter-1, pointer
            # go next node
            pointer = pointer.get_next()

        # If not found
        return None, None

    def delete(self, node_index):

        # counter
        counter = -1

        # pointer to the previous node
        pre_pointer = None

        # start form head of linked list
        pointer = self.head

        while counter + 1 != node_index and pointer is not None:

            # set previous pointer
            pre_pointer = pointer

            # go next node
            pointer = pointer.get_next()

            # increment counter
            counter += 1

        if pointer is self.head:
            # delete first node
            self.head = pointer.get_next()
            del pointer
        elif pointer.get_next() is None:
            # delete last object
            pre_pointer.set_next_node(node=None)
            del pointer
        else:
            # node in middle
            pre_pointer.set_next_node(node=pointer.get_next())
            del pointer

    def print(self):
        # counter
        counter = 0
        # start form head of linked list
        pointer = self.head

        while pointer is not None:
            # count
            counter += 1

            # print data of Node
            print("Node {}\'th Data: {}".format(counter, pointer.get_data()))

            # go to next node
            pointer = pointer.get_next()

        return counter


if __name__ == '__main__':
    # create an object
    ll_obj = LinkedList()

    #########################################################
    # add 1'th node to linked list
    ll_obj.insert_node(data=[3,7])

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 2'th node to linked list
    ll_obj.insert_node(data="open-mind.ir")

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 3'th node to linked list
    ll_obj.insert_node(data=['Rostam', 'Ferdosi', 'Bahram'])

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 4'th node to linked list
    ll_obj.insert_node(data={'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'})

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 5'th node to linked list
    ll_obj.insert_node(data=3.14)

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # add 6'th node to linked list
    ll_obj.insert_node(data=[[6, 7], [2, 4]])

    # print linked list
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data=[1, 3])
    print('Search Result:')
    print('Index in Linked List {}.'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data=['Rostam', 'Ferdosi', 'Bahram'])
    print('Search Result:')
    print('Index in Linked List {}.'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data=3.14)
    print('Search Result:')
    print('Index in Linked List {}.'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # search
    idx_in_ll, pointer = ll_obj.search(data={'Iran': 'Tehran', 'Sweden': 'Stockholm', 'India': 'New Delhi'})
    print('Search Result:')
    print('Index in Linked List {}.\n'.format(idx_in_ll))
    print('=' * 20)
    #########################################################
    # delete
    # print linked list
    print('Before delete 6\'th node')
    ll_obj.print()
    print("Size of Linked List: {}\n".format(ll_obj.size()))

    # delete 5'th node
    ll_obj.delete(node_index=5)

    # print linked list
    print('After delete 6\'th node')
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # delete
    # print linked list
    print('Before delete 1\'th node')
    ll_obj.print()
    print("Size of Linked List: {}\n".format(ll_obj.size()))

    # delete 5'th node
    ll_obj.delete(node_index=0)

    # print linked list
    print('After delete 1\'th node')
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################
    # delete
    # print linked list
    print('Before delete 2\'th node')
    ll_obj.print()
    print("Size of Linked List: {}\n".format(ll_obj.size()))

    # delete 5'th node
    ll_obj.delete(node_index=1)

    # print linked list
    print('After delete 2\'th node')
    ll_obj.print()

    # Print size of Linked List
    print("Size of Linked List: {}\n".format(ll_obj.size()))
    print('=' * 20)
    #########################################################

 

 

 

 

 

نوشته لیست پیوندی در پایتون – Linked List in Python اولین بار در اوپن مایند. پدیدار شد.



برچسب ها : ,