您的位置:首页 > 编程语言 > Python开发

Python快速掌握单双链表和树~

2020-03-29 18:35 211 查看

前言:

单双链表、树、二叉树等数据结构的代码实现都存在相似之处,本文将从单链表入手,轻松掌握单双链表、树、二叉树的代码实现。友情提示:请提前了解什么是链表和树。 

 

 

具体内容 

1.单链表

单链表由一个个节点连接而成每个节点包含两部分信息:值 (val) 、下一个节点 (next) 。

图一单链表示意图

在接触单链表时,书上说的是节点 1 指向节点 2 ,也就是 next 指向下一个节点。在代码实现的时候“ next 指向下一个节点”就等同于“ next ”就是下一个节点。

一个节点由两部分组成:值 (val) 、下一个节点 (next) 。下一个节点 (next) 也由两部分组成: val 和 next 。层层嵌套,就形成了一个单链表。

图二单链表结构图

理解这些后,实现单链表的代码就很简单。

class Node():

def __init__(self,val):

self.elem=val

self.next=None

# 定义单链表 link, 第一个节点的值是 10

link=Node(10)

# 第一个节点的下一个节点是节点 20

link.next=Node(20)

# 第二个节点的下一个节点是 30

link.next.next=Node(30)

# 打印第一个节点的值

print(link.elem)# 返回 10

# 打印第二个节点的值

print(link.next.elem) # 返回 20

# 打印第三个节点的值

print(link.next.next.elem) # 返回 30

根据上方的代码,用节点类 Node 实现了一个单链表,但是很明显,这个单链表的操作看起来有点蠢,当需要添加新节点时,还需要知道链表中有多少个节点,节点一多就需要手敲很多个 next 。

所以需要另一个类,来实现在添加节点时直接添加,而不用去管之前有多少节点。这个类如果还能实现遍历节点之类的操作就更好了。

节点添加:尾插法

# 节点类

class Node():

def __init__(self,val):

self.elem=val

#next 初始化为空

self.next=None

# 定义一个空链表类

class SigleLink():

def __init__(self,node=None):

# 单链表必须从头部访问,空链表需要记录头部,初始化为空

self.__head=node

尾插法,顾名思义,在单链表的尾部添加元素,如果链表为空,令头部 __head 等于新加入节点即可。链表不为空,令最后一个节点的 next 等于新加入的节点,就完成了新节点的插入,由于单链表只能从头部开始操作,所以需要先从头部遍历到最后一个节点。

# 从尾部插入元素

def add_tail(self,val):

# 用户只需传入节点值,由函数自带处理成节点

node=Node(val)

# 分别处理链表为空和不为空的情况

if self.__head==None:

#头部为空,链表为空

self.__head=node

else:

#需要对最后一个节点进行操作,需要先遍历到最后一个节点

cur=self.__head   # 从头节点开始遍历 ,cur 记录当前操作的节点

while cur.next!=None:

# 当前节点的 next 不为空,就将 cur 移向下一个节点

cur=cur.next

cur.next=node

在尾插法的实现中已经包含了节点的遍历,还要再实现从头部插入节点,以及从任意位置插入节点的代码也就很简单了。

# 链表节点遍历

def travel(self):

cur=self.__head

while cur!=None:

print(cur.elem,end=' ')

cur=cur.next

print('')# 换行

节点添加:头插法

在链表头部插入新节点 (node) ,令 node.next 等于原来的头节点,将 node 标识为新的头节点即可。

# 头插法

def add_top(self,val):

node=Node(val)

node.next=self.__head

self.__head=node

节点添加:任意位置插入节点

在下标为 pos 处插入新节点 node ,通过遍历找出第 pos-1 个节点,令 node.next 等于第 pos-1 的节点的 next ,再令第 pos-1 的节点的 next 等于 node 即可 .

# 获取链表的长度

def length(self):

#cur 游标,表示当前操作的节点

cur=self.__head

# 统计有多少节点

count=0

while cur!=None:

count+=1

#将cur 替换为下一个节点

cur=cur.next

return count

def insert(self,pos,val):

# 输入的位置 <0 ,调用头插法

if pos<=0:

self.add_top(val)

# 输入的位置 > 节点个数,调用头插法

elif pos>self.length()-1:

self.add_tail(val)

else:

node=Node(val)

cur=self.__head

count=0  # 表示当前节点的下标,从 0 开始

#遍历到第pos-1 个节点时停止

while count<pos-1:

count+=1

cur=cur.next

node.next=cur.next

cur.next=node

2.双链表

单链表每个节点包含:值 (val) 、下一个节点 (next) 。双链表多一个信息:上一个节点 (last) 。只需要对节点类稍加更改即可。

# 双链表节点类

class Node():

def __init__(self,val):

self.elem=val

self.last=None

self.next=None

(1)遍历

从头部开始遍历,操作和单链表一样。从链表中的某个节点开始遍历,只需要分别向前 (last) 和向后 (next) 遍历一次即可。

(2)插入

单链表从尾部插入只需更改上一个节点的 next ,双链表多一步,还需要更改插入节点的 last 。其他插入方式,也只需要注意多出来的 last 即可。

3.二叉树

二叉树与双链表相比,上一个和下一个节点变为左节点和右节点

根据逻辑结构的变化,对遍历,插入等操作做相应变化即可。

# 二叉树节点类

class Node():

def __init__(self,val):

self.elem=val

self.left=None

self.right=None

4.树

树稍微麻烦一点,因为树中的某个节点有多少子节点是不确定的,所以需要将子节点 (son) 用列表储存。在遍历节点的时候,注意用个 for 循环去遍历当前节点的 son 即可。

# 树节点类

class Node():

def __init__(self,val):

self.elem=val

self.son=[]

结语

单双链表、二叉树、树的代码实现都有其共同之处,在弄清楚单链表的实现后,在编写双链表、二叉树、树的代码时,多思考,举一反三,便能很快上手。

 

更多案例教程加群:850591259

 

  • 点赞
  • 收藏
  • 分享
  • 文章举报
爬遍天下无敌手 发布了2 篇原创文章 · 获赞 0 · 访问量 1905 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: