IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构-链表(linklist)介绍与实现 -> 正文阅读

[数据结构与算法]数据结构-链表(linklist)介绍与实现

介绍

链表和数组一样,都用来存储一系列的元素。但是链表和数组实现的机制完全不同。从而导致其相关操作的效率也有所不同。

链表的特点

  • 链表是一种物理存储单元上非连续、非顺序的存储结构
  • 链表直观形态,每个节点元素都有保存了下一个节点的引用,头部指向第一个节点,最后一个节点指向null。
    在这里插入图片描述

链表和数组的区别

优点

  • 链表存储空间是非连续的而数组的存储空间是连续的。因此链表的内存利用率会更高一点。
  • 链表在头部插入元素和中间插入元素的效率会比数组的效率要高
  • 链表在存储数据过程中无须确定链表的长度,而数组需要确定数组的长度,即使某些语言数组是可变长度的,其背后的原理其实也新建了长度更长的数组然后将其拷贝到新数组中最后返回新数组的引用。

缺点

  • 链表查询效率比数组的查询效率要低很多因为他访问元素的过程中需要从头开始遍历,而数组可以通过下标直接访问。

链表的组成

  • Head :指向链表的第一个节点
  • Node:节点(包含着两项数据,一个是data用于存放当前节点的元素,一个是next用于存放下一个节点的引用)
  • Length:记录链表的长度

链表的常见方法

  • append(element)
  • insert(position,element)

  • remove(data)
  • removeAt(position)

  • update(position,data)

  • get(position)
  • indexOf(data)
  • isEmpty()
  • size()
  • toString()

链表的实现

基本实现

  • 实现内部函数Element 用户创建Element对象存储数据以及下一个节点的引用
  • 实现append()方法完成追加元素的操作
  • 实现toString()方法将链表中的元素转化为字符串的形式并返回
  • 添加head属性用于存放链表的第一个节点
  • 添加length属性用来记录链表中元素的个数

实现上述内容,链表就有了最基本功能和“初步的框架”

//链表的实现
function Linklist (){
	//相当于JAVA中的内部类,用于创建一个节点对象,存放数据和下一个元素的索引
    function Element (data){
        this.data = data
        this.next = null
    }
    this.head = null
    this.length = 0
    //向链表添加元素
    Linklist.prototype.append = function (value){
        let ele = new Element(value)
        let current =  this.head
        if (this.length == 0){
            this.head = ele
        }else {
            while (current.next){
                current = current.next
            }
            current.next = ele
        }
        this.length+=1
    }
    //将链表的内容转换成字符串以逗号进行分割
    Linklist.prototype.toString = function (){
        let current =  this.head
        let str = ""
        //此处循环条件用current.next循环结束在current将会指向最后一个节点,如果条件是cureent的话循环结束后指向的是null。
        while (current.next){
            str+=`${current.data},`
            current = current.next
        }
        str += `${current.data}`
        return str
    }
}

let linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
console.log(linklist.length)
console.log(linklist.toString())

运行结果
在这里插入图片描述

所有常用方法完的整实现

