美文网首页
Python链表实现(转)

Python链表实现(转)

作者: 寻找无双丶 | 来源:发表于2017-11-30 15:08 被阅读85次

链表

链表是一种递归的数据结构,他或者为(null),或者是指向一个结点(node)的引用,该结点含有一个泛型的元素和一个指向另一条链表的引用. 如下图


链表图

链表中的基本要素:

  1. 结点(也可以叫节点或元素),每一个结点有两个域,左边部份叫值域,用于存放用户数据;右边叫指针域,一般是存储着到下一个元素的指针
  2. head结点,head是一个特殊的结节,head结点永远指向第一个结点
  3. tail结点,tail结点也是一个特殊的结点,tail结点永远指向最后一个节点
  4. None,链表中最后一个结点指针域的指针指向None值,因也叫接地点,所以有些资料上用电气上的接地符号代表None

链表的常用方法

  1. LinkedList() 创建空链表,不需要参数,返回值是空链表
  2. is_empty() 测试链表是否为空,不需要参数,返回值是布尔值
  3. append(data) 在尾部增加一个元素作为列表最后一个。参数是要追加的元素,无返回值
  4. iter() 遍历链表,无参数,无返回值,此方法一般是一个生成器
  5. insert(idx,value) 插入一个元素,参数为插入元素的索引和值
  6. remove(idx)移除1个元素,参数为要移除的元素或索引,并修改链表
  7. size() 返回链表的元素数,不需要参数,返回值是个整数
  8. search(item) 查找链表某元素,参数为要查找的元素或索引,返回是布尔值

python实现

# 结点对象
class Node:     ➊
    def __init__(self, data):
        self.data = data
        self.next = None

# 链表对象
class LinkedList:
    def __init__(self):    ➋
        self.head = None
        self.tail = None

    #is_empty方法检查链表是否是一个空链表,这个方法只需要检查head结点是否指向None即可
    def is_empty(self):    
        return self.head is None
    
    def append(self, data): ➌
        node = Node(data)
        if self.head is None:
            self.head = node
            self.tail = node
        else:
            self.tail.next = node
            self.tail = node

    # 遍历列表
    def iter(self):
        if not self.head:
            return
        cur = self.head
        yield cur.data
        while cur.next:
            cur = cur.next
            yield cur.data
  
    def insert(self, idx, value):  ➍
        cur = self.head
        cur_idx = 0
        if cur is None:             # 判断是否是空链表
            raise Exception('The list is an empty list')
        while cur_idx < idx-1:   # 遍历链表
            cur = cur.next
            if cur is None:   # 判断是不是最后一个元素
                raise Exception('list length less than index')
            cur_idx += 1
        node = Node(value)
        node.next = cur.next
        cur.next = node
        if node.next is None:
            self.tail = node
  
    def remove(self, idx):➎
        cur = self.head
        cur_idx = 0
        if self.head is None:  # 空链表时
            raise Exception('The list is an empty list')
        while cur_idx < idx-1:
            cur = cur.next
            if cur is None:
                raise Exception('list length less than index')
            cur_idx += 1
        if idx == 0:   # 当删除第一个结点时
            self.head = cur.next
            cur = cur.next
            return
        if self.head is self.tail:   # 当只有一个结点的链表时
            self.head = None
            self.tail = None
            return
        cur.next = cur.next.next
        if cur.next is None:  # 当删除的结点是链表最后一个结点时
            self.tail = cur
   
    # 遍历计数即可
    def size(self):
        current = self.head
        count = 0
        if current is None:
            return 'The list is an empty list'
        while current is not None:
            count += 1
            current = current.next
        return count
  
    def search(self, item):
        current = self.head
        found = False
        while current is not None and not found:
            if current.data == item:
                found = True
            else:
                current = current.next
        return found
  
if __name__ == '__main__':
    link_list = LinkedList()
    for i in range(150):
        link_list.append(i)
#    print(link_list.is_empty())
#    link_list.insert(10, 30)
  
#    link_list.remove(0)
  
    for node in link_list.iter():
        print('node is {0}'.format(node))
    print(link_list.size())
#    print(link_list.search(20))

➊ python用类来实现链表的数据结构,节点(Node)是实现链表的基本模块,每个节点至少包括两个重要部分。首先,包括节点自身的数据,称为“数据域”(也叫值域)。其次,每个节点包括下一个节点的“引用”(也叫指针).此节点类只有一个构建函数,接收一个数据参数,其中next表示指针域的指针,实例化后得到一个节点对象 node = Node(4)

image

➋ 初始化了head和tail节点,且两节点都指向None,link_list = LinkedList()

image

➌ 既然要新增加节点,首先把Node类实例化得到一个node对象。这里有两种情况需要考虑:一是链表是一个空链表append一个节点,整个链表中就一个节点,此时head与tail都指向这个结点;二是当链表不是空链表append一个节点.
第二种情况重要讲:增加第二个节点的操作需要分两步完成,第一步:self.tail.next = node,即把上一个节点的next指针指向当前node;第二步:self.tail = node,把tail移动到node,如下图:

image

➍ 插入数据

image
  1. 还要额外考虑两种情况:
  2. 空链表时
  3. 插入位置超出链表节点的长度时
  4. 插入位置是链表的最后一个节点时,需要移动tail

➎ 删除数据 考虑以下几种情况

  1. 空链表,直接抛出异常
  2. 删除第一个节点时,移动head到删除节点的next指针指向的对象
  3. 链表只有一个节点时,把head与tail都指向None即可
  4. 删除最后一个节点时,需要移动tail到上一个节点
  5. 遍历链表时要判断给定的索引是否大于链表的长度,如果大于则抛出异常信息

相关链接

这篇文章查看原链接,图片更多,也更容易理解,这里我只是转载过来做一个总结
https://facert.gitbooks.io/python-data-structure-cn/3.%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/3.10.%E4%BB%80%E4%B9%88%E6%98%AF%E9%98%9F%E5%88%97/
https://docs.lvrui.io/2016/07/20/Python%E4%B8%AD%E5%85%88%E8%BF%9B%E5%85%88%E5%87%BA%E9%98%9F%E5%88%97queue%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/

相关文章

网友评论

      本文标题:Python链表实现(转)

      本文链接:https://www.haomeiwen.com/subject/wemvbxtx.html