python数据结构——链表

由于python没有指针,所以将结点封装成类,将其元素值和next作为类的属性
在建立一个链表类对及诶单进行操作

在进行添加,删除等操作时,每次都要注意特殊情况:链表是否为空,链表只有一个元素,进行操作的元素的头结点或者为尾结点等

单链表

class Node(object):
    #节点
    def __init__(self,elem):
        self.elem=elem
        self.next=None#初始状态不知道指向谁

#node=Node()
class Singlelinglist(object):
    #单链表
    def __init__(self,node=None):
        self.__head=node #函数内部使用,对外不暴露,私有化

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


    def length(self):
        #链表长度
        #count记录数量
        count=0#能处理链表为空的情况,若初始值为1,循环判断条件为curr.next!=none,且需要特殊处理链表为空的情况
        # 游标,用来遍历节点
        curr=self.__head
        while curr!=None:
            count+=1
            curr=curr.next
        return count

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

    def add(self,item):
        #链表头部添加节点,头插法
        node=Node(item)#把数据封装成链表需要的节点
        node.next=self.__head
        self.__head=node

    def append(self,item):
        """链表尾部添加,尾插法"""
        node=Node(item)
        if self.is_empty():
            self.__head=node
        else:
            curr=self.__head
            while curr.next!=None:
                curr=curr.next
            curr.next=node


    def insert(self,pos,item):
        """指定位置添加
        pos参数:从0开始,链表的下标
        """
        if pos<=0:#默认为头插法
            self.add(item)
        elif pos>self.length()-1:#默认为尾插法
            self.append(item)
        else:
            node=Node(item)
            pre=self.__head
            count=0
            while count<(pos-1):
                count+=1
                pre=pre.next
            #当循环退出后,pre指向pos-1
            node.next=pre.next
            pre.next=node

    def remove(self,item):
        """删除节点"""
        curr=self.__head
        pre=None
        while curr!=None:
            if curr.elem==item:
                #判断是否是头结点
                if pre==None:#curr==self.__head,满足只有一个元素的情况
                    self.__head=curr.next
                else:
                    pre.next=curr.next#满足是尾结点的情况

                return
            pre=curr
            curr=curr.next



    def search(self,item):
        """指定元素是否在链表中"""
        curr=self.__head
        while curr!=None:
            if curr.elem==item:
                return True
            curr=curr.next
        return False

if __name__=="__main__":
    ll=Singlelinglist()
    print(ll.is_empty())
    print(ll.length())

    ll.append(1)
    print(ll.is_empty())
    print(ll.length())

    ll.append(2)
    ll.add(8)
    ll.append(3)
    ll.append(4)
    ll.append(5)
    ll.append(6)
    #8 1 2 3 4 5 6
    ll.insert(-1,9)#9 8 1 2 3 4 5 6
    ll.travel()
    ll.insert(3,100)#9 8 1 100 23456
    ll.travel()
    ll.insert(10,200)#9 8 1 100 23456 200
    ll.travel()
    print(ll.search(100))
    print(ll.search(99))

    ll.remove(100)
    ll.travel()
    ll.remove(9)
    ll.travel()
    ll.remove(200)
    ll.travel()




双向链表

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):
    #链表长度
    #count记录数量
    count=0#能处理链表为空的情况,若初始值为1,循环判断条件为curr.next!=none,且需要特殊处理链表为空的情况
    # 游标,用来遍历节点
    curr=self.__head
    while curr!=None:
        count+=1
        curr=curr.next
    return count

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

def add(self,item):
    #链表头部添加节点,头插法
    node=Node(item)#把数据封装成链表需要的节点
    node.next=self.__head
    self.__head=node
    node.next.prev=node

def append(self,item):
    """链表尾部添加,尾插法"""
    node=Node(item)
    if self.is_empty():
        self.__head=node
    else:
        curr=self.__head
        while curr.next!=None:
            curr=curr.next
        curr.next=node
        node.prev=curr


def insert(self,pos,item):
    """指定位置添加
    pos参数:从0开始,链表的下标
    """
    if pos<=0:#默认为头插法
        self.add(item)
    elif pos>self.length()-1:#默认为尾插法
        self.append(item)
    else:
        node=Node(item)
        pre=self.__head
        count=0
        while count<(pos-1):
            count+=1
            pre=pre.next
        #当循环退出后,pre指向pos-1
        node.next=pre.next
        node.prev=pre
        pre.next=node
        node.next.prev=node

def remove(self,item):
    """删除节点"""
    curr=self.__head
    while curr!=None:
        if curr.elem==item:
            #判断是否是头结点
            if curr==self.__head:
                self.__head=curr.next
                if curr.next:#特殊处理只有一个元素的链表
                    curr.next.prev=None
            else:
                curr.prev.next=curr.next
                if curr.next:#处理是尾结点的情况
                    curr.next.prev=curr.prev
            return
        curr=curr.next



