Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
the code send error in this line
course["CS"].student=new Course*[1];
i want create linked list of courses contain linked list of students
here is the code
struct Student{
string name;
int id;
int grade;
Student(string n, int i, int gd ){
name=n;
id=i;
grade=gd;
}
};
struct Course{
string C_Name;
Student **student;
int index;
void add_student(Student *new_student){
student[++index]=new_student;
}
};
Course course[4];
void init(){
course["CS"].student=new Course*[1];
}
Your code doesn't contain any kind of linked list, but only plain arrays.
Apart from that, the last line (course["CS"].student=new Course*[1];) contains some invalid syntax.
An integral or enum type must be used to access an array (strings or char[] wont work)
Assigning a Course** to a Student** object is not allowed
A linked list contains of nodes each having a pointer to the next node. The last node usually has a pointer with value nullptr (C++11) or 0 (older standard). Note: There is also a so-called double linked list, where every node also stores a pointer to the previous one.
A node contains all the data, that you want it to store.
Example:
struct Node {
Node* next;
// other node data here
};
To create a linked list, you first start with one node and set next = nullptr; // 0. To add another node just create a new one and change the pointer of the first one.
Example:
Node* node1 = new Node();
node1 -> next = nullptr;
Node* node2 = new Node();
node2 -> next = nullptr;
node1 -> next = node2;
You start to see a pattern. To insert at the front just create a new Node and set its next to the first already existing node. To insert between two nodes, say node1 and node2:
node1 -> next = newNode;
newNode -> next = node2;
To make it nice one usually writes a wrapper class containing functions such as
InsertNodeAt(Node* node, uint index);
Node* GetNodeAt(uint index);
RemoveNodeAt(uint index);
Since you have two different types of objects (Student and Curse), you might want to use templates and avoid writing a linked list class for each type.
If you want to create your linked list yourself, I recommend doing some additional research (google is your friend) as I have only mentioned a few things.
If you don't mind using the c++ standard library you might be interested in using the already pre-made linked list classes std::forward_list (standard linked list) and std::list (double linked list).
in c++ you didn't defined course["string"], so you may not use "CS" as an index to a Course type object
and *.student is a class Student's object, not Course type
#include <iostream>
#include <stdexcept>
using namespace std;
struct Student{
string name;
int id;
int grade;
Student(string n, int i, int gd ){
name=n;
id=i;
grade=gd;
}
};
struct Course{
string C_Name;
Student **student;
int index;
void add_student(Student *new_student){
student[++index]=new_student;
}
};
Course course[4];
void init(){
// Need allocate space for a new object of class "Course"
Course course;
course.student = new Student*[1];// "student" is Student type but not Course
}
int main()
{
try{
init();
}
catch(...){
return -1;
}
std::cerr <<"your debug info" <<endl;
return 0;
}
And in my own opinion, in c++ you may try reference and it's counter in class Course's definition to class Student. Using printer in this way may cause error unexpected.
Related
I'm trying to create a linked list that has 2 data types and a function that inserts nodes. But in order to insert nodes, I have to create at least 1 empty node first.
linked list struct
struct receipt{
string name;
double price;
receipt* link;
};
function that inserts a node at the end of the list
void insert(receipt** head_name_ref, string new_name, double new_price)
{
receipt* new_name_node = new receipt();
receipt *last = *head_name_ref;
new_name_node->name = new_name;
new_name_node->price = new_price;
new_name_node->link = NULL;
if (*head_name_ref == NULL)
{
*head_name_ref = new_name_node;
return;
}
while (last->link != NULL)
{
last = last->link;
}
last->link = new_name_node;
return;
}
function that print the list
void printList(receipt* n){
while(n!=NULL){
cout<<"Name: "<<n->name<<'\t'<<" ";
cout<<"Price: "<<n->price<<'\t'<<" ";
cout<<endl;
n=n->link;
}
}
main function
int main(){
receipt* head = NULL;
head = new receipt;
insert(&head, "item", 23);
printList(head);
return 0;
}
here is a picture of the output https://i.stack.imgur.com/6Ss02.png
Consider that in a more complex program you would have much more than simply a main function. When creating a data structure you have to store a pointer or reference to an object in some way that other functions can receive or access the pointer. For something this simple a global variable or instance of a struct containing the attributes of the list would suffice. Simply initialize the head to 0 and create the functions needed to manage that global object. Upon the first instantiation of the node, simply assign the head to that pointer.
You've already created a struct that represents a node. Now create another one that represents the list which contains nodes. Within that struct you'd want attributes such as a head that pointers to the first node object or null if it is empty. You can give it a default constructor.
Since this looks like an assignment I'm only giving you some hints and not a complete example, purposefully.
struct SinglyLinkList {
receipt* head;
SinglyLinkList() : head(0) {}
~SinglyLinkList() { // code to iterate and destroy all node objects }
// now define copy constructor and assignment operators if you want or delete those
// possibly some methods to add, remove, print nodes
void print();
add(receipt* r); // could overload to insert at a position
remove(size_t n); // remove nth receipt or overload to remove by some other factor
void removeAll();
receipt
};
// somewhere above the main function you could just instantiate a global list
// Within the main function you may call methods that operate on the
// list and call its methods, or define other global functions if you
// prefer that the list be defined only with the attributes
SinglyLinkList list; // default constructed with head = 0 or head = nullptr if you prefer
First note that when struct receipt is constructed, price and link will be uninitialized (std::string name will be default constructed to an empty string, but double and pointers do not have such a default initialization). This problem will manifest with this line in main:
head = new receipt;
(the problem does not manifest when you create new_name_node because you manually initialized it after the allocation).
Therefore you should better handle struct receipt initialization. The minimum would be something like this:
struct receipt {
std::string name;
double price{ 0 };
receipt* link{ nullptr };
};
You can consider to add a custom constructor.
Now to answer you question:
The question title is how to avoid printing the first node.
To do this you just have to skip one node before starting the loop.
Add the following at the beginning of printList:
if (n != nullptr)
{
n = n->link;
}
However, "solving" the problem like this is not a good idea.
Having a "dummy" first node in a linked list is not the ideal design.
I suggest you redesign your code to avoid it. You can search the web for typical linked list implementations to get some ideas. Then the issue of printing (while skipping a node) will not arise at all.
On a side note: better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.
I'm trying to build a nested linked list in C++ (pretty new to C++).
The node in the list could be an integer value or another linked list that has all integer values.
I have gone through other posts on SO, and I understand I should use a union for multiple data types for the node data type.
This is what I have until now.
class linkedList {
private:
struct node {
union data {
int val;
linkedList* list;
};
data currData;
node* next; // a pointer which will point to the next node
}*p;
My question is how do I start allocating the list pointer within the node struct.
For val, I know I can do p->currData->val =5, for example.
I wouldn't use a union. I would just keep a value for each and a typefield of some sort so you know what it is.
class LinkedList {
public:
class Node {
LinkedList * list = nulptr;
int value = 0;
Node * next = nullptr;
};
};
In this case, if list is nullptr, then it's not a node pointing to a new list. Or you could explicitly add a type, but for something this simple, I probably wouldn't.
p->value = 5;
I am in process of learning c++. I am working on creating a linkedlist data structure. One of the functions that displays the values of nodes in the structure does not work. For some reason the while loop that traverses through nodes doesn't work in the display function, hence I can't see the values in those nodes. Does anyone see what the problem is? I've been staring at the code for a while and not sure what is wrong here.
Thanks for your help in advance.
Header:
// linklist.h
// class definitions
#ifndef LINKLIST_H
#define LINKLIST_H
class linklist
{
private:
// structure containing a data part and link part
struct node
{
int data;
node *link;
}*p;
public:
linklist();
void append(int num);
void addatbeg(int num);
void addafter(int loc, int num);
void display();
int count();
void del(int num);
~linklist();
};
#endif
.cpp file
// LinkedListLecture.cpp
// Class LinkedList implementation
#include"linklist.h"
#include<iostream>
using namespace std;
// initializes data member
linklist::linklist()
{
p =NULL;
}
// adds a node at the end of a linked list
void linklist::append(int num)
{
node *temp, *r;
// if the list is empty, create first node
if(p==NULL)
{
temp = new node;
temp->data = num;
temp->link = NULL;
}
else
{
// go to last node
temp = p;
while(temp->link!=NULL)
temp = temp->link;
// add node at the end
r = new node;
r->data=num;
r->link=NULL;
temp->link=r;
}
}
// displays the contents of the linked list
void linklist::display()
{
node *temp = p;
cout<< endl;
// traverse the entire linked list
while(temp!=NULL) // DEBUG: the loop doesn't work
{
cout<<temp->data<<" ";
temp = temp->link;
}
void main()
{
linklist l;
l.append(14);
l.append(30);
l.append(25);
l.append(42);
l.append(17);
cout<<"Elements in the linked list:";
l.display(); // this function doesn't work
system("PAUSE");
}
You never set p to a non NULL value.
if(p==NULL)
{
p = new node;
p->data = num;
p->link = NULL;
}
I think GWW has highlighted the issue, but part of learning to program it to learn how to identify the mistakes.
If you do something and don't get the expected result you could:
Use the visual c++ debugger to step through and see the values of your variables.
Put in log lines to report information you think is important
inspect the code - if you think something is right but it doesn't work, then go to an earlier step and check it does the right thing.
Add unit tests, or follow design by contract adding pre/post conditions and class invariants.
Learning to program C++ by writing a linked list is like learning math by adding 1 + 1. It is old fashioned thinking, slow and mostly boring without having any context.
Math isn't calculating, like C++ programming isn't pointer manipulation. At some stage you might need to know about it, but your better off learning other important things like stl and boost.
If it was understood that append() ment create something, find the end of the list, add it. you could then see that in you append function you have create something mixed uyp with move to the end of the list, but you never add it.
DEAR All;
Hi, I'm just beginner to C++;
Please help me to understand:
What functions should be in the Linked list class ?
I think there should be overloaded operators << and >>;
Please help me to improve the code (style, errors, etc,)
Thanks for advance. Igal.
Edit:
This is only first stage, the next one will be (hopefully) with templates.
Please review the small code for the integer List (enclosed MyNODE.h and ListDriver1.cpp);
MyNODE.h
// This is my first attempt to write linked list. Igal Spector, June 2010.
#include <iostream.h>
#include <assert.h>
//Forward Declaration of the classes:
class ListNode;
class TheLinkedlist;
// Definition of the node (WITH IMPLEMENTATION !!!, without test drive):
class ListNode{
friend class TheLinkedlist;
public:
// constructor:
ListNode(const int& value, ListNode *next= 0);
// note: no destructor, as this handled by TheLinkedList class.
// accessor: return data in the node.
// int Show() const {return theData;}
private:
int theData; //the Data
ListNode* theNext; //points to the next node in the list.
};
//Implementations:
//constructor:
inline ListNode::ListNode(const int &value,ListNode *next)
:theData(value),theNext(next){}
//end of ListNode class, now for the LL class:
class TheLinkedlist
{
public:
//constructors:
TheLinkedlist();
virtual ~TheLinkedlist();
// Accessors:
void InsertAtFront(const &);
void AppendAtBack(const &);
// void InOrderInsert(const &);
bool IsEmpty()const;//predicate function
void Print() const;
private:
ListNode * Head; //pointer to first node
ListNode * Tail; //pointer to last node.
};
//Implementation:
//Default constructor
inline TheLinkedlist::TheLinkedlist():Head(0),Tail(0) {}
//Destructor
inline TheLinkedlist::~TheLinkedlist(){
if(!IsEmpty()){ //list is not empty
cout<<"\n\tDestroying Nodes"<<endl;
ListNode *currentPointer=Head, *tempPtr;
while(currentPointer != 0){ //Delete remaining Nodes.
tempPtr=currentPointer;
cout<<"The node: "<<tempPtr->theData <<" is Destroyed."<<endl<<endl;
currentPointer=currentPointer->theNext;
delete tempPtr;
}
Head=Tail = 0; //don't forget this, as it may be checked one day.
}
}
//Insert the Node to the beginning of the list:
void TheLinkedlist::InsertAtFront(const int& value){
ListNode *newPtr = new ListNode(value,Head);
assert(newPtr!=0);
if(IsEmpty()) //list is empty
Head = Tail = newPtr;
else { //list is NOT empty
newPtr->theNext = Head;
Head = newPtr;
}
}
//Insert the Node to the beginning of the list:
void TheLinkedlist::AppendAtBack(const int& value){
ListNode *newPtr = new ListNode(value, NULL);
assert(newPtr!=0);
if(IsEmpty()) //list is empty
Head = Tail = newPtr;
else { //list is NOT empty
Tail->theNext = newPtr;
Tail = newPtr;
}
}
//is the list empty?
inline bool TheLinkedlist::IsEmpty() const
{ return (Head == 0); }
// Display the contents of the list
void TheLinkedlist::Print()const{
if ( IsEmpty() ){
cout << "\n\t The list is empty!!"<<endl;
return;
}
ListNode *tempPTR = Head;
cout<<"\n\t The List is: ";
while ( tempPTR != 0 ){
cout<< tempPTR->theData <<" ";
tempPTR = tempPTR->theNext;
}
cout<<endl<<endl;
}
//////////////////////////////////////
The test Driver:
//Driver test for integer Linked List.
#include <iostream.h>
#include "MyNODE.h"
// main Driver
int main(){
cout<< "\n\t This is the test for integer LinkedList."<<endl;
const int arraySize=11,
ARRAY[arraySize]={44,77,88,99,11,2,22,204,50,58,12};
cout << "\n\tThe array is: "; //print the numbers.
for (int i=0;i<arraySize; i++)
cout<<ARRAY[i]<<", ";
TheLinkedlist list; //declare the list
for(int index=0;index<arraySize;index++)
list.AppendAtBack( ARRAY[index] );//create the list
cout<<endl<<endl;
list.Print(); //print the list
return 0; //end of the program.
}
What functions should be in the Linked list class ?
That depends on what you need to do with it. At the very least, one should probably be able to add elements to it, and to look at the elements in the list.
(This is common sense. Because if you can't modify or read your list in any way, what could it ever be used for?)
I think there should be overloaded operators << and >>;
Why? What would they do? I suppose you mean operator << to do insertion, similar to how objects are inserted into C++ IO streams; but what exactly should operator >> do? Extraction/removal of elements of some sort? If you implement insertion and extraction (?) in this manner, probably noone will be able to understand your linked list class. A linked list is not an IO stream. (Those operators with IO streams were chosen for brevity.)
I would advise you against operator overloading if the meaning of the operation is not clear. I would suggest you name your operations more explicitly, e.g. by providing methods add and remove (I'm still guessing at the meaning of the latter operation >> btw.).
Please help me to improve the code (style, errors, etc,)
I don't want to make this the main point on my answer, so just very briefly off the top of my head, some issues:
You should #include <iostream> instead of #include <iostream.h>, and then either add a using namespace std; or write (e.g.) std::cout instead of cout.
Try to get rid of the friend. You should be able to design your classes in a way that doesn't require this. friend is easily misused to get around proper encapsulation. But encapsulation is something you should definitely think about in OOP.
Though that's not an advice to give to a C++ beginner, if you made your linked list class into a template class, it could store different values than just ints. Just take this as a hint for future improvements.
And finally:
Just use the STL ("Standard Template Library") containers which are included in the C++ standard library. I know that "rolling your own" helps understanding how these data structures work, but be aware that the C++ standard library already includes a solid and efficient set of data containers.
0 should be NULL
inline only in the case that you don't care that your code will be public, usually implementation puts in separate file Mylist.cpp file.
Why your destructor virtual, do you have inheritance ?
You can just define struct node instead separate class its better define your list for practice like in stl. http://www.sgi.com/tech/stl/List.html http://www.cplusplus.com/reference/stl/list/
In C++ common to use vector vs linked list in Java
http://www.yolinux.com/TUTORIALS/LinuxTutorialC++STL.html
Which of these is a more correct way to store the first object in a linked list?
Or could someone please point out the advantages/disadvantages of each. Thanks.
class Node
{
int var;
Node *next;
static Node *first;
Node()
{
if (first == NULL)
{
first = this;
next = NULL;
}
else
//next code here
}
}
}
Node* Node::first = NULL;
new Node();
-- OR --
class Node
{
int var;
Node *next;
Node()
{
//next code here
}
}
Node* first = new Node();
The latter is definitely preferable. By making the first node pointer a static class member, you are basically saying that there will only be a single linked list in your whole program.
The second example lets you create several lists.
The first example has the definite drawback of only being able to create a single linked list in your entire program, so I wouldn't do that.
The second works fine, but doesn't shield the user of the class from how the linked list works. It would be better to add a second class, for example named LinkedList, that stores the 'first' pointer and performs list management.
Even better, you could use std::list instead.
It's most usual to have a separate List class and a separate Node class. Node is usually very simple. List holds a pointer to the first Node and implements the various list operations (add, remove, find and so on).
Something like the following
class List
{
public:
List()
{
first = new Node();
}
void insert(int val);
void remove(int val);
// ... and so on
~List()
{
// ... clean up
}
private:
struct Node
{
int val;
Node* next;
Node(int val_ = 0, Node* next_ = 0)
: val(val_), next(next_)
{}
};
Node* first;
};
Note that you can place Node outside List if you want to, but this usually doesn't make much sense.
Presumably you may have more than one list? In which case, the static option is a non-starter.
You definitely don't want the "first" to be a static. This implies there's only one linked list in your entire program. static means that every Node in every linked list in your entire program has the same beginning.
That being said you want your Node to have the fewest responsibilities-- It make sense for it to store its value and be able to get to the next Node. It adds complexity to add the job of1 maintaining the "first" pointer. For example what happens when you insert a new element at the beginning? Then you'd have to update everyone's "first" pointer. Given the two choices above I'd chose the second choice.
I would furthermore add a third choice. Add a "linked list" wrapper that gave you easy access to "first", "last" and allow you to easily insert into and iterate through the list. Something like:
class LinkedList
{
Node* First;
Node* Last;
public:
Node* GetFirst() {return First;}
Node* GetLast() {return Last;}
// insert after "where"
void Insert(Node* where, Node* newNode);
...
}
Not uselessly limiting your code to a single list instance is one very good argument for code variant 2.
However, just from superficially looking at the two examples, the sheer number of lines of code also gives a good indication that variant 2 has merits over variant 1 by being significantly shorter.