<!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>
    
    <script>
        // 封装链表
        function LinkedList(){

            // 内部类
            function Node(data){
                this.data = data
                this.next = null
            }
            // 属性
            this.head = null
            this.length = 0 

            // 1 追加方法
            LinkedList.prototype.append = function(data){ 
                // 1 创建新的节点
                var newNode = new Node(data)  
                // 2 判断是否为第一个节点
                if(this.length == 0){ // 2.1是第一个节点 
                    this.head = newNode
                }else{ 
                    // 找到最后一个节点
                    var current = this.head
                    while(current.next){
                        current = current.next 
                    }  
                    // 最后节点的next 指向新的节点
                    current.next = newNode
                } 
                // 3 lenght +1
                this.length += 1
            }
       
            // 2 toString 方法
            LinkedList.prototype.toSring = function(){
                // 1 定义变量
                var current = this.head
                var listString = ''

                // 2 循环获取一个个的节点
                while(current){
                    listString += current.data + ' '
                    current = current.next
                }

                return listString
            }
        
            // 3 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){
                    newNode.next = this.head 
                    this.head = newNode
                }else{
                    var index = 0 
                    var current = this.head
                    var previous = null
                    while(index++ < position){
                        previous = current
                        current = current.next
                    }  
                    newNode.next = current
                    previous.next = newNode
                }

                // 4 lenght +1 
                this.length += 1
                return true
            }

            // 4 get 方法
            LinkedList.prototype.get = function(position){
              // 1 越界判断
              if(position < 0 || position >=  this.length) return null 
             
              // 获取对应的data
              var current = this.head
              var index = 0 
              while(index++ < position){
                current = current.next
              }

              return current.data 
            }

            // 5 indexOf 方法
            LinkedList.prototype.indexOf = function(data){
                // 1 定义变量
                var current = this.head
                var index = 0

                // 2 开始查找
                while(current){
                    if(current.data == data){
                        return index
                    }
                    current = current.next
                    index += 1
                }
                // 3 没找到 返回 -1
                return -1
            }
       
            // 6 update 方法
            LinkedList.prototype.update = function(position,newData){
                // 1 越界判断 
                if(position < 0 || position >= this.length) return false

                // 2 查找正确的节点
                var current = this.head 
                var index = 0 
                while(index++ < position){
                    current = current.next
                }

                // 将 position 位置的node 的data 修改成 newData
                current.data = newData

                return true
 
            }
        
        
            // 7 removeAt 方法 
            LinkedList.prototype.removeAt = function(position){ 
                 // 1 越界判断 
                 if(position < 0 || position >= this.length) return false

                 // 2 判断是否删除的是第一个节点
                 var current = this.head
                 if(position == 0){
                    this.head = this.head.next
                 }else{
                     var index = 0  
                     var previous = null
                     while(index++ < position){
                        previous = current
                        current = current.next
                     }

                     // 前一个节点的nxet 指向, current 的 next 既可
                     previous.next = current.next
                 }

                 // 3 length-1
                 this.length -= 1 
                 return current.data
            }
       
            // 8 remove 方法
            LinkedList.prototype.remove = function(data){
                // 1 获取 data 在列表中的位置
                var position = this.indexOf(data) 
                // 2 根据位置信息 删除节点 
                return this.removeAt(position)
            }
       
            // 9 isEmpty方法
            LinkedList.prototype.isEmpty = function(){
                return this.length == 0 
            }

            // 10 size 方法
            LinkedList.prototype.size = function(){
                return this.length
            }
        }

        // 测试代码
        // 1 创建 linkedList 
        var list = new LinkedList()

        // 2 测试 append 
        list.append('abc')
        list.append('cba')
        list.append('nba')

    //    console.log(list)

        list.insert(0,'aaa')
        list.insert(3,'bbb')
        list.insert(5,'ccc')
        // console.log(list)

        // 4 测试 get 方法
        // alert(list.get(0))
        // alert(list.get(1))
        // alert(list.get(5))

        // 5 测试 indexOf 方法
        // alert(list.indexOf('abc'))
        // alert(list.indexOf('bbb'))
        // alert(list.indexOf('ccc'))

        // 6 测试 updata 方法
        list.update(0,'mmm')
        list.update(3,'nnn') 
        // console.log(list)

        // 7 removeAt 方法的测试
        // console.log(list.removeAt(0))
        // console.log(list)
        // console.log(list.removeAt(3))
        // console.log(list)

        // 8 remove 方法的测试
        // console.log(list.remove('nnn'))
        // console.log(list)


        console.log(list.isEmpty())
        console.log(list.size())
    </script>
</body>
</html>