2017-03-03 210 views
0

LinkedList的实现目前我正在学习数据结构,我想实现在TS链表时面临的几个问题。我添加了几个方法,但它似乎工作,输出真的很奇怪。在打字稿

我的问题是在注释中。

我的代码:

function LinkedList() {  //why doesn't fat arrow syntax work?? 
          //ie. let LinkedList =() => {...this.append =() => {}...} 
          // prints out TypeError: t.append is not a function 

let Node = (elem) => { 
    this.elem = elem; 
    this.next = null; 
} 

this.head = null; 
this.len = 0; 

this.append = (elem) => { 

    let node = new Node(elem); 
    let current; 

    if(this.head === null){ 
     this.head = node; 
    } else { 
     current = this.head; 
     while(current.next){ 
      current = current.next; 
     } 
     current.next = node; 
    } 
    this.len++; 
} 

this.removeAt = (pos) => { 
    if(pos > -1 && pos < this.len){ 
     let current = this.head; 
     let previous; 
     let index = 0; 

     if(pos === 0){ 
      this.head = current.next; 
     } else { 
      while(index++ < pos){ 
       previous = current; 
       current = current.next; 
      } 
      previous.next = current.next; 
     } 
     this.len--; 
     return current.elem; 
    } else { 
     return null; 
    } 
} 


this.insert = (elem, pos) => { 
    if(pos > -1 && pos < this.len){ 
     let current = this.head; 
     let index = 0; 
     let previous; 
     let node = new Node(elem); 

     if(pos === 0){ 
      node.next = current; 
      this.head = node; 
     } else { 
      while(index++ < pos){ 
       previous = current; 
       current = current.next; 
      } 
      node.next = current; 
      previous.next = node; 
     } 
     this.len++; 
     return true; 
    } else { 
     return false; 
    } 
} 

this.toString =() => { 
    var current = this.head; 
    var str = ''; 
    while(current){ 
     str += current.elem; //output is undefinedundefinedundefined 
       // str += JSON.stringify(current); 
       // prints out {"next":{"next":{}}}{"next":{}}{} 
     current = current.next; 
    } 
    return str; 
} 

} 

let t = new LinkedList(); 
t.append('asd'); //Doesn't work with fat arrow function declaration 
t.append(1); 
t.append(0); 
console.log(t); 
let tt = t.removeAt(1); 
console.log(t,'tt', tt); 
t.insert('asd',2); 
let ttt = t.insert('a', 1) 
console.log(ttt); 
console.log(t); 
console.log(t.toString()); 
+3

是否有一个理由,为什么你不使用类? –

回答

2

在我看来,你是混合ES5的语法(其中人用函数来创建JavaScript的伪类)以打字稿。你不需要那样做。写入正确的打字稿,否则根本没有理由使用TypeScript。

也要小心脂肪箭头函数的语法。它们存在的原因不是要取代功能。在你的情况下,你为什么需要使用它没有真正的理由。事实上,这正是可能是打破你的代码:他们使用你原来的(全球性的?)范围为this职能内的范围, LinkedList的实例本身。

更准确地道的执行你正在试图做的会是这个样子的:

class Node { 
    private elem; 
    private next; 

    constructor(elem) { 
     this.elem = elem; 
     this.next = null; 
    } 
} 

class LinkedList { 
    private head = null; 
    private len = 0; 

    public append(elem) { 
     let node = new Node(elem); 
     let current; 

     if (this.head === null) { 
      this.head = node; 
     } else { 
      current = this.head; 
      while (current.next) { 
       current = current.next; 
      } 
      current.next = node; 
     } 
     this.len++; 
    } 

    public removeAt(pos) { 
     if (pos > -1 && pos < this.len) { 
      let current = this.head; 
      let previous; 
      let index = 0; 

      if (pos === 0) { 
       this.head = current.next; 
      } else { 
       while (index++ < pos) { 
        previous = current; 
        current = current.next; 
       } 
       previous.next = current.next; 
      } 
      this.len--; 
      return current.elem; 
     } else { 
      return null; 
     } 
    } 


