0

I am new to c++ and programming in general. I am trying to implement a doubly linked list. I think the list is created successfully, but I am having trouble printing the list out entirely. Can you please let me know what's wrong with my printListForward method below? My code is not complete yet. Would really appreciate any tips and suggestions as well.

#include "MagicSquare.hpp"
#include <iostream>

class MagicSquaresList{

private:

    struct MagicSquaresNode{

        int nodeIndex;
        MagicSquaresNode *pleft;
        MagicSquaresNode *pright;
        MagicSquaresNode *pup;
        MagicSquaresNode *pdown;
    };

    MagicSquaresNode *head;
    MagicSquaresNode *tail;

public:
    MagicSquaresList (){ 
        head = NULL;
        tail = NULL;
    }

    int getListLength(){
        int length = 1;
        MagicSquaresNode *temp = new MagicSquaresNode;
        temp = head;

        if(isEmpty()){
            return 0;
        }else{
            while(temp != tail){
                length++;
                temp = temp->pright;
            }
        }
        return length;
    }

    bool isEmpty(){
        return head == NULL;
    }

    void appendToEnd(int val){
        MagicSquaresNode *newNode = new MagicSquaresNode;
        newNode->nodeIndex = val;

        if(isEmpty()){
            tail = newNode;
        } else {
            tail->pright = newNode;
            newNode->pleft = tail;
        }

        tail = newNode;
    }

    void printListForward() {
        MagicSquaresNode *ptr = head;

        while(ptr != tail){
            std::cout << ptr->nodeIndex << " ";
            ptr = ptr->pright;
        }

        std::cout << std::endl;
    }

};


int main(){

    /*********** temporary *****************/
    int matrixSize, listSize;
    matrixSize = 3;
    listSize = matrixSize * matrixSize;
    /****************************************/

    MagicSquaresList list1;

    for (int i = 1; i <= listSize; i++){
        list1.appendToEnd(i);
    }

    list1.printListForward();
    std::cout << list1.getListLength() << std::endl;
    return 0;

}
melpomene
  • 84,125
  • 8
  • 85
  • 148

2 Answers2

1

You need to set the head.

  void appendToEnd(int val){
    MagicSquaresNode *newNode = new MagicSquaresNode;
    newNode->nodeIndex = val;

    if(isEmpty()){
        tail = newNode;
        head = newNode;
    } else {
        tail->pright = newNode;
        newNode->pleft = tail;
    }

    tail = newNode;
    }
Felipe Centeno
  • 2,911
  • 1
  • 21
  • 39
  • Thank you, Felipe. I made the change to my code and it's able to create the list now. However, when I tried to print out the list, it's missing the last node. In my example, it only printed 1 2 3 4 5 6 7 8 - missing 9. Actually my getListLength() method is also giving 8 as the count of nodes, but I initialized length = 1 to fix the issue. Is it something obvious that I missed? Thanks again! – Yu Han Zheng Sep 29 '16 at 15:50
  • Your while loop iterates until temp == tail. Tail is the last element in this case the 9th element, so when you reached that element you exit the loop without modifying your counter one last time. – Felipe Centeno Sep 30 '16 at 03:50
0

Just a few comments. First you want to use proper indents. For beginner it is important to learn to write a simple Makefile. In your case, I wrote one for you.

Makefile:

  1 bin_PROGRAMS=doublelink
  2 GCCLIBDIR= /usr/local/lib64
  3 CXXFLAGS=-g -std=c++11
  4 CC=g++   
  5 LDFLAGS=-L$(GCCLIBDIR)
  6          
  7 all : $(bin_PROGRAMS)
  8 
  9 doublelink : doublelink.o
 10    $(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

For your source code I did simple editing and named your file: doublelink.cpp:

//#include "MagicSquare.hpp"
#include <iostream>

using namespace std;

class MagicSquaresList{
   private:
      struct MagicSquaresNode {
         MagicSquaresNode(int ni) : nodeIndex(ni), pleft(0), pright(0), pup(0), pdown(0) { }
         int nodeIndex;
         MagicSquaresNode *pleft;
         MagicSquaresNode *pright;
         MagicSquaresNode *pup;
         MagicSquaresNode *pdown;
      };

      MagicSquaresNode *head;
      MagicSquaresNode *tail;

   public:
      MagicSquaresList () { 
         head = 0;
         tail = 0;
      }

      int getListLength(){
         MagicSquaresNode *temp = head;
         if (temp == 0) {
            return 0;
         }
         int length = 0;
         while (temp != 0) {
            ++length;
            temp = temp->pright;
         }
         return length;
      }

      bool isEmpty(){
         return head == 0;
      }

      void appendToEnd(int val){
         MagicSquaresNode *newNode = new MagicSquaresNode(val);
         if (tail == 0) {
            head = newNode;
         } 
         else {
            tail->pright = newNode;
            newNode->pleft = tail;
         }
         tail = newNode;
      }

      void printListForward() {
         MagicSquaresNode *ptr = head;
         while (ptr != 0) {
            //cout << ptr << endl;
            std::cout << ptr->nodeIndex << " ";
            ptr = ptr->pright;
         }
         std::cout << std::endl;
      }

};


int main(){
    /*********** temporary *****************/
    int matrixSize, listSize;
    matrixSize = 3;
    listSize = matrixSize * matrixSize;
    /****************************************/

    MagicSquaresList list1;

    for (int i = 1; i <= listSize; i++){
        list1.appendToEnd(i);
    }

    list1.printListForward();
    std::cout << list1.getListLength() << std::endl;
    return 0;
}

With both file in the directory, you type

make

a binary file doublelink will appear in your directory.
you run this program by typing its name:

$ doublelink 1 2 3 4 5 6 7 8 9 9

But with all these efforts. You should never need to implement double linked list. You should use the C++ standard library and customize the data type for your purpose. The std::list is implemented as double linked list. Please read the document at http://www.cplusplus.com/reference/list/list/. You should create your structure of interest by

list<MagicSquare> myfancySquareList;

myfancySquareList.push_back(MagicSquare(somevalue));

Your double linked list is also missing the destructor, and you are having memory leak. There are many other missing things from your implementation which is usually covered by a text book of several hundred pages. Hope this get you started. When you have trouble, you can run your program in debug mode: gdb doublelink. You can step through it and figure out where is your problem. Your initial problem is a segmentation fault. Try to run your original program and see where it terminate.

Kemin Zhou
  • 6,264
  • 2
  • 48
  • 56
  • Thank you so much, Kemin! Your code clarified a lot of things for me! I will have to study makefile and destructor in more depth, before I am able to implement them. At the moment, I only know the basics of what they do. The reason I am implementing double linked list on my own is that I am learning data structures and C++. I am not very familiar with what C++ Standard Library is able to offer yet. But will definitely learn more about it later. – Yu Han Zheng Sep 29 '16 at 16:52
  • I also found that my original code (after fix) was only able to print out first 8 of the 9 nodes. I looked at your code and saw that your constructor initialized all the pointer members to (0). I made the same change and it fixed my problem. But I don't think I understand the reason behind it. Can you please spare some time to explain? – Yu Han Zheng Sep 29 '16 at 16:53
  • zero for pointer is preferred. Take a look at this post: http://stackoverflow.com/questions/176989/do-you-use-null-or-0-zero-for-pointers-in-c. I will not be repeating here. – Kemin Zhou Sep 30 '16 at 17:16