вставка в односвязный список

Подскажите пожалуйста, как вставить один односвязный список в другой, начиная с индекса.

Я понимаю то, что если будет вставка второго списка в первый начиная с хвоста, то хвост мы поменяем но конец второго списка Что должна принимать функция, реализующая этот метод: только индекс? Нужно ли в методе создавать новый третий список, который будет содержать первый и второй или можно в первый просто вставить во второй?

class Node{
    constructor(value,next=null) {
        this.value=value
        this.next=next
    }
}

class LinkedList {
    constructor() {
        this.head = null
        this.tail = null
    }

Моя нерабочая реализация:

 function insert(index){

        let currentNode=list.head
        let newNode=new(Node)
        while (currentNode.next){
            --index
            currentNode=currentNode.next
            if (index===0){
                let curNode2=list2.head
                while(curNode2.next){
                    newNode.value=curNode2.value
                    newNode.next=curNode2.next
                    curNode2.next=newNode
                }
            }
        }
    }

пример входных данных:

односвязный список 1: head 0 1 2 tail

односвязный список 2: head A B C tail

пример выходных данных:

вызываем function insert(1)

результат: односвязный список 1 становится: head 0 1 A B C 2 tail


Ответы (2 шт):

Автор решения: eternal

функция size() возвращает размер списка

реализация:

 function insert(index) {
    
        if (list.head === null || list2.head === null || index > list.size()) return null
    
        if (index > 0 && index < list.size()) {
    
            let currentNode = list.head
    
            for (let count = 0; count != index - 1; count++) {
                currentNode = currentNode.next
            }
    
            let tempNode = currentNode.next
    
            currentNode.next = list2.head
    
            currentNode = list.head
    
            while (currentNode.next) {
                currentNode = currentNode.next
            }
            currentNode.next = tempNode
        }
    
        if (index === 0) {
            let currentNode = list2.head
            while (currentNode) {
                list.insertBefore(index, currentNode.value)
                currentNode = currentNode.next
                ++index
            }
        }
    
        if (index===list.size()){
    
            let currentNode=list2.head
    
            while (currentNode){
                list.append(currentNode.value)
                currentNode=currentNode.next
            }
        }
    }
→ Ссылка
Автор решения: Stanislav Volodarskiy

Ваша реализация не работает потому что вы создаёте новый узел newNode и затем помещаете в него все значения из второго списка. Есть ещё недостатки, но этого достаточно, чтобы написать новое решение с нуля.

Разностные списки не популярны в русском сообществе, даже в Википедии нет перевода. Это удобная структура, если вам нужно соединять списки вместе за константное время.

Я предполагаю, что insert – метод класса LinkedList. Тогда он принимает два параметра: insert(index, that). index – место вставки, that – список LinkedList, который вставляется.

Для удобства тестирования я поменял конструктор и добавил итератор:

class Node {
    constructor(value, next = null) {
        this.value = value;
        this.next = next;
    }
}

class LinkedList {
    constructor(node = null) {
        this.head = node;
        this.tail = node;
    }

    insert(index, that) {
        if (this.head === null) {
            this.head = that.head;
            this.tail = that.tail;
        } else if (that.head === null) {
        } else {
            if (index === 0) {
                that.tail.next = this.head;
                this.head = that.head;
            } else {
                let insert_after = this.head;
                for (let i = 1; i < index; ++i) {
                    insert_after = insert_after.next;
                }
                if (insert_after === this.tail) {
                    this.tail = that.tail;
                } else {
                    that.tail.next = insert_after.next;
                }
                insert_after.next = that.head;
            }
        }
    }

    [Symbol.iterator]() {
        let node = this.head;
        const tail = this.tail;
        let done = node === null;
        return {
            next() {
                if (done) {
                    return {value: undefined, done};
                }
                const value = node.value;
                done = node === tail;
                node = node.next;
                return {value, done: false};
            }
        };
    }
}


for (let i = 0; i < 4; ++i) {
    const list1 = new LinkedList(new Node('1'));
    list1.insert(1, new LinkedList(new Node('2')));
    list1.insert(2, new LinkedList(new Node('3')));

    const list2 = new LinkedList(new Node('A'));
    list2.insert(1, new LinkedList(new Node('B')));
    list2.insert(2, new LinkedList(new Node('C')));

    list1.insert(i, list2);

    console.log('---------------');
    for (const v of list1) {
        console.log(v);
    }
}

→ Ссылка