双向链表的增、删、查、改、python实现,超详细讲解

双向链表的增、删、查、改

在这里插入图片描述
具体代码如下:

class Node(object):
    """链表单节点实现"""

    def __init__(self, item):
        self.item = item  # 元素域
        self.next = None  # 尾链接域
        self.pre = None  # 前驱指针


class DoubleLink:
    """双向链表"""

    def __init__(self, node=None):
        self.__head = node
        # head为指向一个链表头结点的p变量,接收一个参数node,node就是一个结点(第一个结点),当然也可以不传参数,
        # 当做一个空链表
        # head设置成私有属性,防止外部访问,如果head被外部访问并改动,则head之前指向的链表就丢失找不到了

    def is_empty(self):
        """判断链表是否为空
        :return 如果链表为空, 返回真
        """
        return self.__head is None

    def length(self):
        """
        :return: 链表长度 
        cur 游标
        count 结点计数
        """
        cur = self.__head  # 设置游标指向第一个结点
        count = 0  # 计数初始值为:0
        while cur is not None:  # 如果游标指向的结点不为空则进入循环进行计数
            count += 1  # 每次加一
            cur = cur.next  # 如果cur不为空则让游标指向下一个结点
        return count  # 最后返回链表长度

    def travel(self):
        """
        遍历链表
        :return:打印链表所有元素

        """
        cur = self.__head
        while cur is not None:
            print(cur.item, end=" ")
            cur = cur.next
        print()

    def add(self, item):
        """
        在链表头部添加结点
        :param item: 结点元素
        :return: 
        """
        node = Node(item)  # 创建一个结点对象
        if self.is_empty():  # 如果原始链表为空,直接让head指向新结点就可以了
            self.__head = node
        else:
            node.next = self.__head  # 让新结点的next指向原始的第一个结点
            self.__head.pre = node   # 让原始结点的pre指向新节点
            self.__head = node  # 让头指针指向新加入的结点

    def append(self, item):
        """
        在链表的尾部追加结点
        :param item: 
        :return: 
        """
        node = Node(item)

        #  如果链表为空则需要特殊处理
        if self.is_empty():
            self.__head = node
        else:
            cur = self.__head
            while cur.next is not None:
                cur = cur.next
            cur.next = node  # 让原始结点的为指针指向node
            node.pre = cur      # 让node的前驱指针指向原始尾结点

    def insert(self, pos, item):
        """
        在指定位置插入元素
        :param item: 
        :return: 
        """
        if pos <= 0:  # 如果要插入的位置小于等于0,则相当于在头部加入结点
            self.add(item)  # 直接调用已经写好的方法
        elif pos >= self.length():  # 如果要插入的位置大于等于链表的长度,则相当于在链表的尾部追加元素
            self.append(item)  # 直接调用写好的方法
        else:  # 如果插入位置在链表中间则进行一下操作
            cur = self.__head  # 游标指向第一个结点
            count = 0  # 计数制0
            while count < (pos - 1):  # (pos - 1) cur需要停留在pos位置的前一个结点的位置
                cur = cur.next
                count += 1
            # 当退出循环的时候cur指向pos的前一个位置
            node = Node(item)  # 创建新结点
            # TODO 如果四个指针复制的顺序出错会造成死循环(如下:)
            """
            cur.next = node  # 将cur指向新结点]
            node.pre = cur
            node.next = cur.next  # 将新结点指向cur的下一个结点
            cur.next.pre = node   # 让cur的后一个结点的pre指向node
            """
            node.pre = cur
            node.next = cur.next  # 将新结点指向cur的下一个结点
            cur.next.pre = node   # 让cur的后一个结点的pre指向node
            cur.next = node  # 将cur指向新结点]


    def remove(self, item):
        """删除结点"""
        cur = self.__head
        while cur is not None:  # 如果cur不为空则进入循环
            # 找到了要删除的元素
            if cur.item == item:
                # 在头部找到了元素
                if cur == self.__head:  # 如果找到的元素在头结点上
                    self.__head = cur.next  # 让头结点指向下一个结点,丢弃上个结点
                    if cur.next:
                        cur.next.pre = None  # 将原始头结点删除后将下一个结点的pre指向空
                else:  # 找到的结点不在头结点上,
                    cur.pre.next = cur.next
                    if cur.next:
                        cur.next.pre = cur.pre
                return  # 删除后直接结束循环
            cur = cur.next

    def search(self, item):
        """
        查找结点是否存在
        :return 布尔型
        """
        cur = self.__head
        while cur is not None:
            if cur.item == item:
                return True  # 如果找到了目标结点就返回true
            cur = cur.next
        return False  # 如果整个循环结束也没有找到目标结点,就返回false


if __name__ == '__main__':
    link = DoubleLink()
    print(link.length())
    print(link.is_empty())

    link.add(1)
    link.travel()

    link.append(6)
    link.travel()

    link.insert(1, 3)
    link.travel()

    print(link.length())

    print(link.search(1))

    link.remove(3)
    link.travel()

    link.remove(6)
    link.remove(1)
    print(link.length())

猜你喜欢

转载自blog.csdn.net/weixin_43250623/article/details/88854396
今日推荐