数据结构----链表系列----单向链表---Python

数据结构----单向链表(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]

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值