链表结构

转载自:https://blog.csdn.net/qq_39422642/article/details/78988976,一篇不错的关于链表的讲解,和大家共享。

1.基础 知识
1.1 链表的基本结构

链表是通过一个个节点组成的,每个节点都包含了称为cargo的基本单元,它也是一种递归的数据结构。它能保持数据之间的逻辑顺序,但存储空间不必按照顺序存储。 
如图: 
 
链表的基本元素有:

节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。
head:head节点永远指向第一个节点
tail: tail永远指向最后一个节点
None:链表中最后一个节点的指针域为None值
但链表也分为单向链表和单向循环链表,双向链表和双向循环链表,如图为单向链表和单向循环链表: 

è¿éåå¾çæè¿°
写个基本程序测试一下:

1.2 节点类和链表节点的定义

节点类定义如下:

class Node:
    def __init__(self,cargo = None, next = None):
        self.cargo = cargo
        self.next = next
    def __str__(self):
        #测试基本功能,输出字符串
        return str(self.cargo)
print Node("text")
#输出text


因为任何值都能通过str函数,且能存储下来。

链表怎么定义呢? 
我们可以先定义一个一个节点,如下:

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)


然后再把每个节点的关系表示出来,就OK了

node1.next = node2
node2.next = node3


1.3 顺序打印和逆序打印

因为先前已经建立了关系,所以可以通过输入第一个节点,循环整个链表然后顺序打印整个链表。

def printList(node):
    while node:
        print node
        node = node.next
printList(node1)


使用递归的方法来打印,主要步骤如下:

将list拆分成两个部分,head:第一个元素,tail:其余元素
向后打印
打印第一个元素

def printBackward(lists):
    if lists == None:
        return
    head = lists
    tail= lists.next
    print head,tail
    printBackward(tail)
    print head,tail
printBackward(node1)
1 2
2 3
3 None
3 None
2 3
1 2


事实上,还能更简便。

def printBackward(lists):
    if lists == None:return
    printBackward(lists.next)
    print lists
printBackward(node1)


2.链表的基本操作
在链表的基本操作中,包括插入,删除等,但要注意的是一下的操作是针对非循环链表的,从头节点开始操作,而且我们不能插入 None值到链表中。

2.1 计算链表长度

class Node(object):
#节点类
    #功能:输入一个值data,将值变为一个节点
    def __init__(self, data, next = None):
        self.data = data
        self.next = next

    def __str__(self):
        return self.data

class LinkedList(object):

    def __init__(self, head = None):
        self.head = head
    def __len__(self):
        #功能:输入头节点,返回链表长度
        curr = self.head
        counter = 0
        while curr is not None:
            counter += 1
            curr = curr.next
        return counter


2.2 从前,后插入

从前插入:

被插入数据为空,返回
使用该输入数据创建一个节点,并将该节点指向原来头节点
设置该节点为头节点
时间复杂度和空间复杂度均为O(1)

    def insertToFront(self,data):
        #功能:输入data,插入到头节点前,并更改为头节点
        #输出:当前头节点
        if data is None:
            return None
        node = Node(data,self.head)
        self.head = node
        return node


从后:append

若输入数据为空,返回None
若头节点为空,直接将输入数据作为头节点
遍历整个链表,直到当前节点的下一个节点为None时,将当前节点的下一个节点设置为输入数据
时间复杂度为O(n),空间O(1)

    def append(self,data):
        #功能:输入data,作为节点插入到末尾
        if data is None:
            return None
        node = Node(data)
        if self.head is None:
            self.head = node
            return node
        curr_node = self.head
        while curr_node.next is not None:
            curr_node = curr_node.next
        curr_node.next = node
        return node


2.3 查找与删除

查找

若查找的数据为空,返回
设置头节点为当前节点,若当前节点不为None,遍历整个链表
若当前节点的data与输入的data相同,但会当前节点,否则轮到下一个节点
可见时间复杂度为O(n),空间复杂度为O(1).

    def find(self,data):
        #功能:查找链表的节点data与data相同的节点
        if data is None:
            return None
        curr_node = self.head
        while curr_node is not None:
            if curr_node.data == data:
                return curr_node
            curr_node = curr_node.next
        return None


删除1 
申请两个变量,如果遇到匹配的,不用删除,直接将匹配节点的前一节点指向匹配节点的下一节点,因此需要定义一个前节点和一个当前节点,当前节点用来判断是否与输入数据匹配,前节点用来更改链表的指向。

若输入数据为None,返回
将头节点设置为前节点,头节点的下一个节点设置为当前节点
判断前节点是否与输入数据匹配,若匹配,将头节点设置为当前节点
遍历整个链表,若当前节点与输入数据匹配,将前节点的指针指向当前节点的下一个节点,否则,移到下一个节点
时间复杂度为O(n),空间复杂度为O(1).

   def delete(slef,data):
        #删除节点
        if data is None:
            return None
        if self.head is None:
            return None
        if self.head.data == data:
            self.head = self.head.next
            return
        prev_node = self.head
        curr_node = self.head.next
        while curr_node is not None:
            if curr_node.data == data:
                prev_node.next = curr_node.next
            else:
                prev_node = curr_node
                curr_node = curr_node.next


删除2 
第二种解决办法就是只定义一个变量作为当前节点,使用它的下一个节点去判断是否与数据数据匹配,若匹配,直接将当前节点指向下下一个节点。

时间复杂度为O(n),空间复杂度为O(1).

    def deleteAlt(self):
        #只定义一个变量来完成删除操作
        if data is None:
            return 
        if self.head is None:
            return 
        if self.head.data == data:
            self.head = self.head.next
            return
        curr_node = self.head
        while curr_node.next is not None:
            if curr_node.next.data == data:
                curr_node.next = curr_node.next.next
                return
            curr_node = curr_node.next

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值