實用:pthon中單向鏈表和雙向鏈表的實現(附帶容器化解決)

單向:

class Node:
    def __init__(self,value,next=None,pre=None):#Todo DoubleLinklist
        self.val = value
        self.next = next
        self.pre = pre
    def __str__(self):
        return self.val

class Linkedlist:
    def __init__(self):
        self.nodes = [] # 對於不需要插入的列表來說,檢索方便,但是如果需要插入,remove卻不合適
        self.head = None
        self.tail = None

    def append(self,value):
        node = Node(value)
        if self.tail == None:
            self.head = node
            self.tail = node
        else:
            self.tail.next = node
        self.nodes.append(node)
        self.tail = node

    def iternodes(self,reversed=False): #Todo DoubleLinklist
        while self.head:
            yield self.head
            self.head = self.head.next

    def __getitem__(self, item):
        return self.nodes[item]

    def __len__(self):
        return len(self.nodes)

ll = Linkedlist()
ll.append('a')
ll.append('b')
gn = ll.iternodes()
print(type(gn))
for i in gn:
    print(i)

print(ll[1])# __getitem__實現的功能
print(len(ll))# __len__實現的功能

運行結果:

<class 'generator'>
a          # __str__實現的功能
b          # __str__實現的功能
b          # __getitem__實現的功能
2          # __len__實現的功能

雙向:

class SingleNode:
    '''代表一個節點'''
    def __init__(self,val,next=None,prev=None):
        self.val = val    #node實例值
        self.next = next    #node對象
        self.prev = prev    #node對象

    def __str__(self):
        return str(self.val)

    def __repr__(self):
        return str(self.val)

class Linkedlist:
    '''容器類,某種方式存儲一個個節點'''
    def __init__(self):
        self.head = None
        self.tail = None

    def append(self,val):
        node = SingleNode(val)
        if self.head is None:
            self.head = node
        else:
            node.prev = self.tail
            self.tail.next = node

        self.tail = node

    def iternodes(self,reverse=False):
        current = self.tail if reverse else self.head
        while current:
            yield current
            current = current.prev if reverse else current.next

    def pop(self):
        if self.tail is None:
            raise Exception('Empty')
        tail = self.tail
        prev = tail.prev
        if prev is None:
            self.head = None
            self.tail = None
        else:
            self.tail = prev
            prev.next = None
        return tail.val

    def getitem(self,index):
        if index < 0:
            return None
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is not None:
            return current

    def insert(self,index,val):
        if index < 0:
            raise Exception('Error')
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is None:
            self.append(val)
            return

        prev = current.prev

        node = SingleNode(val)
        if prev is None:
            self.head = node
            current.prev = node
            node.next = current
        else:
            node.prev = prev
            node.next = current
            current.prev = node
            prev.next = node

ll = Linkedlist()
node = SingleNode(1)
ll.append(node)
node = SingleNode(2)
ll.append(node)
node = SingleNode(3)
ll.append(node)
node = SingleNode('abc')#用於pop測試
ll.append(node)

ll.pop()

ll.insert(4,4)
ll.insert(5,5)


for node in ll.iternodes(reverse=True):
    print(node)

print(ll.getitem(0))

運行結果:

5
4
3
2
1
1

容器化的解決

from functools import partial
class SingleNode:
    '''代表一個節點'''
    def __init__(self,val,next=None,prev=None):
        self.val = val    #node實例值
        self.next = next    #node對象
        self.prev = prev    #node對象

    def __str__(self):
        return str(self.val)

    def __repr__(self):
        return str(self.val)