//链表的实现
function Linklist (){
    function Element (data){
        this.data = data
        this.next = null
    }
    this.head = null
    this.length = 0
    //向链表添加元素
    Linklist.prototype.append = function (value){
        let ele = new Element(value)
        let current =  this.head
        if (this.length == 0){
            this.head = ele
        }else {
            while (current.next){
                current = current.next
            }
            current.next = ele
        }
        this.length+=1
    }

    //将链表中的元素转换成字符串的形式返回
    Linklist.prototype.toString = function (){
        let current =  this.head
        let str = ""
        while (current.next){
            str+=`${current.data},`
            current = current.next
        }
        str += `${current.data}`
        return str
    }

    //判断链表是否为空
    Linklist.prototype.isEmpty = function (){
        return this.length == 0
    }

    //查询链表的长度
    Linklist.prototype.size = function (){
        return this.length
    }

    //获取下标对应的元素
    Linklist.prototype.get = function (position){
        if (position<0 || position >= this.length) return null
        let current = this.head
        for (let i = 0 ;i < position;i++){
            current = current.next
        }
        return current.data
    }

    //向链表中的元素插入元素,允许在最后面插入元素也不算越界
    Linklist.prototype.insert = function (position,data){
        //越界判断
        if (position<0 || position>this.length) return false
        let ele = new Element(data)
        let current = this.head
        if (position == 0){
            ele.next = this.head
            this.head = ele
        }else {
            let i = 0;
            let previous = null;
            //我们通过循环主要是要获取的内容是position对应下标的节点以及他的上一个节点
            while(i<position){//难点是这个条件用小于等于还是小于号;
                previous = current//理解,对于这个循环来说,需要确定好每次循环此处current代表的是哪个节点(这里代表i下标对应的节点)
                current = current.next//此处的current其实代表的但是当前i下标所对应的下一个节点
                i++//我们通过上面两个current瞬时值,得出结论,循环只需要循环到当前position-1(也就是<position即可)次就可以得到【position】对应节点以及他的【position-1】对应节点
            }
            previous.next = ele
            ele.next = current
        }
        this.length++
        return true

    }

    //修改对应坐标的元素
    Linklist.prototype.update = function (position,newData){
        //越界判断
        if (position<0 || position >= this.length) return false
        let current = this.head
        for (let i = 0;i < position;i++){
            current = current.next
        }
        current.data = newData
        return true
    }

    //根据内容获取所对应的下标
    Linklist.prototype.indexOf = function (data){
        let current = this.head
        for (let i= 0;i<this.length;i++){//此处i是多少的时候对应current存放的就是i下标所对应的节点
            if (current.data == data){//如果找到该元素则在此处返回i循环也因此结束无须使用break了
                return i
            }
            //如果循环能正常结束自然,程序能运行到这里,代表没有找到该元素
            current = current.next
        }
        return -1
    }

    //移除对应坐标的节点
    Linklist.prototype.removeAt = function (position){
        //越界判断
        if (position<0 || position >= this.length) return null
        if (position == 0){
            this.head = this.head.next
        }
        let current = this.head
        let previous = null
        for (let i = 0;i<position;i++){
            previous = current
            current = current.next
        }
        previous.next = current.next
        this.length-= 1
        return current.data
    }

    //移除对应内容坐标的节点
    Linklist.prototype.remove = function (data){
        let index = this.indexOf(data)
        return this.removeAt(index)
    }
}
//第一阶段测试
console.log("*******第一阶段测试*******")
console.log()
var linklist = new Linklist()
console.log("是否为空:",linklist.isEmpty())
linklist.append("zhangsan")
linklist.append("lisi")
console.log("是否为空:",linklist.isEmpty())
console.log("length:",linklist.length)
console.log("size:",linklist.size())
console.log(linklist.toString())
console.log("==========================")

//get测试
console.log("*******get测试*******")
console.log()
var linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
console.log(linklist.length)
console.log(linklist.toString())
console.log(linklist.get(-1));
console.log(linklist.get(0));
console.log(linklist.get(1));
console.log(linklist.get(2));
console.log("==========================")

//insert 测试
console.log("*******insert测试*******")
console.log()
var linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
linklist.append("wangwu")
console.log(linklist.length)
console.log(linklist.toString())
console.log(linklist.insert(-1,"hhhh"))
console.log(linklist.insert(0,"zhaoliu"))
console.log(linklist.insert(1,"xiaoming"))
console.log(linklist.insert(5,"xiaodu"))
console.log(linklist.insert(7,"hhhh"))
console.log(linklist.toString())
console.log("==========================")

//update 测试
console.log("*******update测试*******")
console.log()
var linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
console.log(linklist.length)
console.log(linklist.toString())
console.log(linklist.update(0,"wangwu"))
console.log(linklist.toString())
console.log(linklist.update(1,"zhaoliu"))
console.log(linklist.toString())
console.log(linklist.update(-1,"haha"))
console.log(linklist.toString())
console.log(linklist.update(3,"xiaodu"))
console.log(linklist.toString())
console.log("==========================")


//indexOf测试
console.log("*******get测试*******")
console.log()
var linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
console.log(linklist.length)
console.log(linklist.toString())
console.log(linklist.indexOf("hh"));
console.log(linklist.indexOf("lisi"));
console.log("==========================")


//removeAt测试
console.log("*******removeAt测试*******")
console.log()
var linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
console.log(linklist.length)
console.log(linklist.toString())
console.log(linklist.removeAt(-1))
console.log(linklist.toString())
console.log(linklist.removeAt(2))
console.log(linklist.toString())
console.log(linklist.removeAt(1))
console.log(linklist.toString())
console.log("==========================")

//remove测试
console.log("*******remove测试*******")
console.log()
var linklist = new Linklist()
linklist.append("zhangsan")
linklist.append("lisi")
console.log(linklist.length)
console.log(linklist.toString())
console.log(linklist.remove("hhh"))
console.log(linklist.toString())
console.log(linklist.remove("lisi"))
console.log(linklist.toString())
console.log("==========================")

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-02 11:37:50  更:2021-09-02 11:39:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 0:52:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码