链表——单链表、单向循环链表、双向链表

1 单链表

单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
![在这里插入GLKg==,size_20,color_FFFFFF,t_70,g_se,x_16)

表元素域elem用来存放具体的数据。
链接域next用来存放下一个节点的位置(python中的标识)
变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。

节点实现

class SingleNode(object):
    """单链表的结点"""
    def __init__(self,item):
        # _item存放数据元素
        self.item = item
        # _next是下一个节点的标识
        self.next = None

单链表操作

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

单链表实现

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=0
        while cur!=None:
            count+=1
            cur=cur.next
        return count

    def travel(self):
        #遍历整个链表
        cur=self.__head
        while cur != None:
            print(cur.elem,end=" ")
            cur=cur.next
        print('')

    def add(self,item):
        #头部插入
        node=SingleNode(item)
        #方法一:头后插入
        if self.is_empty():
            self.__head=node
        else:
            p=self.__head
            self.__head=node
            node.next=p

        # #方法二:重置头
        # node.next=self.__head
        # self.__head=node

    def insert(self,pos,item):
        #指定位置插入   pos从零开始索引
        node = SingleNode(item)
        if pos<=0:
            self.add(item)
        elif pos > self.length():
            self.append(item)
        else:
            pre = self.__head
            count = 0
            while count<(pos-1):#当循环退出后,指向pos-1位置
                count += 1
                pre = pre.next
            node.next=pre.next
            pre.next = node

    def append(self,item):
        #尾端加入
        node=SingleNode(item)
        if self.is_empty():
            self.__head=node
        else:
            cur=self.__head
            while cur.next != None:
                cur=cur.next
            cur.next=node

    def remove(self,item):
        cur = self.__head
        pre=None
        while cur != None:
            if cur.elem == item:
                #先判断是否事头节点
                if cur == self.__head:
                    self.__head=cur.next
                else:
                    pre.next=cur.next
                break
            else:
                pre = cur
                cur = cur.next

    def search(self,item):
        #查找
        cur=self.__head
        while cur!=None:
            if cur.elem==item:
                return True
            else:
                cur=cur.next
        return False

测试

在这里插入图片描述

链表与顺序表对比

链表失去了顺序表随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大,但对存储空间的使用要相对灵活。链表与顺序表的各种操作复杂度如下所示:
在这里插入图片描述
注意虽然表面看起来复杂度都是 O(n),但是链表和顺序表在插入和删除时进行的是完全不同的操作。链表的主要耗时操作是遍历查找,删除和插入操作本身的复杂度是O(1)。顺序表查找很快,主要耗时的操作是拷贝覆盖。因为除了目标元素在尾部的特殊情况,顺序表进行插入和删除时需要对操作点之后的所有元素进行前后移位操作,只能通过拷贝和覆盖的方法进行。

2 单向循环链表

单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头节点。
在这里插入图片描述

操作

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

实现

class Node(object):
    #节点
    def __init__(self,elem):
        self.elem=elem
        self.next=None

