数据结构(JS实现)——单链表的实现

一、什么是单链表?

单链表是一种链式存取的结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成为:元素(数据元素的映像)+指针(指示后继元素的存储位置),元素就是存储数据的储存单元,指针就是连接每个结点的地址数据。
在这里插入图片描述

二、单链表的封装

    // 封装链表类
    function LinkedList() {
        // 内部的类:节点类
        function Node(data) {
            this.data=data;
            this.next=null;
        }

        // 属性
        this.head=null;
        this.length=0;
        
    }

三、单链表常见的操作(增删改查)

  1. append(element):向链表尾部添加一个新的项
  2. insert(position,element):向链表的特定位置插入一个新的项
  3. get(position):获取对应位置的元素
  4. indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1
  5. updata(position,element):更新某个元素
  6. removeAt(position):从链表的特定位置移除一项(根据位置)
  7. remove(element);从链表移除一项(根据元素)
  8. isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false。
  9. size():返回链表包含的元素个数。
  10. tostring():输出

3.1 append(element):向链表尾部添加一个新的项

步骤:

1.创建新的节点(newNode)

2.判断是否添加的是第一个节点

2.1 是第一个节点

2.2不是第一个节点

2.2.1 找到最后一个节点(使用current游标)

2.2.2 将最后一个节点的next指向新的节点

在这里插入图片描述

  LinkedList.prototype.append=function(data){
             // 1.创建新的节点
            var newNode=new Node(data);
             // 2.判断是否添加的是第一个节点
            if (this.length==0) {
                  // 2.1 是第一个节点
                  this.head=newNode;
            } else {
                 // 2.2不是第一个节点
                 var current=this.head;
                  // 2.2.1 找到最后一个节点
                 while (current.next) {
                     current=current.next
                 }
                  // 2.2.2 将最后一个节点的next指向新的节点
                  current.next=newNode;
            }     
              this.length+=1;
        }

3.2 insert(position,element):向链表的特定位置插入一个新的项

步骤:

1.对position进行越界判断

2.根据data创建newNode

3.判断插入的位置是否为第一个

3.1如图(插在第一位)

3.2如图(插在其他位)

3.1:(插在第一位)

在这里插入图片描述

3.2(插在其他位)

在这里插入图片描述

 /* insert():插入 */
        LinkedList.prototype.insert = function (position, data) {
            // 1.对position进行越界判断
            if (position < 0 && position > this.length) {
                return false
            }
            // 2.根据data创建newNode
            var newNode = new Node(data);
            // 3.判断插入的位置是否为第一个
            if (position == 0) {
                // 3.1如图(插在第一位)
                newNode.next =this.head
                this.head = newNode;
            } else {
                // 3.2如图(插在其他位)
                var index=0;
                var current=this.head;
                var previous=null;
                // 将index停在position节点处
                while (index<position) {
                    previous=current;
                    current=current.next;
                    index+=1;
                }
                // 懂?
                newNode.next=current;
                previous.next=newNode;
            }
            this.length+=1;
            return true;
        }

3.3 get(position):获取对应位置的元素

步骤:

1.对position进行越界判断

2.获取data

/* get(position):获取对应位置的元素 */
        LinkedList.prototype.get=function(position){
            // 越界判断
            if (position < 0 || position >=this.length) {
                return null;
            }
            // 获取想应data
            var index=0;
            var current=this.head;
            while (index<position) {
                current=current.next;
                index++;
            }
            return current.data;
        }

3.4 indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1

步骤:

循环,比较

LinkedList.prototype.indexOf=function(element){
            var index=0;
            var current=this.head;
            console.log(this.length);
            while (index<this.length) {//或者while(current)
                if (current.data==element) {
                    return index;
                }
                current=current.next;
                index+=1
            }
            return -1;
        }

3.5 undata(position,element):修改某个元素的位置

步骤:

1.越界判断

2.查找正确的节点

3.将position位置的node的data修改为newData

 LinkedList.prototype.updata=function(position,element){
            //对position进行越界判断
            if (position<0||position>=this.length) {
                return false;
            }
            var current=this.head;
            var index=0;
            //查找正确的节点
            while (index<position) {
                current=current.next;
                index+=1;
            }
            //将position位置的node的data修改为newData
            current.data=element;
            return true;
        }

3.6 removeAt(position):从链表的特定位置移除一项 (根据位置)

步骤

1.对position进行越界判断

2.判断删除节点类型(position为0)

3.让前一个的next指向current的next

在这里插入图片描述

LinkedList.prototype.removeAt = function (position) {
            //1.对position进行越界判断
            if (position < 0 || position >= this.length) {
                return false;
            }
            // 2.判断删除节点类型
            if (position == 0) {
                this.head = this.head.next;
            } else {
                var current = this.head;
                var index = 0;
                var previous = null;
                while (index < position) {
                    previous = current;
                    current = current.next;
                    index++;
                }
                //3. 让前一个的next指向current的next
                previous.next = current.next;
                current.next = null;
            }
            this.length-=1;
            return true;
        }

3.7 remove(element);从链表移除一项 (根据元素)

步骤:(可直接用removeAt和indexOf结合使用)

获取位置

删除元素

 LinkedList.prototype.remove=function(element){
            var index=0;
            var current=this.head;
            var previous=null;
            while (current) {
                if (current.data==element) {
                    if (index==0) {
                        this.head=this.head.next;
                    } else {
                        previous.next=current.next;
                    }
                    this.length-=1;
                    return true;
                }
                previous=current;
                current=current.next;
                index+=1;
            }
            return -1;
        }

