Python 单向链表、双向链表

用面向对象实现Linkedlist链表

单向链表实现append、iternodes

双向链表实现append、pop、insert、remove、iternodes

单向链表与双向链表

单向链表:

就好比小朋友在操场上,手拉着手。

分为数据域和指针域,指针域指向下一个数据,代码中分别用val 和next 表示。

整个链表用一个容器来存储,因为单向链表的数据虽然真正在内存中是散落的,但是某种关系可以把这些数据有序的组织起来,所以最合适的数据结构应该是列表。列表存储还支持追加和索引,容器在代码中用self.nodes=[] 表示。

如图:内存中的数据散落存储,5表示头head,9表示tail尾。

在链表为空时,需要定义头和尾,来表示前一个数据和下一个数据,头和尾在代码中用head 和tail 分别表示,前一个数据和下一个数据用prev 和next 分别表示。

0)链表数据为空时,顺序是:head --> tail,头和尾都可以用None表示;

1)链表中有一个数据时,顺序就变成了:  head--> 数据1 -->tail;

2)链表有两个数据时,顺序变成了:head -->数据1 -->数据2 -->tail;

3)链表有三个数据时,顺序变成了:head -->数据1 -->数据2 -->数据3 -->tail

以此类推。。。

代码:

class SingleNode:
    """代表一个节点"""

    def __init__(self, val, next=None, prev=None):
        self.val = val
        self.next = next
        self.prev = prev

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

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


class LinkedList:
    """容器类,某种方式存储一个个节点"""

    def __init__(self):
        self.nodes = []
        # 不需要插入的列表来说,检索方便,但是insert、remove不合适
        self.head = None
        self.tail = None

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

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

    def append(self, val):
        node = SingleNode(val)  # 实例化的一个新节点
        prev = self.tail
        if prev is None:
            self.head = node
        else:
            prev.next = node
        self.nodes.append(val)
        self.tail = node

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


ll = LinkedList()
ll.append(5)
ll.append(7)

for node in ll.iternodes():
    print(node)

print(ll[0])
print(ll[1])

  

  

双向链表:

0) append 尾部追加

1) pop 尾部弹出

2) insert 头部插入、中间插入、尾部插入

3) remove 头部删除、中间删除、尾部删除

class SingleNode:
    def __init__(self,val,next=None,prev=None):
        self.val = val
        self.next = next
        self.prev = prev

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

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


class LinkedList:
    def __init__(self):
        # self.nodes = []
        self.head = None
        self.tail = None

    def append(self,val):
        node = SingleNode(val)
        # prev = self.tail
        # if prev is None:
        if self.head is None: #only one
            self.head = node
        else: # >1
            self.tail.next = node
            node.prev = self.tail
        # self.nodes.append(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:  #0个数据
            raise Exception('Empty')
        tail = self.tail
        prev = tail.prev
        # next = tail.next #尾的下一个恒定为None
        if prev is None:  # =0, =1
            self.head = None
            self.tail = None
        else:  # >1
            self.tail = prev
            prev.next = None
        return tail.val

    def getitem(self,index):  #index不考虑传入str类型,全当做int类型
        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
        next = current.next

        node = SingleNode(val)
        if prev is None: #头部插入
            self.head = node
            # node.next = current
            # current.prev = node
        else:
            node.prev = prev
            # node.next = current  #和前面条件共同部分抽出来放后面
            # current.prev = node
            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: #Not found
            raise ValueError('Wrong Index {}. Out of boundary'.format(index))

        prev = current.prev
        next = current.next

        if prev is None and next is None: #only one node
            self.head = None
            self.tail = None
        elif prev is None: #删头部
            self.head = next
            next.prev = None
        elif next is None: #删尾部
            self.tail = prev
            prev.next = None
        else:  #中间
            prev.next = next
            next.prev = prev

        del current


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


ll = LinkedList()
ll.append('abc')
ll.append(1)
ll.append(2)
ll.append(3)
ll.append(4)
ll.append(5)
ll.append('def')

ll.insert(6,6)  #边界
ll.insert(7,7)   #尾部
ll.insert(8,8)  #尾部
ll.insert(0,123)  #头部
ll.insert(100,100)  #超界

# ll.remove(100)

# ll.pop()
# ll.pop()

for node in ll.iternodes(False): #False
    print(node)
print('~'*30)
# print(ll[0])
# print(ll[1])
ll.remove(5)
ll.remove(6)
ll.remove(0)
ll.remove(1)
for node in ll.iternodes(False): #False
    print(node)

  

  

原文地址:https://www.cnblogs.com/i-honey/p/7833358.html