数据结构实战:利用JavaScript和Python实现链表

文章目录

  • 一、实战概述
  • 二、链表
    • (一)链表概述
    • (二)结点结构
    • (二)链表结构
  • 三、利用JavaScript实现链表
    • (一)创建LinkedList.js
    • (二)创建LinkedList.html
    • (三)浏览LinkedList.html
  • 四、利用Python实现链表
    • (一)编写程序,实现功能
    • (二)运行程序,查看结果
  • 五、实战总结

一、实战概述

  • 本实战通过JavaScript和Python两种编程语言分别实现单链表数据结构。首先,介绍了链表的基本概念,包括结点(包含数据域和指针域)和链表结构(由多个结点按一定顺序链接而成)。在JavaScript部分,创建了LinkedList.js文件,定义了Node类和LinkedList类,实现了链表的增删查改等核心操作,并通过HTML页面展示其功能;而在Python部分,则直接编写程序并运行,同样实现了链表节点的创建、查找、插入、更新和删除等操作,并实时查看执行结果,以验证链表功能的正确性与实用性。

二、链表

(一)链表概述

  • 链表是一种基本的线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的引用。相比数组,链表具有动态大小、插入和删除高效等优势,但访问元素需遍历。分为单向链表和双向链表,可实现栈、队列等数据结构。链表在内存分配中更灵活,适用于频繁插入删除的场景,是计算机科学中重要的数据结构之一。

(二)结点结构

  • 结点是链表中的基本构建单元,包含数据域和指针域。数据域存储具体数据,而指针域存储指向下一个结点的地址,实现结点之间的连接。这灵活的结构使得链表能够动态地存储和管理数据,支持高效的插入和删除操作。每个结点的指针域充当连接不同结点的桥梁,构建出链表的结构。这种数据结构在计算机科学中被广泛应用,特别适用于需要频繁插入和删除操作的场景。
    在这里插入图片描述

(二)链表结构

  • 链表是一种数据结构,由多个结点组成。每个结点包含数据域,存储具体数据,和指针域,指向下一个结点的地址。通过数据域可以访问所需数据,通过指针域可以访问当前结点之后的结点,形成结点之间的连接。将这些结点串起来构成链表,实现了动态存储和管理数据的功能。链表的灵活性使得它适用于需要频繁插入和删除操作的场景,是计算机科学中常用的数据结构之一。
    在这里插入图片描述

三、利用JavaScript实现链表

(一)创建LinkedList.js

  • js目录里创建LinkedList.js
    在这里插入图片描述
// 定义链表结点类,包含数据(data)和指向下一个结点的指针(next)
class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

// 定义链表类,初始化时设置头结点为一个特殊结点(通常不存储实际数据)
class LinkedList {
    constructor() {
        // 初始化头结点
        this.head = new Node('head');
    }

    /**
     * 根据给定值查找链表中的结点
     * @param value 查找的目标值
     * @returns {Node|-1} 找到的结点或-1表示未找到
     */
    findByValue = (value) => {
        let currentNode = this.head; // 从头结点开始查找

        // 循环直到找到目标值或遍历完整个链表
        while (currentNode != null && currentNode.data !== value) {
            currentNode = currentNode.next;
        }

        // 返回找到的结点或-1
        return currentNode === null ? -1 : currentNode;
    }

    /**
     * 根据索引查找链表中的结点
     * @param index 查找的目标索引
     * @returns {Node|-1} 找到的结点或-1表示索引超出范围
     */
    findByIndex = (index) => {
        let pos = 0;
        let currentNode = this.head;

        // 循环直到找到目标索引位置或遍历完整个链表
        while (currentNode != null && pos !== index) {
            currentNode = currentNode.next;
            pos++;
        }

        // 返回找到的结点或-1
        return currentNode === null ? -1 : currentNode;
    }

    /**
     * 在指定元素后插入新元素
     * @param value 插入的新元素值
     * @param element 插入位置的参考元素值
     */
    insert = (value, element) => {
        let currentNode = this.findByValue(element);

        // 判断是否找到插入位置
        if (currentNode === -1) {
            console.log("未找到插入位置!");
        } else {
            // 创建新结点
            let newNode = new Node(value);
            // 让新结点指向当前结点的下一个结点
            newNode.next = currentNode.next;
            // 让当前结点指向新结点
            currentNode.next = newNode;
        }
    }

    /**
     * 更新指定元素的值
     * @param value 新的元素值
     * @param element 需要更新的元素值
     */
    update = (value, element) => {
        let currentNode = this.findByValue(element);

        // 判断是否找到待更新元素
        if (currentNode === -1) {
            console.log("未找到指定元素[" + element.data + "]!");
        } else {
            currentNode.data = value;
        }
    }

