数据结构----单向链表(linked list)
作者:程序员老九
掘金:https://juejin.im/post/5d132d91e51d4550a629b2ad
来源:请关注我的掘金博客
基础
我们知道什么是list,但是这不是链表。链表是由一系列的节点(Node)实现的,节点呢有至少两部分,一是数据,而是指向下一个节点的指针,如果没有指向,则指针指向Null。
创建链表
链表是由节点来实现的,也就是说链表的建立必然要先建立节点类。
# 首先要有一个节点类
class Node:#(一个是数据、一个是指针,默认指向None)
def __init__(self,dataval):
self.dataval = dataval
self.nextval = None
class S_List:
def __init__(self):
#假设第一个数据是headval
self.headval = None
li = S_List()
#先把数据列出来,这已经是有数据Node了
li.headval = Node('Mon')
e2 = Node('Tue')
e3 = Node('Wed')
# 用指针连接节点,也就是设置指针
li.headval.nextval = e2
e2.nextval = e3
#打印地址
print(e2.nextval)
#打印shuju
print(e2.nextval.dataval)
链表遍历
就是在创建完链表之后,可以输入第一个节点的方式来遍历整个链表
# 首先要有一个节点类
class Node:#(一个是数据、一个是指针,默认指向None)
def __init__(self,dataval):
self.dataval = dataval
self.nextval = None
class S_List:
def __init__(self):
#假设第一个数据是headval
self.headval = None
#定义一个函数--->在链表末尾添加一个新的node,node一定至少有两个部分,一是数据、而是指针(其中指针可以是none)
def append(self,newdata):
#newdata表示传入的数据
Newdata = Node(newdata) # 这句话的意思是,现在Newdata已经通过Node类成为了一个节点。
# if语句是判断Newdata是不是第一个数据,也就是判断它是不是None。
if self.headval is None:
self.headval = Newdata
return self.headval
#这是第一个节点的数据
laste = self.headval
'''判断条件---->判断节点的指针是否指向下一个节点.如果有下一个节点,就会一直指向下一个节点。
如果没有下一个节点(也就是None),则会跳出循环。这时候链表已经创建起来了
'''
while laste.nextval:
laste = laste.nextval
laste.nextval = Newdata
def show(self):
#这样可以直接使用链表
printval = self.headval
while printval:
print (printval.dataval)
printval = printval.nextval
li = S_List()
#先把数据列出来,这已经是有数据Node了
e1 = li.append('Mon')
# li.headval = Node('Mon')
e2 = li.append('Tue')
e3 = li.append('Wed')
# 用指针连接节点,也就是设置指针
# e1.nextval = e2
# e2.nextval = e3
# li.append('Mon')
li.show()
插入
插入元素是指将一个元素从一个已经存在的节点指向新插入的节点。
- 插入开头
# 首先要有一个节点类
class Node:#(一个是数据、一个是指针,默认指向None)
def __init__(self,dataval):
self.dataval = dataval
self.nextval = None
class S_List:
def __init__(self):
#假设第一个数据是headval
self.headval = None
#定义一个函数--->在链表末尾添加一个新的node,这个node一定至少两个方面啊,
#一是数据,而是指针
def append(self,newdata):
#只有数据
Newdata = Node(newdata)
# print(str(Newdata.nextval)+'&&&&&&&')
if self.headval is None:
self.headval = Newdata
# print(str(self.headval.dataval)+"******")
return self.headval
laste = self.headval
# print(str(laste.dataval)+"******")
#判断条件
while laste.nextval:
laste = laste.nextval
laste.nextval = Newdata
# print(str(laste.nextval.nextval)+'&&&&&&&')
#插入链表开头
def add_left(self,newdata):
Newnode = Node(newdata)
if self.headval is None:
self.headval = Newnode
# print(str(self.headval.dataval)+"******")
return self.headval
def show(self):
printval = self.headval
while printval:
print (printval.dataval)
printval = printval.nextval
li = S_List()
#先把数据列出来,这已经是有数据Node了
e4 = li.add_left('Sun')
e1 = li.append('Mon')
# li.headval = Node('Mon')
e2 = li.append('Tue')
e3 = li.append('Wed')
# 用指针连接节点,也就是设置指针
# e1.nextval = e2
# e2.nextval = e3
# li.append('Mon')
li.show()
##############
Sun
Mon
Tue
Wed
[Finished in 0.2s]
- 插入末尾
这就是添加了一个新元素
i.append('某一新元素')
- 在两个元素之间插入
同样地,将指针指向需要插入的新的元素就饿可以了。只需将前一个元素的指针指向插入的元素即可。举例:1--->2---->3 1--->2---->4----->3,原先2指向的是3,现在2指向的是插入元素4,然后由4指向3.
# 首先要有一个节点类
class Node:#(一个是数据、一个是指针,默认指向None)
def __init__(self,dataval):
self.dataval = dataval
self.nextval = None
class S_List:
def __init__(self):
#假设第一个数据是headval
self.headval = None
#定义一个函数--->在链表末尾添加一个新的node,这个node一定至少两个方面啊,
#一是数据,而是指针
def append(self,newdata):
#只有数据
Newdata = Node(newdata)
# print(str(Newdata.nextval)+'&&&&&&&')
if self.headval is None:
self.headval = Newdata
# print(str(self.headval.dataval)+"******")
return self.headval
laste = self.headval
# print(str(laste.dataval)+"******")
#判断条件
while laste.nextval:
laste = laste.nextval
laste.nextval = Newdata
# print(str(laste.nextval.nextval)+'&&&&&&&')
#插入链表开头
# def add_left(self,newdata):
# Newnode = Node(newdata)
# if self.headval is None:
# self.headval = Newnode
# # print(str(self.headval.dataval)+"******")
# return self.headval
#添加节点
def insert(self,middle,insert_node):
#首先判断有没有中间节点
#有中间节点
Newdata = Node(insert_node)
printval = self.headval
while printval:
# print(printval.dataval)
if printval.dataval == middle:
temp = printval.nextval
printval.nextval = Newdata
Newdata.nextval = temp
printval = printval.nextval
def show(self):
printval = self.headval
while printval:
print(printval.dataval)
printval = printval.nextval
li = S_List()
#先把数据列出来,这已经是有数据Node了
# e4 = li.insert(e2,'Sun')
e1 = li.append('1')
# li.headval = Node('Mon')
e2 = li.append('2')
e3 = li.append('3')
e4 = li.insert('2','5')
# 用指针连接节点,也就是设置指针
# e1.nextval = e2
# e2.nextval = e3
# li.append('Mon')
li.show()
删除链表元素
再简单说一下添加,添加呀,可以添加到开头,最后,中间某一位置。相应地,删除呢,可以删除开头、最后、中间某一位置。
- 先来简单的吧。删除开头。就是把第一删除
#删除第一个元素
def remove_left(self):
#将这个元素转化为Node
# Remove_d = Node(Removedata)
#判断是否有第一个元素
if self.headval:
self.headval = self.headval.nextval
- 删除最后一个元素
这个操作其实不能那么简单的,为什么呢?第一,这是单链表,也就是只是指向一个方向;第二,我们可以很容易知道最后一个元素是哪个,但是却不能反向指向倒数第二个元素。
比如:我们可以知道最后一个元素的指针指向的是None。
prev = self.headval
#当跳出循环的时候,就表示找到最后一个元素。
while prev:
prev = prev.nextval
那么,该怎么办呢?首先,我们需要知道,这个链表的长度,然后,依据长度找到倒数第二个元素,使得这个节点的指针指向的是`none`就可以了。
#确定链表长度
def link_len(self,len_link=0):
#第一个节点
prev = self.headval
#确定链表长度-----len_link
while prev:
len_link +=1
prev = prev.nextval
return len_link
删除最后一个元素:
def remove_final(self,length):
prev = self.headval
i = 0
while prev is not None and i<len_list-2:
prev = prev.nextval
i +=1
print(str(i)+"^^^")
prev.nextval = None
return
总的代码:
# 首先要有一个节点类
class Node:#(一个是数据、一个是指针,默认指向None)
def __init__(self,dataval):
self.dataval = dataval
self.nextval = None
class S_List:
def __init__(self):
#假设第一个数据是headval
self.headval = None
#定义一个函数--->在链表末尾添加一个新的node,这个node一定至少两个方面啊,
#一是数据,而是指针
def append(self,newdata):
#只有数据
Newdata = Node(newdata)
# print(str(Newdata.nextval)+'&&&&&&&')
if self.headval is None:
self.headval = Newdata
# print(str(self.headval.dataval)+"******")
return self.headval
laste = self.headval
# print(str(laste.dataval)+"******")
#判断条件
while laste.nextval:
laste = laste.nextval
laste.nextval = Newdata
# print(str(laste.nextval.nextval)+'&&&&&&&')
#插入链表开头
# def add_left(self,newdata):
# Newnode = Node(newdata)
# if self.headval is None:
# self.headval = Newnode
# # print(str(self.headval.dataval)+"******")
# return self.headval
#添加节点
def insert(self,middle_node,insert_node):
#首先判断有没有中间节点
if not middle_node:
print('The mentioned node is absent')
return
#有中间节点
Newdata = Node(insert_node)
# middle_next = middle_node.nextval
Newdata.nextval = middle_node.nextval
middle_node.nextval = Newdata
#删除第一个元素
def len_L(self,len_link=0):
#第一个节点
prev = self.headval
#将这个元素转化为Node
# Remove_d = Node(Removedata)
#判断是否有第一个元素,然后删除第一个元素
# if self.headval:
# self.headval = self.headval.nextval
#确定链表长度-----len_link
while prev:
len_link +=1
prev = prev.nextval
return len_link
#删除最后一个元素
def remove_final(self,length):
prev = self.headval
i = 0
while prev is not None and i<len_list-2:
prev = prev.nextval
i +=1
print(str(i)+"^^^")
prev.nextval = None
return
def show(self):
printval = self.headval
while printval:
print(printval.dataval)
printval = printval.nextval
li = S_List()
#先把数据列出来,这已经是有数据Node了
# e4 = li.insert(e2,'Sun')
e1 = li.append('Mon')
# li.headval = Node('Mon')
e2 = li.append('Tue')
e3 = li.append('Wed')
e4 = li.insert(e1,'Sun')
len_list = (li.len_L())
print(len_list)
li.remove_final(length=len_list)
# 用指针连接节点,也就是设置指针
# e1.nextval = e2
# e2.nextval = e3
# li.append('Mon')
li.show()
####结果是
4
1^^^
2^^^
Mon
Sun
Tue
- 现在我们来删除某任意节点。举例:1--->2--->3--->4 到 1---->2---->4
#删除任意位置节点
def remove_any(self,length,removekey):
prev = self.headval
i = 0
while prev is not None and i<(length-1-removekey-1):
prev = prev.nextval
i +=1
print(str(i)+"^^^")
prev.nextval = prev.nextval.nextval
return
完整代码:
# 首先要有一个节点类
class Node:#(一个是数据、一个是指针,默认指向None)
def __init__(self,dataval):
self.dataval = dataval
self.nextval = None
class S_List:
def __init__(self):
#假设第一个数据是headval
self.headval = None
#定义一个函数--->在链表末尾添加一个新的node,这个node一定至少两个方面啊,
#一是数据,而是指针
def append(self,newdata):
#只有数据
Newdata = Node(newdata)
# print(str(Newdata.nextval)+'&&&&&&&')
if self.headval is None:
self.headval = Newdata
# print(str(self.headval.dataval)+"******")
return self.headval
laste = self.headval
# print(str(laste.dataval)+"******")
#判断条件
while laste.nextval:
laste = laste.nextval
laste.nextval = Newdata
# print(str(laste.nextval.nextval)+'&&&&&&&')
#插入链表开头
# def add_left(self,newdata):
# Newnode = Node(newdata)
# if self.headval is None:
# self.headval = Newnode
# # print(str(self.headval.dataval)+"******")
# return self.headval
#添加节点
def insert(self,middle_node,insert_node):
#首先判断有没有中间节点
if not middle_node:
print('The mentioned node is absent')
return
#有中间节点
Newdata = Node(insert_node)
# middle_next = middle_node.nextval
Newdata.nextval = middle_node.nextval
middle_node.nextval = Newdata
#删除第一个元素
def len_L(self,len_link=0):
#第一个节点
prev = self.headval
#将这个元素转化为Node
# Remove_d = Node(Removedata)
#判断是否有第一个元素,然后删除第一个元素
# if self.headval:
# self.headval = self.headval.nextval
#确定链表长度-----len_link
while prev:
len_link +=1
prev = prev.nextval
return len_link
#删除最后一个元素
def remove_final(self,length):
prev = self.headval
i = 0
while prev is not None and i<len_list-2:
prev = prev.nextval
i +=1
print(str(i)+"^^^")
prev.nextval = None
return
#删除任意位置节点
def remove_any(self,length,removekey):
prev = self.headval
i = 0
while prev is not None and i<(length-1-removekey-1):
prev = prev.nextval
i +=1
print(str(i)+"^^^")
prev.nextval = prev.nextval.nextval
return
def show(self):
printval = self.headval
while printval:
print(printval.dataval)
printval = printval.nextval
li = S_List()
#先把数据列出来,这已经是有数据Node了
# e4 = li.insert(e2,'Sun')
e1 = li.append('Mon')
# li.headval = Node('Mon')
e2 = li.append('Tue')
e3 = li.append('Wed')
e4 = li.insert(e1,'Sun')
len_list = (li.len_L())
li.remove_any(len_list, 2)
# print(len_list)
# li.remove_final(length=len_list)
# 用指针连接节点,也就是设置指针
# e1.nextval = e2
# e2.nextval = e3
# li.append('Mon')
li.show()
###结果
Mon
Tue
Wed
[Finished in 0.2s]