Typescript中的LinkedList实现

时间:2017-03-03 21:43:44

标签: typescript linked-list

我目前正在学习数据结构,在尝试在TS中实现LinkedList时,我遇到了几个问题。我添加了几种方法但是虽然它似乎有用,但输出真的很奇怪。

我的问题在评论中。

我的代码:

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());   

6 个答案:

答案 0 :(得分:3)

在我看来,你正在使用TypeScript混合类似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

但由于任何地方都没有类型注释,因此它没有什么用处。至少,Node需要注释,以便您可以拥有更稳定的代码。

作为奖励:console.log()不会将您的LinkedList实例转换为字符串,因为它可以正确显示对象。相反,toString()仅在JavaScript必须将其转换为字符串时自动使用。所以这会奏效:

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

答案 1 :(得分: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())

答案 2 :(得分:0)

这是具有泛型和严格类型的更“ TypeScripty”实现。请注意,删除节点时,我还将返回一个Node而不是节点的内容。

class LinkedNode<T> {
    private _elem: T;
    public next: LinkedNode<T> | null;

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

    get elem(): T {
        return this._elem;
    }
}

class LinkedList<T> {
    private head: LinkedNode<T> | null = null;
    private len = 0;

    constructor(headElement?: LinkedNode<T>) {
        this.head = headElement || null;
    }

    public append(elem: T) {
        let node = new LinkedNode(elem);
        let current: LinkedNode<T>;

        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: number): LinkedNode<T> | null {
        if (pos > -1 && pos < this.len && this.head) {
            let current = this.head;
            let previous: LinkedNode<T> = current;
            let index = 0;

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


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

            if (pos === 0) {
                node.next = current;
                this.head = node;
            } else {
                while (index++ < pos && current.next) {
                    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;
            current = current.next;
        }
        return str;
    }
}

答案 3 :(得分:0)

这是我的实现

export class Link<U> {
    private value: U;
    next: Link<U> | null;

    constructor(value: U) {
        this.value = value;
        this.next = null;
    }

    getValue(): U {
        return this.value;
    }
}

export class LinkedList<T> {
    private list: Link<T> | null;

    constructor()
    constructor(link: Link<T>)
    constructor(link: Link<T>, list?: LinkedList<T>)
    constructor(link?: Link<T>, list?: LinkedList<T>) {
        if (!link) {
            this.list = null;
        } else {
            this.list = link;
        }
        if (list) {
            this.list.next = list.list;
        }
    }

    add(value: T): void {
        let current = this.list;
        if (!current) {
            this.list = new Link<T>(value);
        } else {
            let link = new Link<T>(value);
            link.next = current;
            this.list = link;
        }
    }
}

答案 4 :(得分:0)

我的实现是这样的

class LinkNode { 
    constructor(public data: any, public next: LinkNode | null = null) { }
}

class LinkList { 
    private head: LinkNode | null = null;
    constructor() { }


    get size(): number { 
        let node = this.head;
        let counter = 0;

        while (node) {
            counter++;
            node = node.next;
        }
        return counter;
    }

    get firstNode(): LinkNode | null { 
        return this.head;
    }

    get lastNode(): LinkNode | null { 
        let node = this.head;

        while(node && node.next) 
            node = node.next

        return node;
    }

    insertFirst(data: any) { 
        return this.head = new LinkNode(data, this.head);
    }

    insertLast(data: any): LinkNode { 
        let node = new LinkNode(data);
        if (!this.lastNode) return this.head = node;
        return this.lastNode.next = node;
    }

    removeFirst(): LinkNode | null { 
        return this.head = this.head ? this.head.next : null;
    }

    removeLast(): any { 
        let node = this.head;
        if (!node) return;

        while (node.next) {
            if (!node.next.next) return node.next = null; 
            node = node.next;
        }

    }

    clear() { 
        return this.head = null;
    }

    getAt(index: number): LinkNode | null {
        let node = this.head;
        if (!node) return null;

        for (let i = 0; i < index; i++) { 
            if (!node.next) return node;
            node = node.next; 
        }
        return node;
    }

    get allElements(): string[] { 
        let node = this.head;
        const arr: string[] = [];

        while (node) { 
            if (node.data) arr.push(node.data);
            node = node.next;
        }
        return arr;
    }

}

答案 5 :(得分:0)

这是我的想法:

class Link<T> {
    private value: T;
    public next: Link<T> | null;

    constructor(elm: T, next = null) {
        this.value = elm;
        this.next = next;
    }

    getElem(): T {
        return this.value;
    }


}

class LinkedList<T> {
    private head: Link<T> | null = null;
    public len = 0;

constructor(headElm?: Link<T>) {
    this.head = headElm ?? null;
}

appendFirst(elm: T) {
    this.head = new Link(elm, this.head);
    this.len++;
}

appendLast(elm: T) {
    let current: Link<T>;
    const node = new Link(elm);

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

        current.next = node;
    }

    this.len++;
}

insertAt(elm: T, index: number) {
    if (index > this.len) {
        return;
    }

    if (index === 0) {
        this.appendFirst(elm);
        return;
    } else if (index === this.len || index === -1) {
        this.appendLast(elm);
        return;
    }

    let currentIndex = 0;

    let current: Link<T> = this.head;

    let previous: Link<T>;

    while (currentIndex < index) {
        previous = current;
        current = current.next;
        currentIndex++;
    }

    const node = new Link(elm, current);

    previous.next = node;

    this.len++;
}

removeFirst() {
    this.head = this.head.next;

    this.len--;
}

removeLast() {
    let current: Link<T> = this.head;

    let previous: Link<T>;

    while (current.next) {
        previous = current;
        current = current.next;
    }

    previous.next = null;

    this.len--;
}

removeAt(index: number) {
    if (index >= this.len) {
        return;
    }

    if (index === 0) {
        this.removeFirst();
        return;
    } else if (index === -1 || index === this.len - 1) {
        this.removeLast();
        return;
    }

    let current: Link<T> = this.head;

    let nextNode: Link<T>;

    let prevNode: Link<T>;

    let currentIndex = 0;

    while (currentIndex < index) {
        prevNode = current;

        current = current.next;

        nextNode = current.next;

        currentIndex++;
    }

    prevNode.next = nextNode;

    this.len--;
}

getList() {
    let current = this.head;

    while (current) {
        console.log(current.getElem());

        current = current.next;
    }

    console.log('_____________');
}
}

const node = new Link(130);

const list = new LinkedList(node);

list.appendFirst(10);

list.appendLast(20);

list.appendLast(90);

list.appendLast(30);

list.appendLast(70);

list.getList();

list.removeAt(3);

list.getList();