    /**
     * 根据给定值删除链表中的结点
     * @param value 要删除的结点值
     * @returns {number} -1表示未找到要删除的结点,否则返回0表示删除成功
     */
    delete = (value) => {
        let currentNode = this.head;
        let previousNode = null;

        // 寻找要删除的结点
        while (currentNode != null && currentNode.data !== value) {
            previousNode = currentNode;
            currentNode = currentNode.next;
        }

        // 判断是否找到并删除结点
        if (currentNode == null) {
            return -1;
        } else {
            previousNode.next = currentNode.next;
        }
    }

    /**
     * 遍历整个链表并打印所有结点的值
     */
    printAll = () => {
        let currentNode = this.head;

        // 遍历并打印所有结点的数据
        while (currentNode != null) {
            console.log(currentNode.data);
            currentNode = currentNode.next;
        }
    }
}

// 测试链表的各种操作
const list = new LinkedList();
list.printAll();

console.log('插入三个结点:mike, howard, alice');
list.insert('mike', 'head');
list.insert('alice', 'mike');
list.insert('howard', 'mike');
list.printAll();

console.log("按值查找alice结点");
console.log(list.findByValue('alice').data);

console.log('按索引查找2结点');
console.log(list.findByIndex(2).data);

console.log('将alice修改为jenny');
list.update('jenny', 'alice');
list.printAll();

console.log('删除howard结点')
list.delete('howard');
list.printAll();
  • 这段代码定义了一个简单的单链表数据结构,包含结点类(Node)和链表类(LinkedList)。Node类用于创建链表中的每个元素,包含存储数据(data)和指向下一个结点(next)的指针。LinkedList类提供了插入、查找(按值或索引)、更新和删除结点的方法,以及遍历并打印所有结点数据的功能。在测试部分,首先初始化一个空链表,然后插入几个结点,通过各种方法进行操作,并输出结果以验证功能实现正确性。

(二)创建LinkedList.html

  • 在根目录创建LinkedList.html
    在这里插入图片描述
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>链表演示</title>
    <script src="js/LinkedList.js"></script>
</head>

<body>
    <h3>演示如何创建链表以及对链表进行增删改查操作</h3>
</body>

</html>

(三)浏览LinkedList.html

  • 打开调试窗口,查看链表操作结果
    在这里插入图片描述

四、利用Python实现链表

(一)编写程序,实现功能

  • 编写程序 - 实现链表.py
    在这里插入图片描述
# 实现链表数据结构

# 定义链表结点类,包含数据和指向下一个结点的引用
class Node:
    def __init__(self, data):
        self.data = data  # 结点的数据
        self.next = None  # 指向下一个结点的引用

# 定义链表类,包含链表操作方法
class LinkedList:
    def __init__(self):
        # 初始化头结点,通常不存储实际数据
        self.head = Node('head')

    # 根据给定值查找链表中的结点
    def findByValue(self, value):
        currentNode = self.head  # 从头结点开始查找
        while currentNode is not None and currentNode.data != value:  # 循环直到找到目标值或遍历完整个链表
            currentNode = currentNode.next
        return -1 if currentNode is None else currentNode  # 返回找到的结点或-1表示未找到

    # 根据索引查找链表中的结点
    def findByIndex(self, index):
        pos = 0
        currentNode = self.head
        while currentNode is not None and pos != index:  # 循环直到找到目标索引位置或遍历完整个链表
            currentNode = currentNode.next
            pos += 1
        return -1 if currentNode is None else currentNode  # 返回找到的结点或-1表示索引超出范围

    # 在指定元素后插入新元素
    def insert(self, value, element):
        targetNode = self.findByValue(element)  # 查找插入位置的目标结点
        if targetNode == -1:
            print("未找到插入位置!")
        else:
            newNode = Node(value)  # 创建新结点
            newNode.next = targetNode.next  # 新结点指向目标结点的下一个结点
            targetNode.next = newNode  # 目标结点指向新结点

    # 更新指定元素的值
    def update(self, newValue, element):
        targetNode = self.findByValue(element)  # 查找待更新的结点
        if targetNode == -1:
            print("未找到指定元素[" + str(element.data) + "]!")  # 若找不到该结点则输出错误信息
        else:
            targetNode.data = newValue  # 更新结点的数据值

    # 根据值删除链表中的结点
    def delete(self, value):
        currentNode = self.head
        previousNode = None
        while currentNode is not None and currentNode.data != value:  # 寻找要删除的结点
            previousNode = currentNode
            currentNode = currentNode.next
        if currentNode is None:  # 判断是否找到并删除结点
            return -1
        else:
            previousNode.next = currentNode.next  # 删除结点(断开前一个结点与当前结点的连接)

    # 遍历整个链表并打印所有结点的值
    def printAll(self):
        currentNode = self.head
        while currentNode is not None:  # 遍历并打印所有结点的数据
            print(currentNode.data)
            currentNode = currentNode.next


