DoubleLinkedList双向链表容器化

  

借助list

class SimplexNode:
    def __init__(self,item,prev=None,post=None):
        self.item=item
        self.prev=None
        self.post=None
    def __repr__(self):
        # return 'item: {} prev: {} post: {}'.format(self.item,str(self.prev),str(self.post))
        return 'item: {}'.format(self.item)
class DoubleLinkedList:
    def __init__(self,head=None,tail=None,size=0):
        self.head=head
        self.tail=tail
        self.size=size
        self.nodes=[]

    def append(self,item):
        node=SimplexNode(item)
        if self.head is None:
            self.head=node
        else:
            self.tail.post=node
            node.prev=self.tail
        self.tail=node
        self.nodes.append(node)

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

    def insert(self,index,item): # implementation of position insertion
        if index<0:
            raise IndexError('{} is negative'.format(index))
        datum=None # 记录插入位置的node
        for i,node in enumerate(self.iternodes()):
            if i==index:
                datum=node
                break

        if datum is None: # index out of range OR instance is empty
            self.append(item)
            return
        node=SimplexNode(item)
        prev=datum.prev

        if prev is None: # index==0
            self.head=node
        else:
            # prev <=> node <=> datum
            prev.post=node
            node.prev=prev
        node.post=datum
        datum.prev=node

        self.nodes.insert(index,node)

    def pop(self):
        if self.tail is None:
            raise Exception('{} is emtpy!'.format(self))
        datum=self.tail # 保存变量
        prev=self.tail.prev
        if prev is None: # self has one element
            self.head=None
            self.tail=None
        else:
            prev.post=None
            self.tail=prev
        self.nodes.pop()
        del datum
        return datum.item

    def remove(self,index=0):
        if self.tail is None:
            raise Exception('{} is empty!'.format(self))
        if index<0:
            raise IndexError('{} is negative!'.format(index))
        datum=None
        for i,node in enumerate(self.iternodes()):
            if i==index:
                datum=node
                break

        if datum is None:
            raise IndexError('{} out of range'.format(index))
        # prev <=> datum <=> post
        prev=datum.prev
        post=datum.post
        if prev is None and post is None: # self has one element
            self.head=None
            self.tail=None
        elif prev is None: # index==0
            post.prev=None
            self.head=post
        elif post is None:
            prev.post=None
            self.tail=prev
        else:
            prev.post=post
            post.head=prev

        del datum
        self.nodes.pop(index)

    def __len__(self):
        return len(self.nodes)
    def __getitem__(self,item):
        return self.nodes[item]
    def __setitem__(self,key,value):
        # self.nodes[key].item=value
        self[key].item=value
    def __iter__(self,reverse=False): # 需要生成器对象,无法传递参数
        return self.iternodes(reverse=False)


b=DoubleLinkedList()
for m in range(5):
    b.append(m)
print(b.nodes)
b.insert(1,88)
# b.remove()
b[1]=999
for m in b.iternodes(reverse=False):
    print(m)
for m in b:
    print(m)

# bb=DoubleLinkedList()
# bb.pop()

 

NoList

from functools import partial
class SimplexNode:
    def __init__(self,item,prev=None,post=None):
        self.item=item
        self.prev=None
        self.post=None
    def __repr__(self):
        # return 'item: {} prev: {} post: {}'.format(self.item,str(self.prev),str(self.post))
        return 'item: {}'.format(self.item)
class DoubleLinkedList:
    def __init__(self,head=None,tail=None,size=0):
        self.head=head
        self.tail=tail
        self.size=size
        self.nodes=[]

    def append(self,item):
        node=SimplexNode(item)
        if self.head is None:
            self.head=node
        else:
            self.tail.post=node
            node.prev=self.tail
        self.tail=node
        self.size+=1
        self.nodes.append(node)

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

    def insert(self,index,item): # implementation of position insertion
        if index<0:
            raise IndexError('{} is negative'.format(index))
        datum=None # 记录插入位置的node
        for i,node in enumerate(self.iternodes()):
            if i==index:
                datum=node
                break

        if datum is None: # index out of range OR instance is empty
            self.append(item)
            return
        node=SimplexNode(item)
        prev=datum.prev

        if prev is None: # index==0
            self.head=node
        else:
            # prev <=> node <=> datum
            prev.post=node
            node.prev=prev
        node.post=datum
        datum.prev=node
        self.size+=1
        self.nodes.insert(index,node)

    def pop(self):
        if self.tail is None:
            raise Exception('{} is emtpy!'.format(self))
        datum=self.tail # 保存变量
        prev=self.tail.prev
        if prev is None: # self has one element
            self.head=None
            self.tail=None
        else:
            prev.post=None
            self.tail=prev
        self.nodes.pop()
        self.size-=1
        return datum.item

    def remove(self,index=0):
        if self.tail is None:
            raise Exception('{} is empty!'.format(self))
        if index<0:
            raise IndexError('{} is negative!'.format(index))
        datum=None
        for i,node in enumerate(self.iternodes()):
            if i==index:
                datum=node
                break

        if datum is None:
            raise IndexError('{} out of range'.format(index))
        # prev <=> datum <=> post
        prev=datum.prev
        post=datum.post
        if prev is None and post is None: # self has one element
            self.head=None
            self.tail=None
        elif prev is None: # index==0
            post.prev=None
            self.head=post
        elif post is None:
            prev.post=None
            self.tail=prev
        else:
            prev.post=post
            post.head=prev
        self.size-=1
        del datum
        self.nodes.pop(index)

    def __len__(self):
        return len(self.nodes)
    def __len__(self):
        length=0
        datum=self.head
        while datum:
            length+=1
            datum=datum.post
        return length
    def __len__(self):
        return self.size

    def __getitem__(self,item):
        return self.nodes[item]
    def __getitem__(self,item):
        datum=None
        for i,node in enumerate(self.iternodes()):
            if i==item:
                datum=node
                break
        if datum is None:
            raise IndexError('{} out of range'.format(item))
        return datum.item
    def __getitem__(self,item):
        datum=None
        for i,node in enumerate(self.iternodes(False if item>=0 else True),0 if item>=0 else 1):
            if i==abs(item):
                datum=node
                break
        if datum is None:
            raise IndexError('{} out of range'.format(item))
        return datum.item

    def __setitem__(self,key,value):
        # self.nodes[key].item=value
        self[key].item=value
    def __setitem__(self,key,value):
        datum=None
        for i,node in enumerate(self.iternodes()):
            if i==key:
                datum=node
                break
        if datum is None:
            raise IndexError('linked list assignment index out of range')
        datum.item=value

    def __iter__(self,reverse=False): # 需要生成器对象,无法传递参数
        return self.iternodes(reverse=False)
    __iter__ = iternodes
    # __iter__ = partial(iternodes,reverse=True)

b=DoubleLinkedList()
for m in range(5):
    b.append(m)
print(b.nodes)
# b.insert(1,88)
# b.remove()
# b[1]=999
b.pop()
b[2]=777
for m in b.iternodes(reverse=False):
    print(m)
for m in b:
    print(m)

print(len(b))
print(b[-1])
print(b[3])
# bb=DoubleLinkedList()
# bb.pop()

 

posted @ 2020-10-08 15:34  ascertain  阅读(176)  评论(0编辑  收藏  举报