    public insert(elem, pos) { 
     if (pos > -1 && pos < this.len) { 
      let current = this.head; 
      let index = 0; 
      let previous; 
      let node = new Node(elem); 

      if (pos === 0) { 
       node.next = current; 
       this.head = node; 
      } else { 
       while (index++ < pos) { 
        previous = current; 
        current = current.next; 
       } 
       node.next = current; 
       previous.next = node; 
      } 
      this.len++; 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public toString() { 
     var current = this.head; 
     var str = ''; 
     while (current) { 
      str += current.elem; //output is undefinedundefinedundefined 
      // str += JSON.stringify(current); 
      // prints out {"next":{"next":{}}}{"next":{}}{} 
      current = current.next; 
     } 
     return str; 
    } 
} 

let t = new LinkedList(); 
t.append('asd'); // Works fine 
t.append(1); 
t.append(0); 
console.log(t); // LinkedList 
let tt = t.removeAt(1); 
console.log(t, 'tt', tt); // LinkedList, 'tt', 1 
t.insert('asd', 2); 
let ttt = t.insert('a', 1) 
console.log(ttt); // true 
console.log(t); // LinkedList 
console.log(t.toString()); //asda0 

但因为没有类型注释的任何地方,它几乎没有多大意义。至少,节点需要注释,以便您可以拥有更稳定的代码。

还有一个好处:console.log()不会将您的LinkedList的实例转换为字符串,因为它可以正确显示对象。相反,toString()仅自动使用JavaScript时必须将其转换到字符串。因此,这会工作:

console.log(t + ""); //asda0 
+0

非常感谢您的详细解答。你能更详细地说明注释(节点)吗? – kazanDipi

+0

你的代码使用的是TypeScript,但它并没有执行任何形式的[types](https://www.typescriptlang.org/docs/handbook/basic-types.html)。你会得到自动完成,但它仍然太动态;你不会让它对你执行任何规则。例如,对于一个LinkedList,使用它可以使用[泛型](https://www.typescriptlang.org/docs/handbook/generics.html),所以你只能添加一个确定的对象键入列表。类型严格的语言的效率来自使用这些类型的结构。 – zeh

0
class Link{ 
    value: number; 
    nextNode: Link; 

    constructor(nodeValue, nodeReference){ 
     this.value = nodeValue; 
     this.nextNode = nodeReference; 
    } 
} 

class LinkedList{ 
    list: Link; 
    _length: number = 0; 
    insertLink(i: number): boolean { 
     if(this.list == null){ 
      this.list = new Link(i, null); 
      this._length++; 
      return true 
     }else{ 
      let temp = this.list; 
      while(temp.nextNode != null){ 
       temp = temp.nextNode 
      } 
      temp.nextNode = new Link(i, null); 
      this._length++; 
      return false 
     } 
    } 

    printLinkList(): void { 
     let temp = this.list; 
     if (this.list == null){ 
      console.log('empty linked list') 
     }else{ 
      while(temp.nextNode != null){ 
       console.log(temp.value); 
       temp = temp.nextNode; 
      } 
      //to show last element 
      console.log(temp.value) 
     } 
    } 

    //last occurrence of a given number 
    searchNodeByValue(i:number): number{ 
     let temp = this.list; 
     let counter = 1; 
     let position = null; 
     if(temp == null){ 
      console.log('empty list'); 
     }else{ 
      while(temp.nextNode != null){ 
       if(temp.value === i){ 
        position = counter; 
       } 
       counter++; 
       temp = temp.nextNode 
      } 
      //check if the last element of the node 
      if (temp.value === i){ 
       position = counter; 
      } 
     } 
     //console.log(position); 
     if(position == null){ 
      return 0; 
     }else{ 
      return position; 
     } 
    } 
    removeListItemByValue(i:number): boolean { 
     if(this.list == null){ 
      return true 
     }else{ 
      let itemPosition = this.searchNodeByValue(i); 
      if(itemPosition == 0){ 
       return true 
      }else{ 
       let temp = this.list; 

       //if its the first element in the stack 
       if(itemPosition == 1){ 
        this.list = this.list.nextNode; 
        return true 
       } 
       //if the element is not first or last 
       while(temp.nextNode.value != i){ 
        console.log('in here'); 
        temp = temp.nextNode; 
       } 
       temp.nextNode = temp.nextNode.nextNode 
      } 
      return true 
     } 
    } 
    removeListItemByPos(i:number): boolean { 
     let temp = this.list; 
     let counter:number = 1; 

     if(i > this._length) return false 

     if(i == 1){ 
      this.list = this.list.nextNode; 
      return true 
     } 

     while(counter != (i-1)){ 
      temp = temp.nextNode; 
      counter ++; 
     } 
     temp.nextNode = temp.nextNode.nextNode; 
    } 

    toString(): String{ 
     let current = this.list; 
     let str = ''; 
     while (current) { 
      str += current.value; //output is undefinedundefinedundefined 
      // str += JSON.stringify(current); 
      // prints out {"next":{"next":{}}}{"next":{}}{} 
      current = current.nextNode; 
     } 
     return str; 
    } 
} 

let obj = new LinkedList(); 
obj.insertLink(1); 
obj.insertLink(2); 
obj.insertLink(3); 
obj.insertLink(4); 

obj.removeListItemByPos(4); 
obj.insertLink(5); 
console.log(obj.toString())