class Linkedlist:
    '''容器類,某種方式存儲一個個節點'''
    def __init__(self):
        self.head = None
        self.tail = None
        self.size = 0
        self.list = []

    def append(self,val):
        node = SingleNode(val)
        if self.head is None:
            self.head = node
        else:
            node.prev = self.tail
            self.tail.next = node

        self.tail = node
        self.size += 1
        #列表操作
        self.list.append(node)


    def pop(self):
        if self.tail is None:
            raise Exception('Empty')
        tail = self.tail
        prev = tail.prev
        if prev is None:
            self.head = None
            self.tail = None
        else:
            self.tail = prev
            prev.next = None
        self.size -= 1
        #列表操作
        self.list.pop()

        return tail.val

    def getitem(self,index):
        if index < 0:
            return None
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break

        if current is not None:
            print(current.val)
        else:
            raise IndexError('Out of range')
        # return self.list[index].val

    def setitem(self,index,value):
        if index < 0:
            return None
        current = None
        for i, node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is not None:
            current.val = value
            return current.val

    def insert(self,index,val):
        if index < 0:
            raise Exception('Error')
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is None:
            self.append(val)
            return

        prev = current.prev

        node = SingleNode(val)
        if prev is None:
            self.head = node
        else:
            node.prev = prev
            prev.next = node
        node.next = current
        current.prev = node

        self.list.insert(index,node)

    def remove(self,index):
        if self.tail is None:
            raise Exception('Empty')
        if index < 0:
            raise ValueError('Wrong Index{}'.format(index))
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is None:
            raise ValueError('Wrong Index {} ,Out of boundary'.format(index))

        prev = current.prev
        next = current.next

        if prev is None and next is None:
            self.head = None
            self.tail = None
        elif prev is None:
            self.head = index
            next.prev = None
        elif next is None:
            self.tail = prev
            prev.next = None
        else:
            prev.next = next
            next.prev = prev

        del current
        self.size -= 1
        return self.list.pop(index)

    def iternodes(self, reverse=False):
        current = self.tail if reverse else self.head
        while current:
            yield current
            current = current.prev if reverse else current.next

    def __len__(self):
        return len(self.list)

    def __getitem__(self, index): # 如果沒有__iter__則調用此方法進行迭代
        print(self.list[index].val)

    def __setitem__(self, index, value):
        self.list[index].val = value

    # def __iter__(self):
    #     return self.iternodes(reverse=True)

    # def __iter__(self):
    #     iternodes = partial(self.iternodes,reverse=True)
    #     return iternodes()

    # __iter__ = lambda self:self.iternodes(reverse=False)
    __iter__ = lambda self:partial(self.iternodes,reverse=True)()

#增
ll = Linkedlist()
ll.append(123)
ll.append(456)
ll.append(789)
ll[0]
ll[1]
ll[2]
ll.getitem(0)
ll.getitem(1)
ll.getitem(2)
print('====================================')

print(type(ll.iternodes()))
for i in ll.iternodes():
    print(i)
print('====================================')

ll[0] = 'a'
ll.setitem(1,'b')
ll.setitem(2,'c')
ll[0]
ll[1]
ll[2]
ll.getitem(0)
ll.getitem(1)
ll.getitem(2)
print('====================================')

print(type(ll.iternodes()))
for i in ll.iternodes():
    print(i)
print('====================================')

#刪--pop
print('popvalue = ',ll.pop())
for i in ll.iternodes():
    print(i)

#刪--remove
print('removevalue = ',ll.remove(1))
for i in ll.iternodes():
    print(i)
print('====================================')

#改
ll.setitem(0,'hello')
ll.append('the')
ll.insert(2,'world')
ll.getitem(0)
ll[1]
ll[2]
ll[2] = 'world!!!'
for i in ll.iternodes():
    print(i)
print('====================================')

#查
ll[0]
ll.getitem(1)
print(len(ll))
print('====================================')
print(type(ll))
for i in ll: #省略了.iternodes()
    print(i)
print(ll.size)

print('====================================')
print(ll.__dict__)
print(Linkedlist.__dict__)

運行結果:

123
456
789
123
456
789
====================================
<class 'generator'>
123
456
789
====================================
a
b
c
a
b
c
====================================
<class 'generator'>
a
b
c
====================================
popvalue =  c
a
b
removevalue =  b
a
====================================
hello
the
world
hello
the
world!!!
====================================
hello
the
3
====================================
<class '__main__.Linkedlist'>
world!!!
the
hello
3
====================================
{'size': 3, 'head': hello, 'tail': world!!!, 'list': [hello, the, world!!!]}
{'__getitem__': <function Linkedlist.__getitem__ at 0x7f6f6cd9ef28>, '__len__': <function Linkedlist.__len__ at 0x7f6f6cd9eea0>, 'remove': <function Linkedlist.remove at 0x7f6f6cd9ed90>, '__dict__': <attribute '__dict__' of 'Linkedlist' objects>, 'insert': <function Linkedlist.insert at 0x7f6f6cd9ed08>, 'getitem': <function Linkedlist.getitem at 0x7f6f6cd9ebf8>, '__module__': '__main__', '__iter__': <function Linkedlist.<lambda> at 0x7f6f6cdaa0d0>, '__doc__': '容器類,某種方式存儲一個個節點', 'setitem': <function Linkedlist.setitem at 0x7f6f6cd9ec80>, 'iternodes': <function Linkedlist.iternodes at 0x7f6f6cd9ee18>, 'append': <function Linkedlist.append at 0x7f6f6cd9eae8>, 'pop': <function Linkedlist.pop at 0x7f6f6cd9eb70>, '__init__': <function Linkedlist.__init__ at 0x7f6f6cd9ea60>, '__weakref__': <attribute '__weakref__' of 'Linkedlist' objects>, '__setitem__': <function Linkedlist.__setitem__ at 0x7f6f6cdaa048>}

非容器化解決上述增刪改查

from functools import partial
class SingleNode:
    '''代表一個節點'''
    def __init__(self,val,next=None,prev=None):
        self.val = val    #node實例值
        self.next = next    #node對象
        self.prev = prev    #node對象

    def __str__(self):
        return str(self.val)

    def __repr__(self):
        return str(self.val)

