【链表】——数据结构与算法

本文深入讲解链表数据结构,包括单链表、双链表及循环链表的概念、存储方式和基本操作。并提供C++与Python代码示例,帮助读者理解链表的设计与实现。

一、什么是链表?

链表分为三种:
1) 单链表:指针域只能指向结点的下一个结点
链表是一种通过指针串联在一起的线性结构。每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思),链接的入口节点称为链表的头结点也就是head。
如图所示(单链表):在这里插入图片描述

2)双链表: 每个结点有两个指针域,一个指向下一个结点,一个指向上一个结点
如图所示:
在这里插入图片描述

3)循环链表:链表首尾相连
在这里插入图片描述

二、链表的存储方式

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
在这里插入图片描述
这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。

三、链表的定义

C++

struct Node{
	int val;  //结点上的存储元素
	ListNode *next  // 指向下一个结点
	ListNode(int x) : val(x), next(NULL){} // 结点的构造函数
}

Python

def __init__(self, val, next=None):
    self.val = val
    self.next = next

四、链表的操作

1) 删除结点

删除D结点,如图所示
在这里插入图片描述
只要将C节点的next指针 指向E节点就可以了。 但D结点还存留在内存中,只是不在这个链表里。
C++里最好手动释放该节点,释放内存。对于其他(python,java)有自己的自动回收机制,不用手动释放。

2) 添加结点

如图所示
在这里插入图片描述

3) 性能分析

数组与链表作对比:
在这里插入图片描述

  • 数组在定义的时候,长度就是固定的,如果想改动数组的长度,就需要重新定义一个新的数组。

  • 链表的长度可以是不固定的,并且可以动态增删, 适合数据量不固定,频繁增删,较少查询的场景

五、 设计链表

此题经典至极,熟练掌握此题可对链表的 增、删、改、查 操作跟深入了解。

在这里插入图片描述

class Node:
    def __init__(self, val):
        self.val = val
        self.next = None

class MyLinkedList(object):
    def __init__(self):
        self._head = Node(0)   # 虚拟头结点
        self._count = 0        # 添加结点数

    def get(self, index):
        if index < 0 or index >= self._count:
            return -1
        else:
            cur = self._head    # 定义一个cur指针 指向虚拟头结点
            for i in range(index+1):
                cur = cur.next
            return cur.val

    def addAtHead(self, val):
        """
        :type val: int
        :rtype: None
        """
        self.addAtIndex(0, val)


    def addAtTail(self, val):
        """
        :type val: int
        :rtype: None
        """
        self.addAtIndex(self._count, val)


    def addAtIndex(self, index, val):
        """
        :type index: int
        :type val: int
        :rtype: None
        """
        if index > self._count:
            return 
        elif index < 0:
            index = 0
        self._count += 1         # 计数+1
        add_node = Node(val)     # 定义新结点
        pre_node, current_node = None, self._head
        for _ in range(index + 1):
            pre_node, current_node = current_node, current_node.next
        else:
            pre_node.next, add_node.next = add_node, current_node


    def deleteAtIndex(self, index):
        """
        :type index: int
        :rtype: None
        """
        if 0 <= index and index < self._count:
            self._count -= 1   # 计数-1
            pre_node, current_node = None, self._head
            for _ in range(index+1):
                pre_node, current_node = current_node, current_node.next
            else:
                pre_node.next, current_node.next = current_node.next, None

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值