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 6 years ago.
Improve this question
I am trying to insert a node into a linked list after it finds a name in the list.
My problem is that when i print out the linked list it prints the nodes up to and including the node containing the name but then outputs infinitely the node I inserted. Any help would be greatly appreciated. Thanks!
(some extra information),(the pointer student is pointing to a dynamically created node already). :)
bool StudentLinkedList::insertStudentAfter(StudentNode* student, string _name)
{
StudentNode* curr = headP;
StudentNode* prev = headP;
while (curr != NULL)
{
if (curr->getName() == _name)
{
StudentNode* dummy = curr -> getnext();
curr->setNext(student);
prev = prev->getnext();
curr=curr ->getnext();
curr->setNext(dummy);
prev = curr;
curr = curr->getnext();
length++;
return true;
}
prev = curr;
curr = curr->getnext();
}
return false;
}
You have to simply insert your new node between curr & prev
If you really want to appreciate accept and upvote the answer
bool StudentLinkedList::insertStudentAfter(StudentNode* student, string _name)
{
StudentNode* curr = headP;
StudentNode* prev = headP;
while (curr != NULL)
{
if (curr->getName() == _name)
{
student->setNext(curr->getnext());
curr->setNext(student);
length++;
return true;
}
prev = curr;
curr = curr->getnext();
}
return false;
}
Your function is too complicated. The more complicated function the more bugs it contains and it is more difficult to read it.:)
The function can be written the following way. I assume that there are defined the following functions
getNext, setNext, getPrev, setPrev
^^^^
Here you are.
bool StudentLinkedList::insertStudentAfter( StudentNode *student,
const std::string &name )
{
StudentNode *current = headP;
while ( current != nullptr && current->getName() != name )
{
current = current->getNext();
}
bool success = current != nullptr;
if ( success )
{
student->setPrev( current );
student->setNext( current->getNext() );
if ( current->getNext() != nullptr )
{
current->getNext()->setPrev( student );
}
current->setNext( student );
}
return success;
}
Take into account that if the list also has a data member called something like tail then the function also has to change the tail variable if current->getNext is equal to nullptr.
For example
if ( current->getNext() != nullptr )
{
current->getNext()->setPrev( student );
}
else
{
tailP = student;
//^^^^
}
Here is a demonstrative program that shows how the class could be defined using your approach
#include <iostream>
#include <string>
class StudentLinkedList
{
private:
class StudentNode
{
private:
StudentNode *next;
StudentNode *prev;
std::string name;
public:
StudentNode( const std::string &name )
: next( nullptr ), prev( nullptr ), name( name ) {}
StudentNode * getNext() const { return next; }
StudentNode * getPrev() const { return prev; }
const std::string & getName() const { return name; }
void setNext( StudentNode *student ) { next = student; }
void setPrev( StudentNode *student ) { prev = student; }
} *head = nullptr, *tail = nullptr;
public:
StudentLinkedList() = default;
StudentLinkedList( const StudentLinkedList & ) = delete;
StudentLinkedList & operator =( const StudentLinkedList & ) = delete;
~StudentLinkedList()
{
while ( head != nullptr)
{
StudentNode *tmp = head;
head = head->getNext();
delete tmp;
}
tail = head;
}
void appendStudent( const std::string &name )
{
StudentNode *student = new StudentNode( name );
appendStudent( student );
}
void insertStudentAfter( const std::string ¤t_name,
const std::string &new_name )
{
StudentNode *student = new StudentNode( new_name );
insertStudentAfter( student, current_name );
}
friend std::ostream & operator <<( std::ostream &os, const StudentLinkedList &lsdt );
private:
void appendStudent( StudentNode *student )
{
if ( tail == nullptr )
{
head = tail = student;
}
else
{
tail->setNext( student );
tail = tail->getNext();
}
}
bool insertStudentAfter( StudentNode *student, const std::string &name )
{
StudentNode *current = head;
while ( current != nullptr && current->getName() != name )
{
current = current->getNext();
}
bool success = current != nullptr;
if ( success )
{
student->setPrev( current );
student->setNext( current->getNext() );
if ( current->getNext() != nullptr )
{
current->getNext()->setPrev( student );
}
else
{
tail = student;
}
current->setNext( student );
}
return success;
}
};
std::ostream & operator <<( std::ostream &os, const StudentLinkedList &lst )
{
for ( StudentLinkedList::StudentNode *current = lst.head;
current != nullptr;
current = current->getNext() )
{
os << current->getName() << ' ';
}
return os;
}
int main()
{
const size_t N = ( 'Z' - 'A' + 1 ) / 2;
StudentLinkedList students;
for ( size_t i = 0; i < N; i++ )
{
char name[2] = { char( 'A' + 2 * i ) };
students.appendStudent( name );
}
std::cout << students << std::endl;
for ( size_t i = 0; i < N; i++ )
{
char new_name[2] = { char( 'A' + 2 * i + 1 ) };
char current_name[2] = { char( 'A' + 2 * i ) };
students.insertStudentAfter( current_name, new_name );
}
std::cout << students << std::endl;
return 0;
}
The program output is
A C E G I K M O Q S U W Y
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Related
I want to implement the sorted bag(collection) data structure(with a singly-linked list) in C++ and I have a problem when I want to test the add function. This is the test:
SortedBag sb(relation1); (relation1 is e1<=e2)
sb.add(5);
std::cout << sb.size()<<" ";
sb.add(6);
std::cout << sb.size() << " ";
sb.add(0);
std::cout << sb.size() << " ";
sb.add(5);
std::cout << sb.size() << " ";
sb.add(10);
std::cout << sb.size() << " ";
sb.add(8);
std::cout << sb.size() << " ";
And it will print 1 2 3 3 4 5 instead of 1 2 3 4 5 6.
This is the add function:
void SortedBag::add(TComp e) {
Node* auxiliarElement = new Node;
Node* CheckSLL = new Node;
int flagStop = 1;
if (this->head == nullptr)
{
auxiliarElement->value = e;
auxiliarElement->freq = 1;
auxiliarElement->next = nullptr;
this->head = auxiliarElement;
}
else {
CheckSLL = this->head;
while (CheckSLL->next != nullptr && rel(CheckSLL->value, e))
{
if (CheckSLL->value == e) {
CheckSLL->freq += 1;
flagStop = 0;
break;
}
CheckSLL = CheckSLL->next;
}
if (CheckSLL == this->head && flagStop)
{
auxiliarElement->value = e;
auxiliarElement->freq = 1;
auxiliarElement->next = this->head;
this->head = auxiliarElement;
flagStop = 0;
}
if (CheckSLL->value == e && flagStop)
{
CheckSLL->freq += 1;
flagStop = 0;
}
if (flagStop) {
auxiliarElement->value = e;
auxiliarElement->freq = 1;
auxiliarElement->next = nullptr;
CheckSLL->next = auxiliarElement;
}
}
}
The size() functions works fine, I will post that too:
int SortedBag::size() const {
int Size = 0;
Node* goThrough = new Node;
goThrough = this->head;
while (goThrough != nullptr) {
Size += goThrough->freq;
goThrough = goThrough->next;
}
return Size;
}
And I can't find out why it doesn't add the frequency from the second 5. Can somebody help me, please? (the struct Node has value,freq and a pointer to the next Node)
For starters these statements
Node* CheckSLL = new Node;
and
Node* goThrough = new Node;
result in memory leaks.
Also this output
And it will print 1 2 3 3 4 5.
does not correspond to the sequence of entered data because the function size counts the total value of frequencies
Size += goThrough->freq;
So as 6 elements were inserted in the list then the output should be
1 2 3 4 5 6
The relation should be specified like e1 < e2 not like e1 <= e2
The function add can be defined very simply. I assume that the relation corresponds to the operator <.
void SortedBag::add( TComp e )
{
Node **current = &this->head;
while ( *current != nullptr && rel( ( *current )->value, e ) )
{
current = &( *current )->next;
}
if ( *current == nullptr || rel( e, ( *current )->value ) )
{
Node *new_node = new Node;
new_node->value = e;
new_node->freq = 1;
new_node->next = *current;
*current = new_node;
}
else
{
++( *current )->freq;
}
}
And you should decide whether the function size returns frequencies or the number of nodes in the list.
Here is a demonstrative program.
#include <iostream>
#include <functional>
template <typename T, typename Comparison = std::less<T>>
class List
{
private:
struct Node
{
T value;
size_t freq;
Node *next;
} *head = nullptr;
Comparison cmp;
public:
explicit List() : cmp( Comparison() )
{
}
explicit List( Comparison cmp ) : cmp( cmp )
{
}
~List()
{
while ( this->head != nullptr )
{
Node *current = this->head;
this->head = this->head->next;
delete current;
}
}
List( const List & ) = delete;
List & operator =( const List & ) = delete;
void add( const T &value );
friend std::ostream & operator <<( std::ostream &os, const List &list )
{
for ( Node *current = list.head; current != nullptr; current = current->next )
{
os << current->value << ':' << current->freq << " -> ";
}
return os << "null";
}
};
template <typename T, typename Comparison>
void List<T, Comparison>::add( const T &value )
{
Node **current = &this->head;
while ( *current != nullptr && cmp( ( *current )->value, value ) )
{
current = &( *current )->next;
}
if ( *current == nullptr || cmp( value, ( *current )->value ) )
{
Node *new_node = new Node { value, 1, *current };
*current = new_node;
}
else
{
++( *current )->freq;
}
}
int main()
{
List<int> list;
list.add( 5 );
list.add( 6 );
list.add( 0 );
list.add( 5 );
list.add( 10 );
list.add( 8 );
std::cout << list << '\n';
return 0;
}
The program output is
0:1 -> 5:2 -> 6:1 -> 8:1 -> 10:1 -> null
I am doing a class assignment, where I have to create a linked list representing a big number, but I cant get the print function to work.
This is the code:
Header
class List
{
private:
struct node
{
int data;
node* next;
};
node* head;
node* temp;
node* curr;
public:
List();
void addNode(std::string digits);
void printList();
};
Constructor
List::List()
{
head = NULL;
curr = NULL;
temp = NULL;
}
Function that creates the list
void List::addNode(string digits)
{
int o = 1;
int j = 0;
int i = 0;
node *n;
node *head;
node *temp;
//=================================================================================//
n = new node;
if (digits[0]=='-')
{
n -> data = -1;
head = n;
temp = n;
}
else
{
n -> data = 1;
head = n;
temp = n;
}
//================================================================================//
if ((head->data) == -1)
{
while (o < digits.length())
{
n = new node;
n->data = stoi(digits.substr(o,1));
temp -> next = n;
temp = temp -> next;
o++;
}
}
else
{
while(i < digits.length())
{
n = new node;
n->data = stoi(digits.substr(i,1));
temp -> next = n;
temp = temp -> next;
i++;
}
}
The print function I've been trying to implement, it gives no output (blank):
void List::printList()
{
node* curr = head;
while(curr != NULL)
{
cout<<curr -> data<<" ";
curr = curr -> next;
}
}
The list prints fine when I use this code in the addNode function:
if ((head -> data) == -1)
{
while(j < digits.length())
{
cout<<head -> data<<" ";
head = head -> next;
j++;
}
}
else
{
while(j<=digits.length())
{
cout<<head -> data<<" ";
head = head -> next;
j++;
}
}
For starters these data members
node* temp;
node* curr;
are redundant. Instead of them you can use similar local variables in member functions of the class if it is required.
The function addNode deals with the local variable head instead of the data member with the same name.
void List::addNode(string digits)
{
int o = 1;
int j = 0;
int i = 0;
node *n;
node *head;
//…
Also you forgot to set the data member next of the last node to nullptr.
If the member function will be called a second time then there will be memory leaks.
Calling the standard function std::stoi for one character
n->data = stoi(digits.substr(i,1));
is inefficient.
The class can look the following way as it is shown in the demonstrative program below. You will need to add other required member functions (as for example the copy constructor or destructor) yourself.
#include <iostream>
#include <string>
class List
{
private:
struct node
{
int data;
node *next;
} *head = nullptr;
public:
List() = default;
void addNode( const std::string &digits );
std::ostream & printList( std::ostream &os = std::cout ) const;
};
void List::addNode( const std::string &digits )
{
if ( !digits.empty() &&
!( digits.size() == 1 && ( digits[0] == '-' || digits[0] == '+') ) )
{
node **current = &head;
while ( *current )
{
node *tmp = *current;
*current = ( *current )->next;
delete tmp;
}
std::string::size_type i = 0;
*current = new node { digits[i] == '-' ? -1 : 1, nullptr };
if ( digits[i] == '-' || digits[i] == '+' ) ++i;
for ( ; i < digits.size(); i++ )
{
current = &( *current )->next;
*current = new node { digits[i] - '0', nullptr };
}
}
}
std::ostream & List::printList( std::ostream &os ) const
{
if ( head != nullptr )
{
if ( head->data == -1 ) os << '-';
for ( node *current = head->next; current != nullptr; current = current->next )
{
os << current->data;
}
}
return os;
}
int main()
{
List lst;
lst.addNode( "-123456789" );
lst.printList() << '\n';
lst.addNode( "987654321" );
lst.printList() << '\n';
return 0;
}
The program output is
-123456789
987654321
I have to write this String class which is represented using linked list. I seem to have problems with my copy constructor and I have no idea how to write my assignment operator. Any idea where the mistake is and how to write them? The shown code is for the copy constructor with the following operation String s="word". I'm not sure how to write one for String s1=s2. Here is my code so far:
struct Element
{
char data;
Element* next;
};
class String
{
Element* top;
public:
String();
bool empty() const;
char last() const;
char pop();
void push(char);
friend std::ostream& operator<<(std::ostream&, const String&);
friend std::istream& operator>>(std::istream&, String&);
String(const char*);
};
String::String(const char *p)
{
int l = strlen(p);
for(int i=0; i < l+1 ; i++)
{
Element *newElement;
newElement = new Element;
newElement->data = p[i];
newElement->next = NULL;
if(top == NULL)
{
top = newElement;
}
else
{
Element *tmp = top;
while(tmp->next != NULL)
{
tmp = tmp->next;
tmp->next = newElement;
}
}
}
}
int main()
{
String s="Hello";
std::cout<<s;//operator<< works tested it
}
If you defined single-linked list when it is much better to add new elements at the head of the list instead of the tail. Nevertheless your function could look the following way
String::String(const char*p)
{
for ( ; *p; ++p )
{
Element *newElement = new Element;
newElement->data = *p;
newElement->next = NULL;
if ( top == NULL )
{
top = newElement;
}
else
{
Element *tmp = top;
while ( tmp->next != NULL ) temp = tmp->next;
tmp->next = newElement;
}
}
}
By the way it is not a copy constructor. As for the copy constructor then it could be defined as
String::String( const String &s ) : top( NULL )
{
if ( s.top )
{
top = new Element;
top->data = s.top->data;
top->next = NULL;
for ( Element *tmp1 = top, tmp2 = s.top; tmp2->next; tmp1 = tmp1->next, tmp2 = tmp2->next )
{
tmp1->next = new Element;
tmp1->next->data = tmp2->next->data;
tmp1->next->next = NULL;
}
}
}
In the following code, your while loop will never execute since the top->next will be NULL.
Element *tmp = top;
while(tmp->next != NULL)
{
...
}
Also, as #Claptrap commented, you assign newElement on every loop iteration.
Given all of this, I'm not seeing why it would fail, but it may be in code that you have not posted. Please try to reduce your code to the minimum necessary that reproduces the problem and then include that code in your post.
This was a 2 part problem, implementing a Trie and a Hash->linked lists
the files contain words for a to z in column format... basically searching for words in the input file from an output file.
The trouble we are having is printing the hash value associated at each memory location in out table.
Words are sorted based on their ACII value sum.
abc and bcd will be placed into same bucket/or created hash value.
ignore the commented code as we have been using/saving most of everything we type and find in out textbook.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
const int N = 111;
//int HashNode *table[N];
//======================================//
// CLASS DEFINITIONS //
//======================================//
// Node class
class Node {
public:
Node(string lab) { mContent = lab[0]; mMarker = false; mLabel = lab; }
~Node() {}
string mLabel;
char mContent;
bool mMarker;
vector<Node*> mChildren;
Node *rightsibling;
Node *firstchild;
char content() { return mContent; }
void setContent(char c) { mContent = c; }
bool wordMarker() { return mMarker; }
void setWordMarker() { mMarker = true; }
vector<Node*> children() { return mChildren; }
Node* findChild(char c);
void appendChild(Node* child) { mChildren.push_back(child); }
};
// Trie class
class Trie {
private:
Node* root;
public:
Trie();
~Trie();
void insert(string s);
bool search(string s);
bool search2(string s);
};
// Hash class
class HashNode{
private:
int tableSize;
Node *parent; //pointer to parent node
char c; //next character of word being hashed
Node *child; //pointer to child node
HashNode *next; //pointer to next node in LL Hash
HashNode(Node *p,char c,Node *q);
public:
HashNode();
void HashInsert(Node *p, char c, Node *q);
int calc_hash(Node *p, char c);
void preorder( Node *p);
Node *findChild2(Node *parent, char c);
};
HashNode *table[N]; //global hashtable array
//======================================//
// METHOD DEFINITIONS //
//======================================//
// FindChild Method
Node* Node::findChild(char c)
{
for ( int i = 0; i < mChildren.size(); i++ )
{
Node* tmp = mChildren.at(i);
if ( tmp->content() == c )
{
return tmp;
}
}
return NULL;
}
// Trie Constructor
Trie::Trie()
{
root = new Node(" ");
}
// Trie Destructor
Trie::~Trie()
{
// Free memory
}
// Insert Method
void Trie::insert(string s)
{
Node* current = root;
if ( s.length() == 0 )
{
current->setWordMarker(); // an empty word
return;
}
for ( int i = 0; i < s.length(); i++ )
{
Node* child = current->findChild(s[i]);
if ( child != NULL )
{
current = child;
int j=0;
string s1, s2, s3;
Node *p, *q;
while((j < current->mLabel.length()) && (current->mLabel[j] == s[i])){j++;i++;}
if ((j<current->mLabel.length())) {
//split current
s1=current->mLabel.substr(0,j-1);
s2=current->mLabel.substr(j,current->mLabel.length()-1);
s3=s.substr(i,s.length()-1); //if i = s.length then ...s3 should be empty string
p=new Node(s3);
p->setWordMarker();
q=new Node(s2);
q->firstchild = current->firstchild;
current->mLabel = s1;
if(s3 < s2){
p->rightsibling=q;
q->rightsibling = NULL;
current->firstchild = p;
}
else {
q->rightsibling=p;
p->rightsibling = NULL;
current->firstchild = q;
}
}
}
else
{
Node* tmp = new Node(" ");
tmp->setContent(s[i]);
current->appendChild(tmp);
current = tmp;
}
if ( i == s.length() - 1 )
current->setWordMarker();
}
}
// Search Method1
bool Trie::search(string s)
{
Node* current = root;
while ( current != NULL )
{
for ( int i = 0; i < s.length(); i++ )
{
Node* tmp = current->findChild(s[i]);
if ( tmp == NULL )
return false;
current = tmp;
}
if ( current->wordMarker() )
return true;
else
return false;
}
return false;
}
// SEARCH METHOD 2
bool Trie::search2(string s)
{
Node* current = root;
while ( current != NULL )
{
for ( int i = 0; i < s.length(); i++ )
{
Node* tmp = current->findChild(s[i]);
if ( tmp == NULL )
return false;
current = tmp;
}
if ( current->wordMarker() )
return true;
else
return false;
}
return false;
}
// Hash Constructor
HashNode::HashNode(Node *p,char c,Node *q){
tableSize = N;
parent =p;
c = c;
child = q;
}
int HashNode::calc_hash(Node *p, char c){
int a = N/3;
int i = *((int*)(&p)); //int i = (int)p;
int j = (int)c;
int h = (a*i + j) % N;
return h;
}
void HashNode::HashInsert(Node *p, char c, Node *q){
int h = calc_hash(p,c);
HashNode *x = table[h];
HashNode *y = new HashNode(p,c,q);
if (x==NULL)
table[h]=y;
while (x->next != NULL)
x = x->next;
x->next = y;
//y->next = x;
//table[h] = y;
}
void HashNode::preorder( Node *p) {
if (p==NULL) return;
Node *q = p->firstchild;
while (q != NULL){
HashInsert(p,q->mContent, q);
preorder(q);
q = q->rightsibling;
}
}
Node *HashNode::findChild2(Node *parent, char c){
int h = calc_hash(parent, c);
HashNode *p = table[h];
while (p != NULL){
if (p->parent == parent && p->c == c){
return p->child;
}
p = p->next;
}
}
//======================================//
// MAIN //
//======================================//
int main()
{
Trie* trie = new Trie();
HashNode hashObj;
//HashEntryNode Hashtable[N];
ifstream infile;
infile.open("testdata.txt");
if (!infile)
cout<<"Input file cannot be openned!"<<endl;
cout<<"---------------------------------"<<endl;
cout<<"List of words inserted into Trie:"<<endl;
cout<<"---------------------------------"<<endl;
cout<<endl;
string wordLine;
while (!infile.eof()){
infile >> wordLine;
trie->insert(wordLine);
cout<<wordLine<<endl;
}
cout<<endl;
cout<<"---------------------------------"<<endl;
cout<<" End of List "<<endl;
cout<<"---------------------------------"<<endl<<endl;
ifstream searchFile;
searchFile.open("searchdata.txt");
if(!searchFile)
cout<<"Search file cannot be openned!"<<endl;
string searchLine;
while (!searchFile.eof()){
searchFile >> searchLine;
if ( trie->search(searchLine) )
cout << searchLine <<" => FOUND!" << endl;
else
cout << searchLine <<" => NOT FOUND." <<endl;
int h;
char p;
// h = hashObj.calc_hash(searchLine);
cout << "hash value is "<< h << endl;
//int index;
//index = hashObj.hashFunction(searchLine);
//cout << "Hash value = " << index <<endl<<endl;
//Hashtable[index] =
}
delete trie;
return 0;
}
I am having problems trying to turn the INSERT function into a function where it sorts the nodes alphabetically. I have written down what I've tried so far...but it only checks the name of the first node to see if it is bigger than the given name of the new node in the function's argument. Can someone please give me an idea of how I would be able to move through each node and be able to compare their keys (names) and place them left and right accordingly? Below is what I have in my code and my INSERT function so far...
// UnSortedLnkList.h
//----------------------------
#include <iostream>
#include <afxwin.h>
using namespace std;
#define new DEBUG_NEW
struct Node {
string m_name; // key
int m_age;
Node* m_next;
Node(const string& name, int age, Node* next = NULL);
};
ostream& operator<< (ostream&, const Node&);
class ULnkList {
friend ostream& operator<< (ostream&, const ULnkList&); // 1.5
public:
ULnkList();
// copy ctor
ULnkList(const ULnkList& existingList ); // 5
~ULnkList(); // 4
bool IsEmpty() const;
int Size() const;
bool Insert(const string& name, int age); // 1
bool Delete(const string& name); // 3
bool Lookup(const string& name, int& age) const; // 2
ULnkList& operator =(const ULnkList& list2); // 6
bool Delete2(const string& name);
private:
Node* m_head; // points to head of the list
int m_num; // the number of entries in the list
// helper functions:
void Clear(); // 7
void Copy(const ULnkList& list2); // 8
};
// UnSortedLnkList.cpp
//----------------------------
#include "UnSortedLnkList.h"
#include <iostream>
#include <string>
using namespace std;
Node::Node(const string& name, int age, Node* next)
: m_name(name), m_age(age), m_next(next)
{}
ostream& operator<< (ostream& os, const Node& n) // cout << n;
{
os << "Name: " << n.m_name << "\tAge: " << n.m_age;
return os;
}
ULnkList::ULnkList()
: m_head(new Node("",-99,NULL)), m_num(0)
{
//m_head = new Node("",-99,NULL);
}
//
ULnkList::ULnkList(const ULnkList& existingList )
{
Copy(existingList);
}
void ULnkList::Copy(const ULnkList& existingList)
{
m_num = existingList.m_num;
// create dummy node
m_head = new Node("",-99,NULL);
// traverse existing list
Node *pe = existingList.m_head->m_next;
Node *pThis = m_head;
while( pe != 0)
{
// create a copy of the Node in OUR list
pThis->m_next = new Node(pe->m_name,pe->m_age,0);
// update pointers
pe = pe->m_next;
pThis = pThis->m_next;
}
}
void ULnkList::Clear()
{
Node *p = m_head->m_next;
Node *tp = m_head; // trail pointer
while( p != 0)
{
delete tp;
// update pointers
tp = p; //
p = p->m_next;
}
delete tp;
}
ULnkList& ULnkList::operator =(const ULnkList& list2) // list1 = list2;
{
// list1 = list1; // check for self-assignment
if( this != &list2 )
{
this->Clear(); // normally Clear();
this->Copy(list2);
}
// l1 = l2 = l3;
return *this;
}
bool ULnkList::IsEmpty() const
{
return m_num == 0;
// return m_head->m_next == NULL;
}
int ULnkList::Size() const
{
return m_num;
}
//
ULnkList::Insert(const string& name, int age)
{
Node *current = m_head->m_next;
Node *previous = m_head;
if (m_head->m_next == NULL)
{
m_head->m_next = new Node(name,age,m_head->m_next);
m_num++;
return true;
}
if (name < m_head->m_next->m_name)
{
m_head->m_next = new Node(name,age,m_head->m_next);
m_num++;
return true;
}
return true;
}
//
ostream& operator<< (ostream& os, const ULnkList& list) // cout << list;
{
Node *p = list.m_head->m_next; // first node with data
while( p != 0 )
{
cout << *p << endl; // ????
// update p
p = p->m_next;
}
cout << "--------------------------------------" << endl;
return os;
}
// input: name
//// output: age if found
bool ULnkList::Lookup(const string& name, int& age) const
{
// linear search
Node *p = m_head->m_next;
while( p != 0)
{
if( name == p->m_name )
{
// found it
age = p->m_age;
return true;
}
// update p
p = p->m_next;
}
return false;
}
//
bool ULnkList::Delete(const string& name)
{
Node *p = m_head->m_next;
Node *tp = m_head; // trail pointer
while( p != 0)
{
if( name == p->m_name )
{
// found it, so now remove it
// fix links
tp->m_next = p->m_next;
// delete the node
delete p;
return true;
}
// update pointers
tp = p; // tp = tp->m_next;
p = p->m_next;
}
return false;
}
bool ULnkList::Delete2(const string& name)
{
Node *p = m_head;
while( p->m_next != 0 ) // ?????
{
if( p->m_next->m_name == name )
{
Node *save = p->m_next;
// remove the node
// fix links
p->m_next = p->m_next->m_next;
// delete memory
delete save;
return true;
}
// update pointers
p = p->m_next;
}
return false;
}
//
ULnkList::~ULnkList()
{
Clear();
}
//
I have a word of caution for this code
if(name > m_head->m_name ){
while(name > current->m_next->m_name){
current = current->m_next;
}
// add temp = current->next
current->m_next = new Node(name,age)
// current->next->next = temp
You don't want to lose the list after where you insert.
I'm guessing this is homework, so I'm not going to write the code. I would suggest that your Insert() function could walk the list from the head until it gets to the 'right' spot, by comparing the input string, and then doing the insert logic. That is assuming that you have to use a literal list as your data structure. If you want better insert performance on average, you could use a binary tree as your underlying structure, but that would make list traversal more complex.
Your problem lies in this code:
if (name < m_head->m_next->m_name)
{
m_head->m_next = new Node(name,age,m_head->m_next);
m_num++;
return true;
}
In order to insert in a sorted manner, I would probably some sort of helper function with a recursive function call.
but this might work:
Node *current = m_head;
if(name > m_head->m_name ){
while(name > current->m_next->m_name){
current = current->m_next;
}
current->m_next = new Node(name,age,current->m_next);
}
else{
m_head = new Node(name,age,m_head);
}
This will insert in an ascendingly sorted manner.
I haven't tested it, but let me know if it works! hope this helps!