# 测试链表的各种操作
linked_list = LinkedList()
linked_list.printAll()  # 打印初始空链表

print('插入三个结点:mike, howard, alice');
linked_list.insert('mike', 'head')
linked_list.insert('alice', 'mike')
linked_list.insert('howard', 'mike')
linked_list.printAll()  # 插入节点后打印链表

print("按值查找alice结点");
print(linked_list.findByValue('alice').data)

print('按索引查找2结点');
print(linked_list.findByIndex(2).data)

print('将alice修改为jenny');
linked_list.update('jenny', 'alice')
linked_list.printAll()  # 修改节点后打印链表

print('删除howard结点')
linked_list.delete('howard')
linked_list.printAll()  # 删除节点后打印链表
  • 这段代码实现了一个简单的单链表数据结构,包括结点类(Node)和链表类(LinkedList)。Node类定义了链表中每个元素的数据(data)及指向下一个结点(next)的引用。LinkedList类初始化时创建头结点,并提供了按值查找、按索引查找、插入新元素、更新指定元素值、根据值删除结点以及遍历打印所有结点的方法。测试部分展示了如何创建一个链表并进行一系列基本操作,如插入、查找、更新和删除结点等。

(二)运行程序,查看结果

  • 运行程序 - 实现链表.py
    在这里插入图片描述

五、实战总结

  • 本实战通过JavaScript和Python两种编程语言,详细实现了单链表这一基本数据结构。从理论层面介绍了链表的基本概念、节点结构以及链表结构,并通过实际代码展示了如何定义节点类(Node)和链表类(LinkedList),实现链表的增删查改等核心操作。JavaScript部分利用HTML页面直观展示了链表功能的执行结果;Python部分则直接运行程序并输出结果。实战中,不仅创建了链表,还进行了插入、查找(按值和索引)、更新和删除结点的操作演示,验证了链表功能的正确性和实用性。通过本次实战,充分理解了链表在内存管理上的灵活性以及其对于频繁插入删除操作的优势,进一步巩固了对链表这一重要数据结构的理解与应用能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/314317.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字图像处理常用算法的原理和代码实现详解

本专栏详细地分析了常用图像处理算法的数学原理、实现步骤。配有matlab或C实现代码&#xff0c;并对代码进行了详细的注释。最后&#xff0c;对算法的效果进行了测试。相信通过这个专栏&#xff0c;你可以对这些算法的原理及实现有深入的理解&#xff01;   如有疑问&#xf…

中通快递批量查询方法

你是否经常需要处理大量的中通快递单号&#xff0c;却苦于一个个等待查询&#xff1f;现在&#xff0c;有了固乔快递查询助手&#xff0c;这个问题迎刃而解&#xff01;通过批量查询功能&#xff0c;你可以轻松管理、追踪你的中通快递单号&#xff0c;大大提高工作效率。 一、下…

结构体成员 分数比较大小

题目&#xff1a; 代码&#xff1a; #include <bits/stdc.h> #include<cstring>using namespace std;struct Num{double fenzi;double fenmu;char fenhao;};bool cmp(Num r1,Num r2){return r1.fenzi/r1.fenmu<r2.fenzi/r2.fenmu;}int main(){int n;Num num[n…

基于net6的asp.net core webapi项目打包为docker镜像,并推送至私有镜像仓库harbor中

基于net6的asp.net core webapi项目打包为docker镜像&#xff0c;并推送至私有镜像仓库harbor中 0、环境说明1、打包步骤1.1 创建Asp.net core WebApi项目1.2 在Asp.net core WebApi项目根目录下创建Dockerfile文件1.3 在子系统Ubuntu20.04.4中通过docker build生成docker镜像1…

游戏测试大揭秘,帮你轻松过关

游戏测试可以看作是软件测试的一个分支&#xff0c;黑盒测试最基本的要求是会玩游戏。小公司会要求测试能力更加全面的员工&#xff0c;其中除了功能测试还要会性能测试&#xff0c;兼容测试&#xff0c;弱网测试&#xff0c;自动化测试等。 游戏测试是游戏开发过程中必不可少…

vue2-手写轮播图

轮播图5长展示&#xff0c;点击指示器向右移动一个图片&#xff0c;每隔2秒移动一张照片&#xff01; <template><div class"top-app"><div class"carousel-container"><div class"carousel" ref"carousel">&…

Tensorflow2.0笔记 - 修改形状和维度

本次笔记主要使用reshape&#xff0c;transpose&#xff0c;expand_dim&#xff0c;和squeeze对tensor的形状和维度进行操作。 import tensorflow as tf import numpy as nptf.__version__#tensor的shape和维数获取 #假设下面这个tensor表示4张28*28*3的图片 tensor tf.rando…

