线性结构_单向链表

链表

  1. 数组的缺点

                1. 数组通常需要申请一段连续的内存空间来存储元素,并且内存空间的大小是固定的(这里只能说大多数是固定大小的)

                    所以当数组需要扩容时,需要冲洗申请一块更大的内存空间,再把之前的数据拷贝进去,然后再存储需要扩容的数据

                2. 往数组头部或者中间添加元素时,成本很高,因为需要大量元素的位移


  2. 链表

                1. 和数组一样,是一种可以存储多个元素的数据结构

                2. 链表中的元素在内存中不必是连续的一段空间

                3. 数组中的每一个元素由一个存储自身元素的节点和指向下一个元素的引用(指针或链接)组成


  3. 链表的优点(相比于数组)

                1. 内存空间不是不许连续的,可以充分利用计算机的内存,实现灵活的内存动态管理

                2. 链表在创建时,不必确定大小,并且可以无限延伸下去

                3. 链表在插入和删除数据时,时间复杂度为O(1), 效率相比于数组要高得多


  4. 链表的缺点

                1. 链表在访问任一位置的元素时,都需要从头开始访问(无法跳过某些元素而直接定位到那个元素)

                2. 无法通过下标来访问,都需要从头开始一个一个访问,知道找到对应的元素


  5. 链表的方法

                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()                        查看链表是否为空

                9. size()                           返回链表的长度

                10. toString()                      将链表中节点的值按顺序转换成字符输出,以空格隔开

 

  6. 单向链表的代码实现

  // 代码中属性不包含链表长度 this.length属性

function LinkedList(){
        // 封装节点类
        function Node(data){
            // 1. 存储节点的数据
            this.data = data;
            // 2. 存储下一个节点的链接
            this.next = null;
        }

        // 链表的属性
        this.header = null;
        this.length = 0;

        // 链表的方法(不使用this.length属性,即假设该属性不存在)
        // 1. 向链表尾部添加一个新的元素
        LinkedList.prototype.appendItem = function(element){
            // 先构造节点
            var newNode = new Node(element);
            
            if(this.header == null){
                this.header = newNode;
            }else{
                var cur = this.header;
                while(cur.next != null){
                    cur = cur.next;
                }
                cur.next = newNode;
            }
        }

        // 2. 向指定的位置添加一个新的元素
        LinkedList.prototype.insertItem = function(position, element){
            var newNode = new Node(element);
            if(this.header == null){
                alert("链表为空无法查找");
                return 
            }else{
                var cur  = this.header;
                for(var k = 1; k < position; k++){
                    cur = cur.next;
                    if(cur == null){
                        alert("所输入的位置必须为非负整数");
                        return 
                    }
                }
                newNode.next = cur.next;
                cur.next = newNode;
            }
        }

        // 3. 获取指定位置的元素
        LinkedList.prototype.getItem = function(position){
            var cur = this.header;
            for(var i = 0; i < position; i++){
                if(cur == null){
                    alert("所输入的位置必须为非负整数");
                    return 
                }
                cur = cur.next;
            }
            return cur.data;
        }

        // 4. 返回元素在链表中的索引,没有则返回-1
        LinkedList.prototype.indexOf = function(element){
            var cur = this.header;
            var index = 0;
            while(cur != null){
                if(cur.data == element){
                    return index;
                }else{
                    cur = cur.next;
                    index++;
                }
            }
            return -1;
        }

        // 5. 修改某个位置的元素
        LinkedList.prototype.updata = function(position, element){
            var newNode = new Node(element);
            if(position < 0){
                alert("所输入的位置必须为非负整数");
                return 
            }else if(position == 0){
                this.header = newNode;
                return
            }else{
                var index = 0;
                var cur = this.header;
                while(index != position){
                    cur = cur.next;
                    index++;
                    if(cur == null){
                        alert("所输入的位置超过链表长度,请重新输入");
                        return 
                    }
                }
                cur.data = element;
            }
        }

        // 6. 从列表的指定位置删除元素
        LinkedList.prototype.removeAt = function(position){
            var index = 0;
            var cur = this.header;
            while(index != position-1 && cur != null){
                cur = cur.next;
                index++;
            }
            if(cur == null){
                alert("所输入的位置超过链表长度,请重新输入");
            }else{
                cur.next = cur.next.next;
            }
        }

        // 7. 从列表中删除指定元素
        // 此时,这里也可以通过调用前面的 indexOf 和 removeAt 两个函数来实现。
        LinkedList.prototype.remove = function(element){
            var cur = this.header;
            var pos = 1;
            while(cur != null && cur.data != element){
                cur = cur.next;
                pos++;
            }
            if(cur == null){
                alert("所输入的位置超过链表长度,请重新输入");
                return
            }else{
                var cur = this.header;
                for(var k = 2; k < pos; k++){
                    cur = cur.next;
                }
                cur.next = cur.next.next;
            }
        }

        // 8. 查看链表是否为空
        LinkedList.prototype.isEmpty = function(){
            return this.header == null;
        }

        // 9. 返回链表的长度
        LinkedList.prototype.size = function(){
            if(this.header == null){
                return 0;
            }else{
                var index = 1;
                var cur = this.header;
                while(cur.next != null){
                    cur = cur.next;
                    index++;
                }
                return index;
            }
        }

        // 10. 将链表中节点的值按顺序转换成字符输出,以空格隔开
        LinkedList.prototype.toString = function(){
            var res = "";
            var cur = this.header;
            while(cur != null){
                res += cur.data + " ";
                cur = cur.next;
            }
            return res;
        }

   }
