iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++和python如何实现单链表
  • 355
分享到

C++和python如何实现单链表

2023-06-29 11:06:31 355人浏览 薄情痞子
摘要

这篇文章给大家分享的是有关c++和python如何实现单链表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、链表的基本概念链表是数据元素的线性集合(Linear Collection),物理存储不连续。那么,这

这篇文章给大家分享的是有关c++python如何实现单链表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

一、链表的基本概念

链表是数据元素的线性集合Linear Collection),物理存储不连续。那么,这种设计的优点是什么?缺点又是什么?

链表的基本结构:

C++和python如何实现单链表

链表是由一系列的“节点”组成在一起的集合,节点(node)由数据域(data)和指针域(next)组成。

从功能上看,data负责存储数据,next负责存储下一个节点的位置。当然,用更加严格的语句来讲,next存储的是其直接后继的地址,关于直接后继的定义见:

链表的分类:

常见的链表种类有:单向链表、双向链表、单向循环链表、双向循环链表,将会在后面文章中单独介绍各种链表的结构和代码实现,以及对应的链表操作。

链表的基本操作:

链表的基础操作包含:插入、删除、查找、合并等,此外还有:反转、排序、深度复制等。

链表的优点:

  • 插入和删除快;

  • 存储空间不受限制,可动态申请扩充,不需事先开辟内存;

链表的缺点:

  • 相比于数组,链表的需要更多的存储空间(需存储指针);

  • 存储不连续导致其访问时间长;

  • 从反向访问角度,单向链表难以反向访问,扩展为双向链表则需要额外存储反向指针;

  • 每次节点访问都需要从头部开始;

二、单链表

基本结构:

C++和python如何实现单链表

单链表的结构含有四个概念:头指针、头结点、普通Node、尾结点,下面分别介绍:

  • 头指针指向头结点,是单链表的表示,必不可少;

  • 头结点是单链表的第一个节点,其数据域内容一般无效;

  • 普通Node即用于数据存储和直接后继指针存储的节点;

  • 尾结点即链表中最后一个节点,其指针域next为空,其后无节点;

单链表的基本操作:

针对单链表常见的操作有:增、改、查、删等,

常用的操作如下:

(1)增

对链表添加元素一般有三种方法:头插法(add)、尾插法(append)、任意位置插入法(insert)。

(2)改

改动链表中某个节点的data

(3)查

查找分为按值查找和按位置查找两种,前者表示按照值查找对应位置,后者表示按位置查找对应值;

(4)删

删除分为按值删除和按位置删除两种;前者表示按照值删除对应节点,后者表示按照位置删除对应节点;

实现说明:

按照自己目前所看的资料,一般都会实现下面介绍的这些函数,具体介绍放在Python和C++实现中。

C++和python如何实现单链表

1.python实现

(1)节点设计

按照单链表的定义可知,节点包含数据域data和指针域next

C++和python如何实现单链表

但是由于next和python的内置函数next()重名,所以指针域使用pointer表示。

代码如下:

class Node:    def __init__(self, data):        """        Args:            data: data of node, any type         """        self.data = data        self.pointer = None
(2)链表类:Single_Linked_List

上述Node类对象即为链表的基本组成结构,可以用于实现头结点、普通节点和尾结点。

因此,链表类只需要提供头指针:

class Single_Linked_List:    def __init__(self, node=None):        self.__head = node
(3)判断链表是否为空:is_empty()函数

实际上,只需要判断头指针是否指向Node类对象(或是否等于None),就可判断一个链表是否为空:

def is_empty(self):    """判断链表是否为空"""    if self.__head == None:        return True    else:        return False
(4)头插法:add()函数

在链表头进行节点插入是很常见的插入操作,这种方式使得“先插入的节点在链表尾部”。头插法需要将头指针指向新的节点,并让新的节点指向原来的头结点:

def add(self, data):    """Add dnode into head    """     # 创建新节点    node = Node(data)    # 令新的节点指向原来的头结点    node.pointer = self.__head    # 令头指针指向新的节点    self.__head = node
(5)尾插法:append()函数

如果想要链表节点次序和插入次序相同,就需要使用尾插法。在插入之前需要判断链表是否为空,如果不为空才能进行插入(可以调用前面定义的is_empty()函数,但是下述代码没有)。

此外,还需要进行链表的遍历操作,找到最后一个节点。单链表只能从表头开始访问,所以每次尾插都必须遍历。