3.8 isEmpty():判空

LinkedList.prototype.isEmpty = function () {
            return this.length==0;
        }

3.9 size():返回链表包含的元素个数。

 LinkedList.prototype.size = function () {
            return this.length;
        }

3.10 tostring():输出

步骤:

1.定义游标

2.循环获取

LinkedList.prototype.tostring=function(){
            // 定义游标
            var currrent=this.head;
            var stringsub="";
            // 循环获取   
            while(currrent){
                stringsub+=currrent.data+" ";
                currrent=currrent.next;
            }
            return stringsub;
        }

四. 源码

   <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单向列表</title>
</head>

<body>
</body>
<script>
    // 封装链表类
    function LinkedList() {
        // 内部的类:节点类
        function Node(data) {
            this.data = data;
            this.next = null;
        }
        // 属性
        this.head = null;
        this.length = 0;

        /*  append(element):向链表尾部添加一个新的项 */
        LinkedList.prototype.append = function (data) {
            // 1.创建新的节点
            var newNode = new Node(data);
            // 2.判断是否添加的是第一个节点
            if (this.length == 0) {
                // 2.1 是第一个节点
                this.head = newNode;
            } else {
                // 2.2不是第一个节点
                var current = this.head;
                // 2.2.1 找到最后一个节点
                while (current.next) {
                    current = current.next
                }
                // 2.2.2 将最后一个节点的next指向新的节点
                current.next = newNode;

            }
            this.length += 1;
        }
        /*   tostring():输出 */
        LinkedList.prototype.tostring = function () {
            // 定义游标
            var currrent = this.head;
            var stringsub = "";
            // 循环获取   
            while (currrent) {
                stringsub += currrent.data + " ";
                currrent = currrent.next;
            }
            return stringsub;
        }

        /* insert():插入 */
        LinkedList.prototype.insert = function (position, data) {
            // 1.对position进行越界判断
            if (position < 0 && position > this.length) {
                return false
            }
            // 2.根据data创建newNode
            var newNode = new Node(data);
            // 3.判断插入的位置是否为第一个
            if (position == 0) {
                // 3.1如图(插在第一位)
                newNode.next = this.head
                this.head = newNode;
            } else {
                // 3.2如图(插在其他位)
                var index = 0;
                var current = this.head;
                var previous = null;
                // 将index停在position节点处
                while (index < position) {
                    previous = current;
                    current = current.next;
                    index += 1;
                }
                // 懂?
                newNode.next = current;
                previous.next = newNode;
            }
            this.length += 1;
            return true;
        }
        /* get(position):获取对应位置的元素 */
        LinkedList.prototype.get = function (position) {
            // 越界判断
            if (position < 0 || position >= this.length) {
                return null;
            }
            // 获取想应data
            var index = 0;
            var current = this.head;
            while (index < position) {
                current = current.next;
                index++;
            }
            return current.data;
        }



        /* indexOf(element):返回元素在列表上的索引。如果链表上没有该元素则返回-1 */
        LinkedList.prototype.indexOf = function (element) {
            var index = 0;
            var current = this.head;
            console.log(this.length);
            while (index < this.length) {//或者while(current)
                if (current.data == element) {
                    return index;
                }
                current = current.next;
                index += 1
            }
            return -1;
        }

        /* undata(position,element):修改某个元素的位置 */
        LinkedList.prototype.updata = function (position, element) {
            //对position进行越界判断
            if (position < 0 || position >= this.length) {
                return false;
            }
            var current = this.head;
            var index = 0;
            //查找正确的节点
            while (index < position) {
                current = current.next;
                index += 1;
            }
            //将position位置的node的data修改为newData
            current.data = element;
            return true;
        }



        /*removeAt(position):从链表的特定位置移除一项(根据位置) */
        LinkedList.prototype.removeAt = function (position) {
            //1.对position进行越界判断
            if (position < 0 || position >= this.length) {
                return false;
            }
            // 2.判断删除节点类型
            if (position == 0) {
                this.head = this.head.next;
            } else {
                var current = this.head;
                var index = 0;
                var previous = null;
                while (index < position) {
                    previous = current;
                    current = current.next;
                    index++;
                }
                //3. 让前一个的next指向current的next
                previous.next = current.next;
                current.next = null;
            }
            this.length -= 1;
            return true;
        }

        /* remove(element);从链表移除一项(根据元素) */
        LinkedList.prototype.remove = function (element) {
            var index = 0;
            var current = this.head;
            var previous = null;
            while (current) {
                if (current.data == element) {
                    if (index == 0) {
                        this.head = this.head.next;
                    } else {
                        previous.next = current.next;
                    }
                    this.length -= 1;
                    return true;
                }
                previous = current;
                current = current.next;
                index += 1;
            }
            return -1;
        }

        /* size():长度 */
        LinkedList.prototype.size = function () {
            return this.length;
        }

        /* isEmpty():长度 */
        LinkedList.prototype.isEmpty = function () {
            return this.length==0;
        }

    }
    var list = new LinkedList();
    list.append('abc');
    list.append('cbb');
    list.append('axx');
    console.log(list.tostring());
    console.log(list.remove(' sss'));
    console.log(list.tostring());
    console.log(list.size());
    console.log(list.isEmpty());
    console.log(list);
</script>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值