看到网上很多人做单链表是否带头结点的实现比较疑惑,而且很多博客文章都是错误的,刚好最近在刷题,做下笔记,带头结点是一种数据结构常用的设置哨兵位的方法技巧,目的是简化代码实现,在这里就是方便统一单链表在删除和插入时链表只剩一个结点的操作。
以下代码对两种单链表做了详细实现,还有世上最简单的单链表反转方法
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()