def append(self, data):    """ append node into tail    """    node = Node(data)        # 头指针为空时即为首节点    if self.__head == None:        self.__head = node    # 头指针不为空时进行遍历    else:        current = self.__head        while current.pointer != None:            current = current.pointer        current.pointer = node
(6)在任意位置插入:insert()函数

前面介绍的头插法和尾插法,其原理相对简单,但是并不能完全满足插入需求。如果知道目标插入的位置,可以采用insert()函数实现任意位置的节点插入。

需要注意的是,在实现insert()函数时必须考虑到“position”参数可能出现的几种情况。比如python中并没有明确的类型要求,所以要检查“position”是不是int类型。

对于核心的节点插入实现功能,需要找到目标插入位置对应的节点,并使得这个节点指向新节点,让新节点指向原位置节点的后一个节点。这个过程类似于铁链中加入铁环的过程,要保证新铁环和原来的两个铁环相连接。

def insert(self, position, data):    """在任意位置插入节点    Args:        position:插入节点的位置,int        data:插入节点的值    """        if not isinstance(position, int):        raise ValueError("expect type is 'int', but Got {}".fORMat(position.__class__))        # 头插法    if position <= 0:        self.add(data)    # 尾插法    elif position > self.get_length():        self.append(data)        else:        current = self.__head        current_position = 0        node = Node(data)        # 目的:计算出插入位置        while current_position < position -1:            current_position += 1            current = current.pointer        # 首先:必须使得当前节点的pointer指针指向新建的node        # 其次:必须保证新建的node的pointer指向当前节点的后一个节点        node.pointer = current.pointer        current.pointer = node
(7)计算链表长度:get_length()函数

对于调用者和类内部的其它函数来做,链表长度是一个非常有用的值。比如在插入函数insert()中,需要判断插入位置是不是大于链表长度。

计算链表长度的实现比较简单,只需要遍历链表的所有节点,并用计数器来统计节点的数目即可。

def get_length(self):    """ 获取链表的长度"""    # 没有任何node    if self.__head == None:        return 0    # 节点数统计    else:        current = self.__head        length = 0        while current != None:            current = current.pointer            length += 1        return length
(8)遍历所有节点:traversal()函数

链表、树、图等结构都需要遍历操作,其中链表的遍历比较简单,只需要依次的访问所有节点即可。

def traversal(self):    current = self.__head    i = 0    # 循环结束的条件依旧是节点的pointer指向不为空    while current !=  None:        print("Element {} is {} ".format(i, current.data))        current = current.pointer        i += 1
(9)搜索:search()函数

前面提到搜索有按值搜索和按位置搜索两种,它们的原理和实现都十分相似,所以仅以按值搜索为例。

需要注意的是,insert()函数需要判断链表是否为空,并且需要考虑到目标值不在链表中的情况,分别对应不同的返回值。

def search(self, data):    """ 返回值为data的第一个节点"""    if self.__head == None:        return -1    else:        current = self.__head        current_position = 0        # 遍历节点        while current != None:            # 目标值搜索成功            if current.data == data:                return current_position            # 目标值搜索不到则继续搜索                   else:                current_position += 1                current = current.pointer    # 目标值不存在于链表中             return False
(10)删除:delete()函数

上述的查找中以“按值查找”为例,这次删除中同样以“按值删除”为例,“按位置删除”的实现与之类似。

按值删除,即删除目标值对应的目标节点。在进行遍历时,需要记录当前节点和当前节点的前一个节点。因为,一旦查找大目标值所在的目标节点,需要令目标节点的前一个节点指向目标节点的下一个节点,即完成节点的删除。

def delete(self, data):    """ 删除值为data的第一个节点"""    if self.is_empty():        return None        # 记录当前节点和前一个节点    current = self.__head    piror = None    while current != None:        # 查找成功分为两种情况        if current.data == data:            # 目标节点为头结点            if current == self.__head:                self.__head = self.__head.pointer                return True             # 目标节点不是头结点             # 令目标节点的前一个节点指向目标节点的后一个节点               else:                piror.pointer = current.pointer                return True         # 更新当前节点和前一个节点         else:            piror = current            current = current.pointer    return False

2.C++实现

前面的python实现中已经分析了各个函数的作用,以及对应的实现过程。虽然python和C++的语法不同,但是核心过程是类似的,所以下面不再重复对过程的叙述。