def search(self,item):
    """指定元素是否在链表中"""
    curr=self.__head
    while curr!=None:
        if curr.elem==item:
            return True
        curr=curr.next
    return False

if name==“main”:
dll=Doublelinklist()
print(dll.is_empty())
print(dll.length())

dll.append(1)
print(dll.is_empty())
print(dll.length())

dll.append(2)
dll.add(8)
dll.append(3)
dll.append(4)
dll.append(5)
dll.append(6)
dll.travel()
# 8 1 2 3 4 5 6
dll.insert(-1, 9)  # 9 8 1 2 3 4 5 6
dll.travel()
dll.insert(3, 100)  # 9 8 1 100 23456
dll.travel()
dll.insert(10, 200)  # 9 8 1 100 23456 200
dll.travel()
print(dll.search(100))
print(dll.search(99))

dll.remove(100)
dll.travel()
dll.remove(9)
dll.travel()
dll.remove(200)
dll.travel()

单向循环链表

class Node(object):
    #节点
    def __init__(self,elem):
        self.elem=elem
        self.next=None#初始状态不知道指向谁

#node=Node()
class Singlecyclelinglist(object):
    #单向循环链表
    def __init__(self,node=None):
        self.__head=node #函数内部使用,对外不暴露,私有化
        if node:#传了一个node
            node.next=node

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


    def length(self):
        #链表长度
        if self.is_empty():
            return 0
        #count记录数量
        count=1#不能处理链表为空的情况,
        # 游标,用来遍历节点
        curr=self.__head
        while curr.next!=self.__head:
            count+=1
            curr=curr.next
        return count

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

    def add(self,item):
        #链表头部添加节点,头插法
        #需要把尾结点的指针指向新的头结点,需要进行遍历
        node=Node(item)#把数据封装成链表需要的节点
        curr=self.__head
        #特殊处理空链表的情况
        if self.is_empty():
            self.__head=node
            node.next=node
            return

        while curr.next!=self.__head:
            curr=curr.next
        # 退出循环,curr指向尾结点
        curr.next=node
        node.next=self.__head
        self.__head=node

    def append(self,item):
        """链表尾部添加,尾插法"""
        node=Node(item)
        if self.is_empty():
            self.__head=node
            node.next=node
        else:
            curr=self.__head
            while curr.next!=self.__head:
                curr=curr.next
            curr.next=node
            node.next=self.__head


    def insert(self,pos,item):
        """指定位置添加
        pos参数:从0开始,链表的下标
        """
        if pos<=0:#默认为头插法
            self.add(item)
        elif pos>self.length()-1:#默认为尾插法
            self.append(item)
        else:
            node=Node(item)
            pre=self.__head
            count=0
            while count<(pos-1):
                count+=1
                pre=pre.next
            #当循环退出后,pre指向pos-1
            node.next=pre.next
            pre.next=node

    def remove(self,item):
        """删除节点"""
        if self.is_empty():
            return
        curr=self.__head
        pre=None
        while curr.next!=self.__head:
            if curr.elem==item:
                #判断是否是头结点
                #是头结点,需要改变尾部的指针
                if pre==None:
                    #找尾结点
                    rear=self.__head
                    while rear.next!=self.__head:
                        rear=rear.next
                    rear.next=curr.next
                    self.__head=curr.next
                else:
                    #中间节点
                    pre.next=curr.next
                return
            pre=curr
            curr=curr.next
        #退出循环,curr指向尾结点
        if curr.elem==item:
            #只有一个要删除的节点时
            if pre==None:
                self.__head=None
            else:
                pre.next=curr.next



    def search(self,item):
        """指定元素是否在链表中"""
        curr=self.__head
        if self.is_empty():
            return False
        while curr.next!=self.__head:
            if curr.elem==item:
                return True
            curr=curr.next
        return curr.elem==item#单独判断尾结点是否为指定元素

if __name__=="__main__":
    ll=Singlecyclelinglist()
    print(ll.is_empty())
    print(ll.length())

    ll.append(1)
    print(ll.is_empty())
    print(ll.length())

    ll.append(2)
    ll.add(8)
    ll.append(3)
    ll.append(4)
    ll.append(5)
    ll.append(6)
    #8 1 2 3 4 5 6
    ll.insert(-1,9)#9 8 1 2 3 4 5 6
    ll.travel()
    ll.insert(3,100)#9 8 1 100 23456
    ll.travel()
    ll.insert(10,200)#9 8 1 100 23456 200
    ll.travel()
    print(ll.search(100))
    print(ll.search(99))

    ll.remove(100)
    ll.travel()
    ll.remove(9)
    ll.travel()
    ll.remove(200)
    ll.travel()




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值