最清晰的单链表实现,包括带头结点和不带头结点实现和链表反转

看到网上很多人做单链表是否带头结点的实现比较疑惑,而且很多博客文章都是错误的,刚好最近在刷题,做下笔记,带头结点是一种数据结构常用的设置哨兵位的方法技巧,目的是简化代码实现,在这里就是方便统一单链表在删除和插入时链表只剩一个结点的操作。

以下代码对两种单链表做了详细实现,还有世上最简单的单链表反转方法

class Node(object):
    """结点类"""
    def __init__(self,item):
        self.item = item
        self.next = None


class SingleLinkCreate(object):
    def __init__(self, item=None, *args, **kwargs):
        # self.first是永远指向第一个结点的
        if item is None:
            # 初始化空链表, 无结点
            self.first=item
        else:
            # 初始化链表,同时指向第一个结点
            self.first=Node(item)
            for arg in args:
                self.append(arg)
        if kwargs.values() is not None:
            for kwarg in kwargs:
                self.append(kwargs[kwarg])

    def is_empty(self):
        return self.first is None

    def length(self):
        cur = self.first
        count = 0
        while cur is not None:
            count += 1
            cur = cur.next
        return count

    def add(self,item):
        # 链表头部添加元素
        node = Node(item)
        # 新结点的next指针域指向self.first指向的结点
        node.next = self.first
        # 头指针指向新结点
        self.first = node

    def append(self, item):
        # 链表尾部添加元素
        node = Node(item)
        if self.is_empty():
            self.first = node
        else:
            # 先创建个cur变量指向链表self.first指向的结点,然后移动到链表表尾添加数据
            cur = self.first
            while cur.next is not None:
                cur = cur.next
            # 退出循环时,cur尾结点
            cur.next = node

    def insert(self,pos,item):
        if pos <= 0:
            self.add(item)
        elif pos>=self.length():
            self.append(item)
        else:
            cur = self.first
            count = 0
            while count < (pos-1):
                count += 1
                cur = cur.next
            # 退出时,cur指向pos的前驱结点
            node = Node(item)
            node.next=cur.next
            cur.next = node

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

    def remove(self,item):
        cur = self.first
        pre = None  # 记录要删除结点的前一个结点,pre,cur同时移动
        while cur is not None:
            if cur.item == item:
                if cur == self.first:
                    self.first = cur.next
                else:
                    pre.next = cur.next
                return
            pre = cur
            cur = cur.next

    def search(self,item):
        cur = self.first
        while cur is not None:
            if cur.item == item:
                return True
            cur = cur.next
        return False

    def reverse(self):
        cur = self.first
        while cur.next is not None:
            temp_del = cur.next
            cur.next = cur.next.next
            temp_del.next = self.first
            self.first = temp_del


class SingleHeadLinkCreate(object):
    def __init__(self, item=None, *args, **kwargs):
        # 初始化链表,带头结点, self.__head永远指向头结点
        self.__head=Node(item)
        for arg in args:
            self.append(arg)
        if kwargs.values() is not None:
            for kwarg in kwargs:
                self.append(kwargs[kwarg])

    def is_empty(self):
        return self.__head is None

    def length(self):
        # 返回链表有效结点的个数,不包括头结点
        cur = self.__head
        count = 0
        while cur.next is not None:
            count += 1
            cur = cur.next
        return count

    def add(self,item):
        # 链表头部添加元素
        node = Node(item)
        node.next = self.__head.next
        self.__head.next = node

    def append(self, item):
        # 链表尾部添加元素
        node = Node(item)
        # 先创建个cur变量指向链表的头结点,然后移动到链表表尾添加数据
        cur = self.__head
        while cur.next is not None:
            cur = cur.next
        # 退出循环时,cur尾结点
        cur.next = node

    def insert(self,pos,item):
        # 在pos位置前插入元素
        cur = self.__head
        count = 0
        while cur.next is not None:
            cur = cur.next
            count += 1
            if count == pos-1:
                break
        if count>self.length()+1 or pos<0:
            assert 'error insert local'
        # 退出时,cur指向pos的前驱结点
        node = Node(item)
        node.next=cur.next
        cur.next = node

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

    def remove(self,item):
        cur = self.__head.next
        pre = self.__head  # 记录要删除结点的前一个结点,pre,cur同时移动
        while cur is not None:
            if cur.item == item:
                pre.next = cur.next
                return
            pre = cur
            cur = cur.next

    def search(self,item):
        cur = self.__head
        while cur.next is not None:
            cur = cur.next
            if cur.item == item:
                return True
        return False

    def reverse(self):
        cur = self.__head.next
        while cur.next is not None:
            # 从第2个结点开始摘下来,然后进行头插法
            temp_del = cur.next
            cur.next = cur.next.next
            temp_del.next = self.__head.next
            self.__head.next = temp_del

    def reverse2(self):
        cur = self.__head.next
        temp_del = cur.next
        while temp_del is not None:
            cur.next = temp_del.next
            temp_del.next = self.__head.next
            self.__head.next = temp_del
            temp_del = cur.next

if __name__ == "__main__":
    # link = SingleLinkCreate()
    link = SingleHeadLinkCreate()
    link.add(9)
    link.remove(9)
    link.append(5)
    link.append(7)
    link.insert(2,12)
    link.add(18)
    link.add(32)
    link.travel()
    link.reverse()
    link.travel()
    # link.reverse2()
    # link.travel()
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值