(1)节点设计

由于C++的指针必须指定类型,所以需要使用空指针NULL作为pointer的值。

class Node{public:    int data;    Node *pointer=NULL;};
(2)链表类:SingleLinkedList

遵循声明和实现分类的策略,先对各个函数进行声明。

class SingleLinkedList {public:    SingleLinkedList();    bool isEmpty();    int getLength();    void add(int data);    void append(int data);    void insert(int position, int data);    void traversal();    int search(int data);    void remove(int data);private:    Node *head;};
(3)判断链表是否为空:isEmpty()函数
bool SingleLinkedList::isEmpty() {    // 头结点不指向任何结点,为空    if (head->pointer == NULL) {        return true;    }    else {        return false;    }}
(4)头插法:add()函数
void SingleLinkedList::add(int data) {    // 当原列表仅有头结点时,直接插入新节点即可    if (head->pointer == NULL) {        head->pointer = new Node;        head->pointer->data = data;            }    // 当原列表头结点后面含有后继节点时    // 令头结点直接后继为新节点    // 并令新节点的直接后继为原来头结点的直接后继    else {        // 临时存储头结点的直接后继        Node *temp = head->pointer;        head->pointer = new Node;        head->pointer->data = data;        head->pointer->pointer = temp;    }}
(5)尾插法:append()函数
void SingleLinkedList::append(int data) {    Node *current = head->pointer;    // 找到列表的最后一个节点的位置current    // current的指针域为NULL    while (current->pointer!=NULL)    {        current = current->pointer;    }    // 令current的指针域指向新节点,完成插入    current->pointer = new Node;    current->pointer->data = data;}
(6)在任意位置插入:insert()函数
void SingleLinkedList::insert(int position, int data) {    // 头插法    if (position <= 0) {        add(data);    }    // 尾插法    else if (position > getLength()){        append(data);    }    else {        // 令头指针所在的位置为0        int current_position = 0;        Node *current = head;        Node *prior = NULL;        // 查找目标节点位置current,并记录其直接前驱节点piror        while (current_position<position)        {            // 更新当前节点和直接前驱            prior = current;            current = current->pointer;            current_position++;        }        // 目标位置的直接前驱prior指向新节点        // 新节点指向目标位置的节点        prior->pointer = new Node;        prior->pointer->data = data;        prior->pointer->pointer = current;    }};
(7)计算链表长度:getLength()函数
int SingleLinkedList::getLength() {    int counter = 0;    Node *current = head;    // 遍历链表,直到最后一个元素    while (current->pointer!=NULL)    {        counter++;        current = current->pointer;    }    return counter;}
(8)遍历所有节点:traversal()函数
void SingleLinkedList::traversal() {    Node *current;    // 指向头结点的直接后继    current = head->pointer;    int counter = 1;    // 遍历链表,输出每个节点的值    while (current!=NULL)    {        printf("Element in %d is %d \n", counter, current->data);        counter++;        current = current->pointer;    }}
(9)搜索:search()函数
int SingleLinkedList::search(int data) {    int current_position = 1;    Node *current = head->pointer;    while (current!=NULL)    {        // 搜索成功返回当前位置        if (current->data == data) {            return current_position;        }        // 继续更新位置;        current = current->pointer;        current_position++;    }    // 搜索失败,返回-1    return -1;}
(10)删除:remove()函数
void SingleLinkedList::remove(int data) {    Node *current = head->pointer;    Node *prior = head;    // 遍历链表    while (current!=NULL)    {        // 查找到目标位置        if (current->data == data) {            // 令目标位置的直接前驱指向目标节点的直接后继            prior->pointer = current->pointer;            break;        }        // 更新当前节点和其前驱节点        prior = current;        current = current->pointer;    }}

感谢各位的阅读!关于“C++和python如何实现单链表”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: C++和python如何实现单链表

本文链接: https://www.lsjlt.com/news/324498.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++和python如何实现单链表
    这篇文章给大家分享的是有关C++和python如何实现单链表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、链表的基本概念链表是数据元素的线性集合(Linear Collection),物理存储不连续。那么,这...
    99+
    2023-06-29
  • C++如何实现单链表
    小编给大家分享一下C++如何实现单链表,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!单链表的实现(从入门到熟练)概念和结构概念:链表是一种物理存储结构上非连续、非...
    99+
    2023-06-29
  • C++和python实现单链表及其原理
    目录一、链表的基本概念二、单链表1.python实现(1)节点设计(2)链表类:Single_Linked_List(3)判断链表是否为空:is_empty()函数(4)头插法:ad...
    99+
    2024-04-02
  • C++详解如何实现单链表
    目录单链表单链表的基本操作1.初始化2.取值3.查找4.插入5.删除示例代码开发环境运行结果单链表 链表内存空间不一定连续,其扩展性较好。多余的不多说了。该文主要记录单链表的实现,该...
    99+
    2024-04-02
  • C语言中单链表如何实现
    这篇文章主要介绍“C语言中单链表如何实现”,在日常操作中,相信很多人在C语言中单链表如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言中单链表如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-07-04
  • python实现单链表
    #encoding:utf-8 import sys class Lnode():     def __init__(self,elem,next=None):         self.elem = elem    #节点的值   ...
    99+
    2023-01-31
    链表 python
  • python如何实现单向链表及单向链表的反转
    链表的定义 链表中的每个节点会存储相邻节点的位置信息,单链表中的每个节点只存储下一关节点的位置信息 单向链表的实现 class ListNode: def __init_...
    99+
    2024-04-02
  • python 实现线性链表(单链表)
    初学python,拿数据结构中的线性链表存储结构练练手,理论比较简单,直接上代码。 #!/usr/bin/python # -*- coding:utf-8 -*- # Author: Hui # Date: 2017-10-13...
    99+
    2023-01-31
    链表 线性 python
  • C语言如何实现单链表操作
    本篇内容介绍了“C语言如何实现单链表操作”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1 链表的概念及结构概念:链表是一种物理存储结构上非连...
    99+
    2023-06-29
  • python单向循环链表如何实现
    本篇内容主要讲解“python单向循环链表如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python单向循环链表如何实现”吧!单向循环链表将所有的链接在一起,每一个节点分为数据存储区和链...
    99+
    2023-07-06
  • Python实现单向链表
    单向链表每个节点都是由两部分组成:数据字段和指针,指针指向下一个元素在内存中的位置。 单向链表的第一个节点节点是链表头指针,而最后一个节点的指针设为None,不指向任何元素。(链表头...
    99+
    2024-04-02
  • php如何实现单链表
    本文将为大家详细介绍“php如何实现单链表”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“php如何实现单链表”能够给你意想不到的收获,请大家跟着小编的思路慢慢深入,具体内容如下,一起去收获新知识吧。php实现...
    99+
    2023-06-06
  • Golang如何实现单链表
    今天小编给大家分享一下Golang如何实现单链表的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. 定义节点// ...
    99+
    2023-07-05
  • C++怎么实现单链表
    本文小编为大家详细介绍“C++怎么实现单链表”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现单链表”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。单链表链表内存空间不一定连续,其扩展性较好。多余的不多...
    99+
    2023-07-02
  • python单链表的实现
    ''' 当加入第一个node节点的时候,会有几个值,(这里的self.tail.next 其实就是node.next) head = item = tail = Node(object element1 memory) item = hea...
    99+
    2023-01-31
    链表 python
  • C++数据结构之单链表如何实现
    这篇文章主要介绍了C++数据结构之单链表如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++数据结构之单链表如何实现文章都会有所收获,下面我们一起来看看吧。一、单链表的定义线性表的链式存储又称为单链表,...
    99+
    2023-06-30
  • 一文弄懂C语言如何实现单链表
    目录一、单链表与顺序表的区别:一、顺序表:二、链表二、关于链表中的一些函数接口的作用及实现1、头文件里的结构体和函数声明等等2、创建接口空间3.尾插尾删4、头插头删 5、单...
    99+
    2024-04-02
  • C++ 实现单链表创建、插入和删除
    目录C++单链表创建、插入和删除1.头节点插入和删除结果2.中间节点插入和删除结果3.尾结点插入和删除结果C++单链表(带头结点)总结归纳代码实现C++单链表创建、插入和删除 这里仅...
    99+
    2024-04-02
  • c语言链表如何实现
    这篇“c语言链表如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“c语言链表如何实现”文章吧。在计算机领域离不开算法和数...
    99+
    2023-06-19
  • C语言如何实现双向链表和双向循环链表
    本文小编为大家详细介绍“C语言如何实现双向链表和双向循环链表”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言如何实现双向链表和双向循环链表”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。双向链表和双向循环链表...
    99+
    2023-06-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作