链表

为什么需要链表?

因为在我们的计算机中内存空间不一定是连续的,而顺序表是一整块连续的内存空间,这样就不够灵活,还会造成内存的浪费。

链表的定义

链表是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。

链表的分类

  • 单向链表
  • 双向链表
  • 单向循环链表

单向链表

单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含了两个域一个信息域和一个链接域

结点的实现

class Node(object):
    """结点的实现"""
    def __init__(self):
        self.item = item   # 存放元素
        self.next = None   # next 是指向下一个节点的标识

单链表的操作

  • is_empty() 链表是否为空
  • length() 链表长度
  • travel() 遍历整个链表
  • add(item) 链表头部添加元素
  • append(item) 链表尾部添加元素
  • insert(pos, item) 指定位置添加元素
  • remove(item) 删除节点
  • search(item) 查找节点是否存在
class SingleLinkList(object):
    """单向链表"""
    def __init__(self, none=None):
        self._head = None
    
    def is_empty(self):
        """链表是否为空"""
        return self._head == None

travel / length

python 链表如何插入元素 python 链表怎么定义_指定位置

def length(self):
        """链表长度"""
        count = 0           # 记录列表长度的count
        cur = self.__head   # 游标
        while cur != None:
            cur = cur.next  # 游标右移
            count += 1 
        # cur == None 表示指向到最后一个节点的next区域
        reutnr count

    def travel(self):
        """遍历链表"""
        cur  = self.__head
        while cur != None:
            print(cur.itme, end='')
            cur = cur.next
        print("")
        def add(self, item):
        """链表头部添加元素"""
        # 创建新结点
        node = Node(item)
        # 新结点的next指向旧的头结点
        node.next = self.__head
        # 头指针指向新的结点
        self.__head = node

    def append(self, item):
        """链表尾部添加元素"""
        node = Node(item)
        # 链表为空
        if self.is_empty():
            self.__head = node
        # 链表不为空
        else:
            cur = self.__head
            while cur.next != None:
                cur = cur.next
            # 跳出循环,cur.next == None cur指向最后一个结点
            # 最后一个结点next指向新的结点
            cur.next = node
            node.next = None

    def insert(self, pos, item):
        """指定位置添加元素"""
        # 头部添加
        if pos <= 0:
            self.add(item)
        # 尾部添加
        elif pos >= self.length():
            self.append(item)
        # 指定pos位置添加元素
        else:
            # 新结点
            node = Node(item)
            # 计数
            count = 0
            # 游标
            cur = self.__head
            # 寻找pos前一个结点
            while count < (pos - 1):
                cur = cur.next
                count += 1
            # count == pos -1 cur游标指向pos结点的前一个结点
            # 新结点next指向pos位置的结点
            node.next = cur.next
            # pos前一个结点的next指向新结点
            cur.next = node

    def remove(self, item):
        """链表删除指定item的元素"""
        # 游标
        cur = self.__head
        # cur的前一个游标
        pre = None
        while cur != None:
            # 找到了要删除的元素
            if cur.item == item:
                # 1.要删除的元素是头结点
                if cur == self.__head:
                    # 头指针指向1号结点
                    self.__head = cur.next
                # 2.要删除的元素不是头结点
                else:
                    pre.next = cur.next
                return
            else:
                # 在cur移动之前将值赋值pre 形成一前一后的关系
                pre = cur
                # 游标右移动
                cur = cur.next

    def search(self, item):
        """判断传入的元素是否在链表内 bool"""
        cur = self.__head
        while cur != None:
            # 表示传入的元素找到了
            if cur.item == item:
                return True
            else:
                # 循环未退出 继续移动比较
                cur = cur.next
        # 循环退出了还未找到
        return False

 

 双向链表

操作

  • is_empty() 链表是否为空
  • length() 链表长度
  • travel() 遍历链表
  • add(item) 链表头部添加
  • append(item) 链表尾部添加
  • insert(pos, item) 指定位置添加
  • remove(item) 删除节点
  • search(item) 查找节点是否存在

单向循环链表

单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。

操作

  • is_empty() 判断链表是否为空
  • length() 返回链表的长度
  • travel() 遍历
  • add(item) 在头部添加一个节点
  • append(item) 在尾部添加一个节点
  • insert(pos, item) 在指定位置pos添加节点
  • remove(item) 删除一个节点
  • search(item) 查找节点是否存在