class Linkedlist:
    '''容器類,某種方式存儲一個個節點'''
    def __init__(self):
        self.head = None
        self.tail = None
        self.size = 0

    def append(self,val):
        node = SingleNode(val)
        if self.head is None:
            self.head = node
        else:
            node.prev = self.tail
            self.tail.next = node

        self.tail = node
        self.size += 1

    def pop(self):
        if self.tail is None:
            raise Exception('Empty')
        tail = self.tail
        prev = tail.prev
        if prev is None:
            self.head = None
            self.tail = None
        else:
            self.tail = prev
            prev.next = None
        self.size -= 1

        return tail.val

    def insert(self,index,val):
        if index < 0:
            raise Exception('Error')
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is None:
            self.append(val)
            return

        prev = current.prev

        node = SingleNode(val)
        if prev is None:
            self.head = node
        else:
            node.prev = prev
            prev.next = node
        node.next = current
        current.prev = node

    def remove(self,index):
        if self.tail is None:
            raise Exception('Empty')
        if index < 0:
            raise ValueError('Wrong Index{}'.format(index))
        current = None
        for i,node in enumerate(self.iternodes()):
            if i == index:
                current = node
                break
        if current is None:
            raise ValueError('Wrong Index {} ,Out of boundary'.format(index))

        prev = current.prev
        next = current.next

        if prev is None and next is None:
            self.head = None
            self.tail = None
        elif prev is None:
            self.head = index
            next.prev = None
        elif next is None:
            self.tail = prev
            prev.next = None
        else:
            prev.next = next
            next.prev = prev

        del current
        self.size -= 1

    def iternodes(self, reverse=False):
        current = self.tail if reverse else self.head
        while current:
            yield current
            current = current.prev if reverse else current.next

    def __len__(self):
        return self.size

    def __getitem__(self, index): # 如果沒有__iter__則調用此方法進行迭代
        for i,node in enumerate(self.iternodes(False if index >=0 else True),0 if index >=0 else 1):
            if i == abs(index):
                return node

    def __setitem__(self, index, value):
        self[index].val = value

    __iter__ = lambda self:partial(self.iternodes,reverse=True)()

#增
ll = Linkedlist()
ll.append(123)
ll.append(456)
ll.append(789)
print(ll[0])
print(ll[1])
print(ll[2])
print('====================================')

print(type(ll.iternodes()))
for i in ll.iternodes():
    print(i)
print('====================================')

ll[0] = 'a'
print(ll[0])
print(ll[1])
print(ll[2])
print('====================================')

print(type(ll))
for i in ll:
    print(i)
print('====================================')

#刪--pop
print('popvalue = ',ll.pop())
for i in ll.iternodes():
    print(i)

#刪--remove
print('removevalue = ',ll.remove(1))
for i in ll.iternodes():
    print(i)
print('====================================')

#改
ll.append('the')
ll.insert(2,'world')
print(ll[0])
print(ll[1])
ll[2] = 'world!!!'
for i in ll:
    print(i)
print('====================================')

#查
print(ll[0])
print(len(ll))
print('====================================')

print(type(ll))
for i in ll: #省略了.iternodes()
    print(i)
print(ll.size)
print('====================================')

print(ll.__dict__)
print(Linkedlist.__dict__)

運行結果:

123
456
789
====================================
<class 'generator'>
123
456
789
====================================
a
456
789
====================================
<class '__main__.Linkedlist'>
789
456
a
====================================
popvalue =  789
a
456
removevalue =  None
a
====================================
a
the
world!!!
the
a
====================================
a
3
====================================
<class '__main__.Linkedlist'>
world!!!
the
a
3
====================================
{'tail': world!!!, 'size': 3, 'head': a}
{'pop': <function Linkedlist.pop at 0x7ffb91ac9bf8>, '__len__': <function Linkedlist.__len__ at 0x7ffb91ac9e18>, '__getitem__': <function Linkedlist.__getitem__ at 0x7ffb91ac9ea0>, '__dict__': <attribute '__dict__' of 'Linkedlist' objects>, 'iternodes': <function Linkedlist.iternodes at 0x7ffb91ac9d90>, '__doc__': '容器類,某種方式存儲一個個節點', '__init__': <function Linkedlist.__init__ at 0x7ffb91ac9ae8>, '__weakref__': <attribute '__weakref__' of 'Linkedlist' objects>, '__module__': '__main__', '__setitem__': <function Linkedlist.__setitem__ at 0x7ffb91ac9f28>, '__iter__': <function Linkedlist.<lambda> at 0x7ffb91ad5048>, 'insert': <function Linkedlist.insert at 0x7ffb91ac9c80>, 'remove': <function Linkedlist.remove at 0x7ffb91ac9d08>, 'append': <function Linkedlist.append at 0x7ffb91ac9b70>}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章