class SingleCycleLinkList(object):
    #单项循环列表
    def __init__(self,node=None):
        #初始时候头指向为空,也就是先生成一个空的链表
        self.__head=node
        if node:
            node.next=node

    def is_empty(self):
        #判断是否为空
        return self.__head==None

    def length(self):
        #输出链表的长度
        if self.is_empty():
            return 0
        #定义一个指针进行遍历
        cur=self.__head
        count=1
        while cur.next!=self.__head:
            count+=1
            cur=cur.next
        return count

    def travel(self):
        #遍历整个链表
        if self.is_empty():
            return
        cur=self.__head
        while cur.next!=self.__head:
            print(cur.elem,end=" ")
            cur=cur.next
        #退出循环,cur指向尾节点,但尾节点的元素未打印
        print(cur.elem)

    def add(self,item):
        #头部插入
        node=Node(item)
        if self.is_empty():
            self.__head=node
            node.next=node
        else:
            cur = self.__head
            while cur.next != self.__head:
                cur = cur.next
            # 退出循环,cur指向尾节点,
            node.next=self.__head
            cur.next=node
            self.__head=node

    def insert(self,pos,item):
        #指定位置插入   pos从零开始索引
        node = Node(item)
        if pos<=0:
            self.add(item)
        elif pos > self.length():
            self.append(item)
        else:
            pre = self.__head
            count = 0
            while count<(pos-1):#当循环退出后,指向pos-1位置
                count += 1
                pre = pre.next
            node.next=pre.next
            pre.next = node

    def append(self,item):
        #尾端加入
        node=Node(item)
        if self.is_empty():
            self.__head=node
            node.next=node
        else:
            cur=self.__head
            while cur.next !=self.__head:
                cur=cur.next
            cur.next=node
            node.next=self.__head

    def remove(self,item):
        #删除节点
        if self.is_empty():
            return
        cur = self.__head
        pre=None
        while cur.next != self.__head:
            if cur.elem == item:
                #先判断是否事头节点
                if cur == self.__head:
                    #头节点的情况
                    #先找的尾节点
                    rear=self.__head
                    while rear.next!=self.__head:
                        rear=rear.next
                    self.__head=cur.next
                    rear.next=self.__head
                else:
                    #中间节点
                    pre.next=cur.next
                return
            else:
                pre = cur
                cur = cur.next
        # 退出循环,cur指向尾节点
        if cur.elem==item:
            if cur==self.__head:
                #链表只有一个节点
                self.__head=None
            pre.next = cur.next

    def search(self,item):
        #查找
        if self.is_empty():
            return False
        cur=self.__head
        while cur.next!=self.__head:
            if cur.elem==item:
                return True
            else:
                cur=cur.next
        if cur.elem == item:
            return True
        return False

测试

在这里插入图片描述

3 双向链表

每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
在这里插入图片描述

操作

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

实现

class Node(object):
    #节点
    def __init__(self,item):
        self.elem=item
        self.next=None
        self.prev=None

class DoubleLinkList(object):
    #双链表
    def __init__(self,node=None):
        #初始时候头指向为空,也就是先生成一个空的链表
        self.__head=node

    def is_empty(self):
        #判断是否为空
        return self.__head is None

    def length(self):
        #输出链表的长度
        #定义一个指针进行遍历
        cur=self.__head
        count=0
        while cur!=None:
            count+=1
            cur=cur.next
        return count

    def travel(self):
        #遍历整个链表
        cur=self.__head
        while cur != None:
            print(cur.elem,end=" ")
            cur=cur.next
        print('')

    def add(self,item):
        #头部插入
        node=Node(item)
        node.next=self.__head
        self.__head=node
        node.next.prev=node

        # node.next=self.__head
        # self.__head.prev=node
        # self.__head=node


    def insert(self,pos,item):
        #指定位置插入   pos从零开始索引
        node = Node(item)
        if pos<=0:
            self.add(item)
        elif pos > self.length():
            self.append(item)
        else:
            cur=self.__head
            count = 0
            while count<pos:
                count += 1
                cur = cur.next
            #当循环退出后,cur就是指向pos这个位置
            node.next=cur
            node.prev=cur.prev
            cur.prev.next=node
            cur.prev=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=node
            node.prev=cur

    def remove(self,item):
        cur = self.__head
        while cur != None:
            if cur.elem == item:
                #先判断是否事头节点
                if cur == self.__head:
                    self.__head=cur.next
                    #判断链表是否只有一个节点
                    if cur.next:
                        cur.next.prev=None
                else:
                    cur.prev.next=cur.next
                    if cur.next:
                        cur.next.prev=cur.prev
                break
            else:
                cur = cur.next

    def search(self,item):
        #查找
        cur=self.__head
        while cur!=None:
            if cur.elem==item:
                return True
            else:
                cur=cur.next
        return False

测试

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_48994268/article/details/120934320
今日推荐