链表python(数据结构与算法)

链表的定义:

不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址),而是数组由一个一个节点组成,每个节点包含:数据部分和保存下一个数据的地址。在建立数组的时候通过添加元素的操作将数据连起来。

链表分类:

  • 单链表:就是由多个节点的集合共同构成一个线性序列;
  • 双向链表:它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。
  • 循环链表:特点是链表中最后一个结点的指针域指向头结点,整个链表形成一个环。
  • 双向循环链表:即在双向链表的基础上,使最后一个节点的指针域指向头节点,整个链表形成一个环。

单向链表:

创建链表的过程是建立基础的节点类,节点可用一个类来实现,然后建立一个链表类,实现对节点的操作,实现链表、

1 节点的实现:

class Node:
    
    def __init__(self,data):
        self.data = data #数据的位置
        self.next = None # 保存下一个数据的地址

然后,使用节点类实现上图所示链表,

#
node1 = Node(5)     #第一个节点   
node1.next = Node(6) # 第二个节点
node1.next.next = Node(8)#链接第三个节点
node1.next.next.next = Node(7)#链接第4个节点
#打印数据
print(node1.data)#5
print(node1.next.data)#6
print(node1.next.next.data)#8
print(node1.next.next.next.data)#7 
out:   
5
6
8
7

上述过程实现过程很符合实际操作,下面用一个类来调用节点类,实现更加复杂的功能,先建立一个包含基本的类,

常见单链表的操作

  • is_empty() 链表是否为空
  • length() 链表长度
  • travel() 遍历整个链表
  • add(item) 链表头部添加元素
  • append(item) 链表尾部添加元素
  • insert(pos, item) 指定位置添加元素
  • remove(item) 删除节点
  • search(item) 查找节点是否存在

 

单向链表的实现:

其基本实现基类:

class Linkedlist():
    
    def __init__(self):
        self.head = None #没有元素的时候,是空的
        
    #1判断是否为空
    def is_empty(self):
        pass
    #2在链表首部添加元素
    def add(self,elem):
        pass
    #3在链表的尾部添加元素
    def append(self,elem):
        pass
    #4在指定的位置添加元素
    def insert(self,pos,item):
        pass
    #5删除元素
    def remove(self,elem):
        pass
    #6求链表的长度
    def lengeth(self):
        pass
    #7查找是否包含元素elem
    def search(self,elem):
        pass
    #8遍历链表
    def travel(self):
        pass   

基类的实现:

1判断是否为空

#1判断是否为空
    def is_empty(self):
        return self.head == None # self.head is None 

 

2 append(item) 链表尾部添加元素:

在链表的尾部添加元素,操作比较简单,先实现,即将每一个节点尾部指向下一个元素,

需要考虑的情况:1.链表是空的时,添加元素,2链表不为空时,添加元素。

 

程序的实现:(重点在怎么找到链表的尾部)

#2在链表首部添加元素
    def add(self,elem):
        node = _Node(elem)
        if self.is_empty():
            self.head = node
        else:
            cur = self.head
            while cur.next != None:#判断当前节点的next是否为空,不为空,为True
                cur = cur.next#将cur移动到下一个节点
            cur.next = node

 

3 add(item) 链表头部添加元素

def add(self,elem):
        node = _Node(elem)
        node.next = self.head
        self.head = node

4求链表的长度

 

#6求链表的长度
    def lengeth(self):
        cur = self.head
        count = 0
        while cur.next != None:#跳出循环后会指向最后一个节点,
            #故将加法放在前面
            count += 1
            cur = cur.next
        return count  

5在指定的位置添加元素

需考虑三种情况:

  • 指定为在第一元素之前
  • 指定的元素位置超过链表的长度
  • 指定的元素位置在链表长度范围之内

首先是插入操作过程:

#4在指定的位置添加元素
    def insert(self,pos,item):
        #在第一元素之前
        if pos < 0:
            self.add(item)
        elif pos > (self.lengeth() - 1):
            self.append(item)
        else:
            node = Node(item)
            count = 0
            pre = self._head
            while count < (pos-1):
                count += 1
                pre = pre.next
            node.next = pre.next
            pre.next = node

最终测试代码:

class Node:
    
    __slots__ = 'elem','next'
    
    def __init__(self,elem):
        
        self.elem = elem #数据的位置
        self.next = None # 保存下一个数据的地址
        
        
class Linkedlist():
    
    def __init__(self):
        self.head = None #没有元素的时候,是空的
        
    #1判断是否为空
    def is_empty(self):
        return self.head == None # self.head is None ,为空返回True
    #2在链表首部添加元素
    def add(self,elem):
        node = Node(elem)
        node.next = self.head
        self.head = node
            
    #3在链表的尾部添加元素
    def append(self,elem):
        node = Node(elem)#调用节点类。创建一个节点
        #判断是否为空
        if self.is_empty():
            self.head = node 
        else:
            cur = self.head
            while cur.next != None:
                cur = cur.next
            cur.next = node 
            
    #4在指定的位置添加元素
    def insert(self,pos,item):
        #在第一元素之前
        if pos < 0:
            self.add(item)
        elif pos > (self.lengeth() - 1):
            self.append(item)
        else:
            node = Node(item)
            count = 0
            pre = self.head
            while count < (pos-1):
                count += 1
                pre = pre.next
            node.next = pre.next
            pre.next = node
    #5删除元素
    def remove(self,elem):
        cur = self.head
        pre = None
        while cur != None:
            #找到指定的元素
            if cur.elem == elem:
                
                if not pre:
                    self.head = cur.next
                else:
                    pre.next = cur.next
                break
            else:
                #继续将链表的节点往后节点
                pre = cur 
                cur = cur.next
            
            
    #6求链表的长度
    def lengeth(self):
        
        cur = self.head
        count = 0
        while cur != None:#跳出循环后会指向最后一个节点,
            #故将加法放在前面
            count += 1
            cur = cur.next
        return count   
    #7查找是否包含元素elem
    def search(self,elem):
        
        cur = self.head
        
        while cur != None:
            if cur.elem == elem:
                return True
            cur = cur.next
            
        return False
            
    #8遍历链表
    def travel(self):
        cur = self.head
        while cur != None:
            print(cur.elem)
            cur = cur.next
            
if __name__ == "__main__":
    link = Linkedlist()
    print(link.is_empty())
    print(link.lengeth())
    
    #在尾部添加元素
    link.append(5)
    link.append(6)
    link.append(7)
    #遍历元素
    print("--遍历在尾部添加元素的后的链表----")
    link.travel()
    #在指定位置添加元素
    link.insert(2,8)
    #遍历元素
    print("---遍历插入后的链表-----")
    link.travel()
True
0
--遍历在尾部添加元素的后的链表----
5
6
7
---遍历插入后的链表-----
5
6
8
7

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值