【python】鏈表

鏈表

鏈表由包含數值域和指針域的數據節點構成。

單向鏈表

每個數據節點包含一個指向下一個節點的指針。

代碼示例:
#!/usr/bin/env python
# encoding: utf-8


# TODO: 定義單向鏈表節點
class Node(object):
    def __init__(self, item=None):
        '''
        :param item: 記錄當前節點值
        :param next: 記錄下一個節點
        :return: None
        '''
        self.item = item
        self.next = None

    def __repr__(self):
        return repr(self.item)


# TODO: 定義單向鏈表
class SLinkList(object):
    def __init__(self):
        '''
        :param head: 頭節點
        :param last: 尾節點
        :param length: 鏈表長度
        :return:
        '''
        self.head = None
        self.last = None
        self.curNode = None
        self.length = 0
        self.index = 0

    # 顯示內容
    def __repr__(self):
        return repr(self.view())

    # 獲取鏈表長度,適用len方法
    def __len__(self):
        '''
        count = 0
        curNode = self.head
        while curNode:
            count += 1
            curNode = curNode.next
        return count
        '''
        return self.length

    # 使鏈表可索引和切片
    def __getitem__(self, index):
        print(type(index))
        try:
            return self.view()[index]
        except IndexError as e:
            raise e

    # 標示可迭代
    def __iter__(self):
        return self

    # 適用next方法,實現可迭代
    def __next__(self):
        if not self.head or self.index >= self.length:
            raise StopIteration
        else:
            if not self.curNode:
                self.curNode = self.head
            curItem = self.curNode.item
            self.curNode = self.curNode.next
            self.index += 1
        return curItem

    # 判斷鏈表是否爲空
    def isEmpty(self):
        return self.head is None

    # 頭部添加節點
    def add(self, item):
        newNode = Node(item)
        if self.isEmpty():
            self.head = newNode
            self.last = newNode
        else:
            newNode.next = self.head
            self.head = newNode
        self.length += 1
        return self

    # 尾部添加節點
    def append(self, item):
        newNode = Node(item)
        if self.isEmpty():
            self.head = newNode
        else:
            self.last.next = newNode
        self.last = newNode
        self.length += 1
        return self

    # 指定位置插入節點
    def insert(self, pos, item):
        if pos <= 0:
            self.add(item)
        elif pos >= self.length:
            self.append(item)
        else:
            newNode = Node(item)
            curNode = self.head
            count = 0
            while count != pos:
                count += 1
                preNode = curNode
                curNode = curNode.next
            preNode.next = newNode
            newNode.next = curNode
            self.length += 1
        return self

    # 刪除元素
    def remove(self, item):
        if self.isEmpty() or not self.find(item):
            return self
        else:
            curNode = self.head
            curItem = curNode.item
            if curItem == item and self.length == 1:
                self.head = None
                self.last = None
            elif curItem == item and self.length > 1:
                self.head = curNode.next
            else:
                while item != curItem:
                    preNode = curNode or None
                    curNode = curNode.next or None
                    nextNode = None if not curNode else curNode.next
                    curItem = None if not curNode else curNode.item
                preNode.next = nextNode
            self.length -= 1

    # 查找元素,返回元素節點
    def find(self, item):
        curNode = self.head
        curItem = curNode.item
        pos = 0
        if curItem == item:
            return curNode
        else:
            pos += 1
            while curItem != item:
                pos += 1
                curNode = curNode.next
                if not curNode:
                    break
                curItem = curNode.item
        return curNode

    # 清空鏈表
    def clear(self):
        self.length = 0
        self.head = None
        self.last = None

    # 查看鏈表值
    def view(self):
        items = []
        curNode = self.head
        while curNode:
            items.append(curNode.item)
            curNode = curNode.next
        return items


if __name__ == '__main__':
    link = SLinkList()
    print(link.isEmpty())
    link.add(1)
    link.add(2)
    print(link.isEmpty())
    print(link)
    link.append(5)
    link.append(9)
    print(link)
    link.insert(0, 6)
    link.insert(3, 7)
    print(link)
    link.insert(11, 7)
    print(link)
    link.insert(1, 8)
    print(link)
    print(link[1:3])
    print(link[1])
    print(len(link))
    link.remove(6)
    print(link)
    from collections import Iterable, Iterator
    print(isinstance(link, Iterable))
    print(link.find(2).next)
    link.remove(5)
    link.remove(5)
    link.remove(2)
    link.remove(7)
    print(link)
    print('last=', link.last)
    # for i, x in enumerate(link):
    #     print(i, x)
輸出結果爲:
True
False
[2, 1]
[2, 1, 5, 9]
[6, 2, 1, 7, 5, 9]
[6, 2, 1, 7, 5, 9, 7]
[6, 8, 2, 1, 7, 5, 9, 7]
<class 'slice'>
[8, 2]
<class 'int'>
8
8
[8, 2, 1, 7, 5, 9, 7]
True
1
[8, 1, 9, 7]
last= 7

雙向鏈表

每個數據節點包含一個指向下一節點的指針和一個指向上一節點的指針。

代碼示例:
#!/usr/bin/env python
# encoding: utf-8

# TODO: 定義雙向鏈表節點
class Node(object):
    def __init__(self, item=None):
        '''
        :param item: 記錄當前節點值
        :param prev: 記錄前一個節點
        :param next: 記錄下一個節點
        :return: None
        '''
        self.item = item
        self.prev = None
        self.next = None

    def __repr__(self):
        return repr(self.item)


# TODO: 定義雙向鏈表
class DLinkList(object):
    def __init__(self):
        '''
        :param head: 頭節點
        :param last: 尾節點
        :param length: 鏈表長度
        :return:
        '''
        self.head = None
        self.last = None
        self.curNode = None
        self.length = 0
        self.index = 0

    # 顯示內容
    def __repr__(self):
        '''
        repr類似給原有對象加引號;
        str則是將原對象轉換成字符串格式。
        '''
        return repr(self.view())

    # 獲取鏈表長度,適用len方法
    def __len__(self):
        '''
        count = 0
        curNode = self.head
        while curNode:
            count += 1
            curNode = curNode.next
        return count
        '''
        return self.length

    # 使鏈表可索引和切片
    def __getitem__(self, index):
        # index爲<class 'slice'>或者<class 'int'>類型
        # print(type(index))
        try:
            return self.view()[index]
        except IndexError as e:
            raise e

    # 標示可迭代
    def __iter__(self):
        return self

    # 適用next方法,實現可迭代
    def __next__(self):
        # StopIteration拋出越界異常,否則死循環
        if not self.head or self.index >= self.length:
            raise StopIteration
        else:
            if not self.curNode:
                self.curNode = self.head
            curItem = self.curNode.item
            self.curNode = self.curNode.next
            self.index += 1
        return curItem

    # 判斷鏈表是否爲空
    def isEmpty(self):
        return self.head is None

    # 頭部添加節點
    def add(self, item):
        newNode = Node(item)
        newNode.prev = None
        if self.isEmpty():
            self.head = newNode
            self.last = newNode
        else:
            newNode.next = self.head
            self.head = newNode
        self.length += 1
        return self

    # 尾部添加節點
    def append(self, item):
        newNode = Node(item)
        if self.isEmpty():
            self.head = newNode
        else:
            self.last.next = newNode
        newNode.prev = self.last
        self.last = newNode
        self.length += 1
        return self

    # 指定位置插入節點
    def insert(self, pos, item):
        if pos <= 0:
            self.add(item)
        elif pos >= self.length:
            self.append(item)
        else:
            newNode = Node(item)
            curNode = self.head
            count = 0
            while count < pos:
                count += 1
                preNode = curNode
                curNode = curNode.next

            preNode.next = newNode
            newNode.prev = preNode
            newNode.next = curNode
            curNode.prev = newNode

            self.length += 1
        return self

    # 刪除元素
    def remove(self, item):
        if self.isEmpty() or not self.find(item):
            return self
        else:
            curNode = self.head
            curItem = curNode.item
            if curItem == item and self.length == 1:
                self.head = None
                self.last = None
            elif curItem == item and self.length > 1:
                self.head = curNode.next
                if self.head:
                    self.head.prev = None
            else:
                while item != curItem:
                    preNode = curNode or None
                    curNode = curNode.next or None
                    nextNode = None if not curNode else curNode.next
                    curItem = None if not curNode else curNode.item
                preNode.next = nextNode
                if nextNode:
                    nextNode.prev = preNode
            self.length -= 1

    # 查找元素,返回元素節點
    def find(self, item):
        curNode = self.head
        curItem = curNode.item
        pos = 0
        if curItem == item:
            return curNode
        else:
            pos += 1
            while curItem != item:
                pos += 1
                curNode = curNode.next
                if not curNode:
                    break
                curItem = curNode.item
        return curNode

    # 清空鏈表
    def clear(self):
        self.length = 0
        self.head = None
        self.last = None

    # 查看鏈表值
    def view(self):
        items = []
        curNode = self.head
        while curNode:
            items.append(curNode.item)
            curNode = curNode.next
        return items


if __name__ == '__main__':
    from collections import Iterable

    link = DLinkList()
    print(link.isEmpty())
    link.append(1)
    link.add(2)
    link.add(3)
    print(link)
    link.append(4)
    print(link)
    link.insert(0, 'a')
    link.insert(2, 'b')
    print(link)
    link.insert(9, 'c')
    print(link.isEmpty())
    link.remove(3)
    link.remove(4)
    link.remove('2')
    print(link)
    print(link[2])
    print(link[1:3])
    print('last=', link.last)
輸出結果爲:
True
[3, 2, 1]
[3, 2, 1, 4]
['a', 3, 'b', 2, 1, 4]
False
['a', 'b', 2, 1, 'c']
2
['b', 2]
last= 'c'

循環鏈表

雙向鏈表中,head節點的prev指針指向last節點,last節點的next指針指向head節點。

代碼示例:
略!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章