View Code

 

 // 代码中属性不包含链表长度 this.length属性

function LinkedList(){
        // 封装节点类
        function Node(data){
            // 1. 存储节点的数据
            this.data = data;
            // 2. 存储下一个节点的链接
            this.next = null;
        }

        // 链表的属性
        this.header = null;
        this.length = 0;

        // 链表的方法(使用this.length属性)
        // 1. 向列表尾部添加一个新的元素
        LinkedList.prototype.appendItem = function(element){
            var newNode = new Node(element);
            if(this.header == null){
                this.header = newNode;
                this.length++;
            }else{
                var cur = this.header;
                for(var i = 0; i < this.length - 1; i++){
                    cur = cur.next;
                }
                cur.next = newNode;
                this.length++;
            }
        }

        // 2. 向指定的位置添加一个新的元素
        LinkedList.prototype.insertItem = function(position, element){
            var newNode = new Node(element);
            if(position > this.length){
                alert("所输入的位置超过链表长度,请重新输入");
            }else{
                var cur = this.header;
                for(var i = 0; i < position; i++){
                    cur = cur.next;
                }
                newNode.next = cur.next;
                cur.next = newNode;
                this.length++;
            }
        }

        // 3. 获取指定位置的元素
        LinkedList.prototype.getItem = function(position){
            if(position > this.length){
                alert("所输入的位置超过链表长度,请重新输入");
            }else{
                var cur = this.header;
                for(var i = 1; i < this.length; i++){
                    cur = cur.next;
                }
                return cur.data;
            }
        }

        // 4. 返回元素在链表中的索引,没有则返回-1
        LinkedList.prototype.indexOf = function(element){
            var cur = this.header;
            var index = -1;
            for(var i = 1; i < this.length; i++){
                if(cur.data == element){
                    index = i - 1;
                    break;
                }
                cur = cur.next;
            }
            return index;
        }

        // 5. 修改某个位置的元素
        LinkedList.prototype.updata = function(position, element){
            if(position > this.length){
                alert("所输入的位置超过链表长度,请重新输入");
            }else{
                var cur = this.header;
                for(var i = 1; i <= position; i++){
                    cur = cur.next;
                }
                cur.data = element;
            }
        }

        // 6. 从列表的指定位置删除元素
        LinkedList.prototype.removeAt = function(position){
            if(position > this.length){
                alert("所输入的位置超过链表长度,请重新输入");
            }else{
                var cur = this.header;
                for(var i = 1; i < position; i++){
                    cur = cur.next;
                }
                cur.next = cur.next.next;
                this.length--;
            }
            
        }

        // 7. 从列表中删除指定元素
        LinkedList.prototype.remove = function(element){
            var cur = this.header;
            for(var i = 1; i < position; i++){
                cur = cur.next;
            }
            cur.next = cur.next.next;
            this.length--;
        }

        // 8. 查看链表是否为空
        LinkedList.prototype.isEmpty = function(){
            return this.header == null;
        }

        // 9. 返回链表的长度
        LinkedList.prototype.size = function(){
            return this.length;
        }

        // 10. 将链表中节点的值按顺序转换成字符输出,以空格隔开
        LinkedList.prototype.toString = function(){
            var res = "";
            var cur = this.header;
            for(var k = 0; k < this.length; k++){
                res += cur.data + " ";
                cur = cur.next;
            }
            return res
        }
   }
View Code

 

posted @ 2020-01-23 11:50  CarreyB  阅读(145)  评论(0编辑  收藏  举报