RAG 详解

原文&#xff1a;GitHub - Tongji-KGLLM/RAG-Survey 目录 RAG调查 什么是RAG&#xff1f;RAG的范式 幼稚的 RAG高级 RAG模块化 RAG如何进行增强&#xff1f;RAG 还是微调&#xff1f;如何评估 RAG&#xff1f;前景 严峻的挑战多式联运扩展RAG的生态系统RAG论文清单 增强阶段 …

C++多线程学习[二]:线程的传参以及传参的一些坑

一、线程的传参 #include<iostream> #include<thread> #include<string> using namespace std; void threadtest(int a,double b,string str) {this_thread::sleep_for(100ms);cout << a << " " << b << " " &…

【Linux】编写第一个小程序:进度条

文章目录 1. 预备知识1.1 简单认识几个函数1.1.1 sleep()1.1.2 fflush()1.1.3 usleep()1.1.4 memset() 1.2 缓冲区1.3 回车与换行 2. 编写入门版的进度条2.1 基本逻辑2.2 美化效果2.3 代码实现2.4 执行效果 3. 编写升级版的进度条3.1 代码实现3.2 执行效果 1. 预备知识 1.1 简…

C++每日一练(15):简单幂计算

题目描述 输入两个数a和b&#xff0c;求a的b次方。 输入 输入两个整数a&#xff0c;b&#xff08;1<a<10&#xff0c;1<b<15&#xff09;。 输出 输出一个正整数&#xff0c;该值<1000000000000。 输入样例 3 3 输出样例 27 参考答案 #include<bits/stdc.h&…

企业级iptalbes防火墙

一、IPtables介绍 Iptables是unix/linux自带的一款开源的基于包过滤(对OSI模型的四层或者是四层以下进行过滤)的防火墙工具&#xff0c;它的功能十分强大&#xff0c;可以对流入和流出服务器的数据包进行很精细的控制。 iptables其实并不是真正的防火墙&#xff0c;我们可以把…

【AI绘画】全网最强midjourney使用方法!新手必收藏!!

手把手教你入门绘图超强的AI绘画程序Midjourney&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。下面是Midjourney注册和使用的方法。给大家带来了全新保姆级教程资料包**&#xff08;文末可获取&#xff09;** 第一步&#xff1a; 先注册一个D…

10 sping核心技术验证(Validation) 数据绑定(Data Binding)

Validation Spring提供了一个Validator接口&#xff0c;您可以使用它来验证对象。Validator接口通过使用Errors对象来工作&#xff0c;以便在进行验证时&#xff0c;验证器可以向Errors对象报告验证失败public class Person {private String name;private int age;// the usua…

代码随想录算法训练营第三天| LeetCode203.移除链表元素、707.设计链表、206.反转链表

文章目录 一、203. 移除链表元素感受代码二、707.设计链表感受代码206.反转链表感受总结一、203. 移除链表元素 感受 我对这道题。从理论上来说太熟悉了。咸鱼讲数据结构常用的方法他都会讲。但是我没上机没写过。到后面上机还是写不出来。giao。 代码 第一次写,想说一下,…

Blazor中使用impress.js

impress.js是什么&#xff1f; 你想在浏览器中做PPT吗&#xff1f;比如在做某些类似于PPT自动翻页&#xff0c;局部放大之类&#xff0c;炫酷无比。 官方示例直接放到Blazor中是不可用的。几经尝试&#xff0c;用以下方法可以实现。 &#xff08;写文不易&#xff0c;请点赞、…

Java常用类---日期时间类

日期时间类 Date类 简介 在Java中&#xff0c;Date类用来封装当前的日期和时间。Date类提供两个构造函数来初始化对象&#xff0c;如下所示。 通过Date() 使用当前日期和时间来初始化对象。 通过Date(long millisec) 来初始化对象&#xff0c;其中的参数是从1970年1月1日起…

RS触发器

转自&#xff1a;【基础】RS触发器_两个或非门构成rs触发器-CSDN博客 RS触发器为什么能 “保持上一状态” 触发器就是在常规的门电路的基础上加入了反馈&#xff0c;这样触发器就实现了存储数据的功能。这也是上面章节 “RS触发器实验” 的 RS触发器特征表 中第3条 “保持上一…

Redis的优化

1 Redis的高可用 1.1 高可用的定义 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&…

mat数据格式转png

目的 将多个.mat数据格式转化成多个文件夹下的png图片格式 即 一个PAT.mat文件&#xff0c;生成一个PAT文件夹下的图片 方法 1 单文件处理 import scipy.io as scio from PIL import Image import numpy as npdef MatrixToImage(data):data data*255new_im Image.fromarray…