【python链表】之单向链表详解


参考学习视频

python03-04-01单向链表

一、单向链表介绍

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。像锁链一样,由一节节节点连在一起,组成一条数据链。

1.1 链表节点结构:

在这里插入图片描述

1.2 单向链表的结构

img

1.3 单链表和单向循环链表

  1. 单链表:每个节点只有一个属性.next,用于存放其后继节点;尾节点的后继为None;若链表为空,则头节点.head为None。
  2. 单向循环链表:每个节点只有一个属性.next,用于存放其后继节点;由于循环,故尾节点的后继为头节点;若链表为空,则头节点.head为None。

二、操作单链表

2.1 常用方法(自己定义的)

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

2.2 单向链表的实现

1、单节点类结构
class SingleNode(object):
    """单链表的结点"""
    def __init__(self,item):
        # item存放数据元素
        self.item = item
        # next是下一个节点的标识
        self.next = None
2、单链表的增删改查
# #
class Node():
    """表节点结构实现  私有属性__next是指向下个节点的指针,__value为此节点的值"""
    def __init__(self, value=None, next=None, ):
        self._value = value
        self._next = next

    # 将方法封装
    def getValue(self):
        return self._value

    def getNext(self):
        return self._next

    def setvalue(self, value):
        self._value = value

    def setNext(self, next):
        self._next = next
        
        

class SingleLinkList(object):
    """操作单链表的方法"""
    def __init__(self, Node=None):
        """设置一个头节点"""
        self.head = Node

    def is_empty(self):
        """判断链表是否为空"""
        return self.head is None

    def add(self, node):
        """向链表头添加输入"""
        # 将插入元素实例化
        tmp = Node(node)
        # 如果链表为空,则让头指针指向实例化的节点
        if self.is_empty():
            self.head = tmp
        else:
            # 如果链表不为空,则先将头部节点指向的节点(内存地址),赋值给要插入节点的指针域
            # 然后将头部节点指针域指向要插入的节点
            tmp.setNext(self.head)
            self.head = tmp

    def append(self, node):
        """向链表尾添加数据"""
        end_Node = Node(node)
        cursor = self.head
        # 判断列表是否为空,如果为空,则头部插入
        if self.is_empty():
            self.add(end_Node)
        else:
            # 如果不为空,
            while cursor.getNext() is not None:
                cursor = cursor.getNext()
            cursor.setNext(end_Node)

    def tarver(self):
        """遍历整个链表"""
        cur = self.head
        while cur is not None:
            print(cur.getValue(), end=" ")
            cur = cur.getNext()
        print()  # 换行

    def length(self):
        """链表长度"""
        cur = self.head
        count = 0
        while cur is not None:
            count += 1
            cur = cur.getNext()
        return count

    def insert(self, index, node):
        """指定位置插入链表"""
        tmp = Node(node)
        if self.is_empty():
            print("链表为空")
            return
        elif index <= 0:
            # 如果在头部直接插入
            self.add(node)

        elif index > self.length():
            # 如果大于链表长度,则在尾部插入
            self.append(node)

        else:
            count = 0
            cur = self.head
            while count < (index - 1):
                count += 1
                cur = cur.getNext()
            tmp.setNext(cur.getNext())
            cur.setNext(tmp)

    def remove(self, index):
        """通过索引 删除节点"""
        if self.is_empty():
            print("链表为空")
            return

        if index < 0 or index > self.length()-1:
            print("索引范围超出链表长度!")
            return

        # 删除索引为0的元素
        elif index == 0:
            self.head = self.head.getNext()
        else:
            cur = 0  # 索引
            pre = self.head
            while cur < index-1:
                cur += 1
                pre = pre.getNext()
            pre.setNext(pre.getNext().getNext())


    def search(self, value):
        """链表查找节点是否存在,并返回True或者False"""
        cur = self.head
        if self.is_empty():
            print("链表为空!")
            return
        while cur != None:
            if cur.getValue() == value:
                return True
            cur = cur.getNext()
        return False
        
    def change(self, index, value):
        """链表内容替换"""
        if self.is_empty():
            print("链表为空!")
            return

        if index < 0 or index > self.length()-1:
            print("索引范围超出链表长度!")
            return
        
        node = self.head
        for i in range(self.length()):
            if i == index:
                node.setvalue(value)
                return
            node = node.getNext()


if __name__ == '__main__':
    obj = SingleLinkList()
    obj.add(1)
    obj.tarver()
    obj.append(2)
    obj.append(4)
    obj.add(7)
    obj.tarver()
    obj.insert(3, 5)
    obj.tarver()
    obj.remove(1)
    obj.tarver()
    print(obj.search(2))
    obj.tarver()
    obj.change(2, 55) 
    obj.tarver()



3、反转单链表

"""
 翻转一条单链表
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL

"""

class ListNode:
    def __init__(self, x, Next=None):
        self.val = x
        self.next = Next

# 遍历替换法
def ReverseList(head):
    if head == None or head.next == None:
        return head

    last = None  # 前置节点
    while head:
        tmp = head.next  # 保存当前节点的下一个节点,不可缺,因为后面更改了当前节点的next指向
        head.next = last  # 更改当前节点的next为上一个节点
        last = head  # 将上一个节点移动到当前节点
        head = tmp   # 当前节点移动到下一个节点
        # head.next, last, head = last, head, head.next 可以简写成
    return last


if __name__ == '__main__':
    # 创建一个1-5的链表
    a = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5,)))))
    Node = ReverseList(a)

    while Node:
        print(Node.val)
        Node = Node.next

结果:

5
4
3
2
1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章