通过自己实现链表的增删改查了解链表这些方法的实现原理

链表:

    链表和数组都是线性表:
        数组:将元素顺序地存放在一块连续的存储区内,元素间的顺序关系由它们的存储顺序自然表示。
        链表:将元素存放在通过链接构造起来的一系列存储块中。
        
    特点:不用连续存储,不需要知道存储的数量,分散存储。
    寻找元素的方式:比如有个list li = [200,400,600]
                    200这个元素存储着400的内存地址,400存储着600的内存地址,
                    既一个链表元素存储着两个东西:1、数据区2、链接区
                    
    单向链表:
        前一个节点指向下一个节点,单向的。尾节点的链接区指向为空。

 


通过类实现以下功能

单链表的操作

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

在例如c语言中,申明一个变量需要规定好这个变量的类型,例如:int a = 10,这是因为c在申明变量后,会在内存中

划出一个空间存放10,这个空间的别名为a,a就算改变也只能是int类型,而在python中 a = 10的意思是a

代表着内存,存放着数字10的内存地址,既指针概念,换成其他类型也不影响(例如浮点,函数等)。

一个元素有两个属性:

1、elem 为此元素的值

2、next为指向下一个元素位置的内存地址

 

class Node:#元素
    def __init__(self,elem):
        self.elem = elem#此节点的数值
        self.next = None#下一个节点的内存地址

class SingleLinkList:#单向链表
    def __init__(self):
        self._head = None
        
    def is_empty(self):#链表是否为空
        pass
    
    def length(self):#链表长度
        pass
    
    def travel(self):# 遍历整个链表
        pass
    
    def add(self,item):#链表头部添加元素
        pass
    
    def append(self,item):#链表尾部添加元素
        pass
    
    def insert(self,pos, item):#指定位置添加元素
        pass
    
    def remove(self,item):#删除节点
        pass
    
    def search(self,item):#查找节点是否存在
        pass
    

先定义两个类,节点和单向链表。

初始化链表,链表的头元素(_head=None)为None空,要想向链表添加一个节点,则必须先实例化一个Node对象。

sll = SingleLinkList()
node = Node(100)

向sll链表添加一个节点100,则sll._head 指向100。

is_empty

现在可以写出is_empty的方法,当_head == None则表示链表为空。

    def is_empty(self):  # 链表是否为空
        return self._head == None

length

要想实现知道链表里元素的个数,则需要一个指针或者游标来计数。

计数初始,游标在_head处,然后通过_head指向的头节点找到第一个节点,然后再从第一个节点的链接self.next找到下一个节点。

判断是否是最后一个节点的标志是此时节点的next属性是否为None,如果为None则是最后一个节点。

    def length(self):  # 链表长度
        #要考虑到链表为空的情况
        count = 0
        cur = self._head#游标
        while cur != None:
            count += 1
            cur = cur.next
        return count

同理,遍历也可以写出来

travel

    def travel(self):  # 遍历整个链表
        cur = self._head#游标
        while cur != None:
            print(cur.elem)
            cur = cur.next

append

    def append(self, item):  # 链表尾部添加元素 item为数据,不是节点,让用户使用起来方便,只要用户输入数字
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head
            while cur.next != None:
                cur = cur.next
            cur.next = node

insert

    def insert(self, pos, item):  # 指定位置添加元素
        count = 0
        cur = self.__head
        if pos <= 0:
            self.add(item)
        elif pos > self.length() - 1:
            self.append(item)
        else:
            while count < pos - 1:#在指定位置的前一个节点,插入新的节点,
                cur = cur.next#游标指向下一个
                count += 1
            node = Node(item)
            node.next = cur.next#新的节点的下一个节点指向原来位置为pos的节点
            cur.next = node#然后在把游标的下一个节点指向要插入的节点,要注意先后顺序

remove

    def remove(self, item):  # 删除节点
        cur = self.__head#游标在第一个节点
        prev = None#此时游标的上一个位置为None
        while cur != None:#当游标部位不为空时
            if cur.elem == item:#找到要删除逇数字
                if cur == self.__head:#如果要删除的节点为第一个节点
                    self.__head == cur.next#把首节点指向第二个节点
                else:
                    prev.next = cur.next#其余情况下则把要删除节点的上一个节点指向下一个节点
                break
            else:
                prev = cur
                cur = cur.next

search

    def search(self, item):  # 查找节点是否存在
        cur = self.__head#游标
        while cur != None:
            if cur.elem == item:
                return True
            else:
                cur = cur.next
        return False

完整版:

class Node:  # 元素
    def __init__(self, elem):
        self.elem = elem  # 此节点的数值
        self.next = None  # 下一个节点的内存地址


class SingleLinkList:  # 单向链表
    def __init__(self):
        self.__head = None

    def is_empty(self):  # 链表是否为空
        return self.__head == None

    def length(self):  # 链表长度
        #要考虑到链表为空的情况
        count = 0
        cur = self.__head#游标
        while cur != None:
            count += 1
            cur = cur.next
        return count

    def travel(self):  # 遍历整个链表
        cur = self.__head#游标
        while cur != None:
            print(cur.elem, end=" ")
            cur = cur.next

    def add(self, item):  # 链表头部添加元素
        node = Node(item)
        node.next = self.__head
        self.__head = node

    def append(self, item):  # 链表尾部添加元素 item为数据,不是节点,让用户使用起来方便,只要用户输入数字
        node = Node(item)
        if self.is_empty():
            self.__head = node
        else:
            cur = self.__head
            while cur.next != None:
                cur = cur.next
            cur.next = node

    def insert(self, pos, item):  # 指定位置添加元素
        count = 0
        cur = self.__head
        if pos <= 0:
            self.add(item)
        elif pos > self.length() - 1:
            self.append(item)
        else:
            while count < pos - 1:#在指定位置的前一个节点,插入新的节点,
                cur = cur.next#游标指向下一个
                count += 1
            node = Node(item)
            node.next = cur.next#新的节点的下一个节点指向原来位置为pos的节点
            cur.next = node#然后在把游标的下一个节点指向要插入的节点,要注意先后顺序

    def remove(self, item):  # 删除节点
        cur = self.__head#游标在第一个节点
        prev = None#此时游标的上一个位置为None
        while cur != None:#当游标部位不为空时
            if cur.elem == item:#找到要删除逇数字
                if cur == self.__head:#如果要删除的节点为第一个节点
                    self.__head == cur.next#把首节点指向第二个节点
                else:
                    prev.next = cur.next#其余情况下则把要删除节点的上一个节点指向下一个节点
                break
            else:
                prev = cur
                cur = cur.next

    def search(self, item):  # 查找节点是否存在
        cur = self.__head#游标
        while cur != None:
            if cur.elem == item:
                return True
            else:
                cur = cur.next
        return False
if __name__ == '__main__':

    sll = SingleLinkList()
    print("是否为空",sll.is_empty())
    print("链表长度",sll.length())
    sll.append(1)
    sll.append(2)
    sll.append(3)
    sll.append(4)
    sll.travel()
    sll.remove(4)
    sll.travel()
    sll.remove(3)
    sll.travel()

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值