Как использовать указатели в круговом двусвязном списке - PullRequest
0 голосов
/ 26 января 2019

Я не могу заставить компилятор остановить цикл в цикле while. Для этой функции есть две цепи, и вы должны сплести их вместе. Например, цепь 1 имеет главный дозорный узел, а затем 1,2,3,4. Цепь 2 имеет головной страж, а затем 5,6,7,8. Выход должен быть Chain1 - head, 1,5,2,6,3,7,4,8, а Chain 2 имеет только head. Пустая цепочка все равно будет иметь головной узел. Если одна цепочка короче другой, остальные узлы должны просто присоединиться к Chain1, потому что выходные данные всегда Chain1.

Я настраивал то, на что указывают вещи, и раньше он неоднократно печатал задачу 2, теперь он неоднократно печатал проблему4. Я думаю, что я не указываю, куда мои указатели должны идти, но я даже не уверен, на что они указывают прямо сейчас.

 void Chain::weave(Chain & other) {     
    if(other.height_ != this->height_ || other.width_ != width_){
        cout << "Block sizes differ." << endl;
    } else if (other.size() == 0){
        return;
    }else if (this->size() == 0 && other.size() >= 1){
        this->head_->next = other.head_->next;
        other.head_->next->prev = this->head_;
        this->head_->prev = other.head_->prev;
        other.head_->prev->next = this->head_;
    } else {
        Node * current = head_->next;
        Node * othernode = other.head_->next;
        Node * pre;
        Node * nex;
        Node * opre;
        Node * onex;
        while (current != nullptr || othernode !=nullptr){
            if (current != nullptr && othernode !=nullptr){
                current = current->next;
                othernode = othernode->next;
                opre = othernode->prev;
                onex = other.head_->next->next;
                pre = current->prev;
                nex = current->next;

                current->next = othernode;
                othernode->prev = current;
                nex->prev = othernode;
                othernode->next = nex;
                current = nex;
                othernode = onex;

                cout << this->size() << endl;
                cout << other.size() << endl;
                cout << "problem1" << endl;

                if(onex == other.head_){
                    othernode = nullptr;
                    cout << "problem2" << endl;
                }
                if (current == this->head_){
                    current = nullptr;
                    cout << "problem3" << endl;
                }
            }else if(current == nullptr && othernode != nullptr){

                this->head_->next = othernode;

                cout << "problem4" << endl;

            }             
        }
       }

    }

1 Ответ

0 голосов
/ 26 января 2019

Эта строка непосредственно перед тем, как вы напечатаете «задачу 4»:

                this->head_->next = othernode;

должно быть

                pre->next->next = othernode;
                break;

Вы не хотите менять, head_, если список не пуст. Но вы ранее проверяли это. Таким образом, вы знаете, что список не пуст на данный момент в коде.

Узел, который вы хотите изменить, - это узел перед current, то есть pre->next в этой точке. pre->next->next - это current, то есть nullptr. Вы хотите установить это на othernode.

Вам также нужно добавить еще else:

                } else {
                    break;

Это обрабатывает случай, когда current не нуль, а othernode. В этом случае, вы сделали. Но ваш код будет продолжать цикл.


Лучшим решением может быть изменение while на

while (current != this->head_ && othernode != other.head_) {

и избавиться от внутреннего if. Затем вы можете проверить

if (othernode != other.head_) {

после цикла while. Тогда просто сделай

    pre->next->next = othernode;

Это избавит от break.

Это также избавляет от проверок и назначений nullptr.


Следующий код также проблематичен.

            current = current->next;
            othernode = othernode->next;
            opre = othernode->prev;
            onex = other.head_->next->next;
            pre = current->prev;
            nex = current->next;

            current->next = othernode;
            othernode->prev = current;
            nex->prev = othernode;
            othernode->next = nex;
            current = nex;
            othernode = onex;

Вам не нужен current = current->next, так как он продвигает указатель, и вы уже выдвинули его как head_->next или nex. Так что просто избавьтесь от этой строки и othernode = othernode->next.

            onex = other.head_->next->next;

Как и ранее, это не должно ссылаться на head_. Это делает его одинаковым на каждой итерации. Всего

            onex = othernode->next;

Я думаю, что это все, но я не пытался запустить его. Там может быть больше ошибок, которые я не заметил.

...