简体   繁体   中英

How to use pointers in a circular doubly linked-list

I can't get the compiler to stop looping in the while loop. For this function, there are two chains and you are suppose to weave them together. For example, Chain 1 has a head sentinel node and then 1,2,3,4. Chain 2 has a head sentinel and then 5,6,7,8. Output should be Chain1 - head,1,5,2,6,3,7,4,8 and Chain 2 only has head. An empty chain would still have a head node. If one chain is shorter than the other, the remaining nodes should just append itself to Chain1 because output is always Chain1.

I've been adjusting where things point to and it previously was repeatedly printing out problem 2, now it is repeatedly printing out problem4. I think I'm not pointing out where my pointers should go, but I'm not even sure what they're pointing to right now.

 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;

            }             
        }
       }

    }

This line, just before you print "problem 4":

                this->head_->next = othernode;

should be

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

You don't want to change, head_ unless the list is empty. But you previously checked for that. So you know the list is not empty at this point in the code.

The node that you want to change is the one before current , which is pre->next at that point. The pre->next->next is current , which is a nullptr . You want to set that to othernode .

You also need to add another else :

                } else {
                    break;

This handles the case where current is not null but othernode is. In that case, you're done. But your code would keep looping.


A better solution might be to change the while to

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

and get rid of the internal if . You can then check

if (othernode != other.head_) {

after the while loop. Then just do

    pre->next->next = othernode;

That would get rid of the break .

This also gets rid of the nullptr checks and assignment.


The following code is also problematic.

            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;

You don't want current = current->next , as that advances the pointer and you already have it advanced as either head_->next or nex . So just get rid of that line and othernode = othernode->next .

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

As previously, this should not reference the head_ . That makes it the same value on every iteration. Just

            onex = othernode->next;

I think that this is everything, but I haven't tried to run it. There may be more errors that I didn't notice.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM