Python中实现单链表

关于链表

链表是一种将元素存放在通过连接构造出来的一系列存储块中的结构。

链表的结构由两部分组成:数据区(存储数据)+链接区(存储地址),这样的结构称为一个节点,如图所示:

python子节点_python子节点


下面是一个单链表的例子:

python子节点_头结点_02


箭头显示了单个链接列表中的节点是如何组合在一起的。

链表的实现

节点结构的定义

前面说过,链表每一个节点是由两部分组成的数据区+链接区,因此在定义时需要表示出来。

class Node(object):
    """定义一个节点类"""
    def __init__(self,val):
        self.val = val
        self.next = None
单链表实现

在单链表中我们通常会指定一个头结点(head),head指向链表中的第一个元素节点,方便我们进行链表的遍历、元素查找等,也就是说知道了头节点也就知道了整个链表。
单链表的实现代码如下:
我们首先定义了一个头结点

class SingleLinkList(object):
    def __init__(self,node=None):
        self.__head = node

我们接着定义了链表中的操作方法
1.链表判断是否为空

def is_empty(self):
        """链表是否为空"""
        return self.__head == None

通过判断头结点的指向,来判断链表是否为空。

python子节点_链表_03


2.链表的长度

def length(self):
        """链表的长度"""
        # 定义一个指针,用来移动遍历节点
        cur = self.__head
        # count用来记录节点数量
        count = 0
        while(cur != None):
            count += 1
            cur = cur.next
        return count

3.链表的遍历

def travel(self):
        cur = self.__head
        while(cur!=None):
            print(cur.val," ")
            cur=cur.next

4.链表元素的添加
链表尾部添加元素,尾插法

def append(self,val):
        """链表尾部添加元素"""
        node = Node(val)
        # 链表为空时
        if self.__head == None:
            self.__head = node
        else:
            cur = self.__head
            while(cur.next != None):
                cur = cur.next
            cur.next = node

链表头部添加元素,头插法

def add(self,val):
        """链表头部添加元素,头插法"""
        node = Node(val)
        node.next = self.__head
        self.__head = node

图解步骤:

python子节点_python子节点_04


注:这里需要注意在插入新的节点时,我们要先将新的节点指向第一个节点,在将头节点指向新节点,保证原有的节点不会丢失。

指定位置添加元素

def insert(self,pos,val):
        """指定位置添加元素"""
        # 下标小于0时,相当于在头部插入
        if pos < 0:
            self.add(val)
        # 下标超过链表的长度,相当于在尾部插入
        elif pos > ( self.length()-1):
            self.append(val)
        else:
            pre = self.__head
            count = 0
            while(count < pos -1):
                pre = pre.next
                count += 1
            node = Node(val)
            node.next = pre.next
            pre.next = node

图解步骤:

python子节点_数据结构_05


5.链表节点的删除

def remove(self,val):
        """删除节点,双指针"""
        pre = None
        cur = self.__head
        while(cur != None):
            if cur.val == val:
                # 判断此节点是否是头结点
                if cur == self.__head:
                    self.__head = cur.next
                else:
                    pre.next = cur.next
                break
            else:
                pre = cur
                cur = cur.next

图解步骤:

python子节点_python子节点_06


完整代码:

class Node(object):
    """定义一个节点类"""
    def __init__(self,val):
        self.val = val
        self.next = None

class SingleLinkList(object):
    def __init__(self,node=None):
        self.__head = node

    def is_empty(self):
        """链表是否为空"""
        return self.__head == None

    def length(self):
        """链表的长度"""
        cur = self.__head
        # count记录数量
        count = 0
        while(cur != None):
            count += 1
            cur = cur.next
        return count

    def travel(self):
        cur = self.__head
        while(cur!=None):
            print(cur.val,end = " ")
            cur=cur.next
        print("")

    def append(self,val):
        """链表尾部添加元素"""
        node = Node(val)
        if self.__head == None:
            self.__head = node
        else:
            cur = self.__head
            while(cur.next != None):
                cur = cur.next
            cur.next = node

    def add(self,val):
        """链表头部添加元素,头插法"""
        node = Node(val)
        # print(node.val)
        node.next = self.__head
        self.__head = node

    def insert(self,pos,val):
        """指定位置添加元素"""
        if pos < 0:
            self.add(val)
        elif pos > ( self.length()-1):
            self.append(val)
        else:
            pre = self.__head
            count = 0
            while(count < pos -1):
                pre = pre.next
                count += 1
            # 当循环退出后,pre指向pos-1的位置
            node = Node(val)
            node.next = pre.next
            pre.next = node

    def remove(self,val):
        """删除节点,双指针"""
        pre = None
        cur = self.__head
        while(cur != None):
            if cur.val == val:
                # 判断此节点是否是头结点
                if cur == self.__head:
                    self.__head = cur.next
                else:
                    pre.next = cur.next
                break
            else:
                pre = cur
                cur = cur.next

l = SingleLinkList()
l.append(10)
l.append(20)
l.travel()
l.add(30)
l.travel()
l.insert(1,40)
l.travel()
l.remove(30)
l.travel()
"""
上述代码执行的结果:
10 20 
30 10 20 
30 40 10 20 
40 10 20 
"""

总结

我们给出一下链表的各种操作的时间复杂度:

python子节点_python子节点_07