2017-03-03 247 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())