bool CharacterList::addCharacter(Character *newCharacter)
{
Character *temp, *back;
if(head == NULL)
{
head = newCharacter;
}
else
{
temp = head;
back = NULL;
while((temp != NULL) && (temp < newCharacter))
{
back = temp;
temp = temp.next;
}
if(back == NULL)
{
newCharacter.next = head;
head = newCharacter;
}
else
{
back.next = newCharacter;
newCharacter.next = temp;
}
return true;
}
}
I'm creating an ordered linked list(CharacterList) for the objects of class Character. This function will take only one argument, a pointer to a Character class object(*newCharacter). It will then add this character to the linked list of character objects. I'm not sure if this is how I insert an object to the linked list. can someone guide me please ?
Instead of reinventing your own, you should use std::list, as follows:
std::list<Character> CharacterList;
But please read a good book before going any further.
Related
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
Full disclosure: This is a project for my class, but I'm not here to ask you to do my homework for me. I'm looking for a little direction as to what I seem to be missing.
The assignment: From a file of formatted data (see below). You are to create 3 doubly linked lists. (so one set of data with three "chains" that orders the data numerically) If you come across an piece of data with the same timestamp as a previous piece of data, that data is considered to be unreliable and needs to be deleted from the doubly linked list.
The Problem: I have four linked list heads, timeHead, tempHead, and windHead are for the data being read in from the file. The last is duplHead (duplicateHead) is for a list of duplicates. My issue is that whenever I try to delete a particular node from my linked list. I cant seem to do it correctly. I either crash the program or the doubly linked list falls apart.
Here is my code: I feel my main problem is either not creating the list correctly OR not deleting the problem nodes correctly.
The int main function only calls two functions addData and print report. I have included what I felt was relevant.
//ADD TO LINKED LIST
void linkedlist::addToLinkedList(weatherdata *newNode){
int doubleMarker = 0;
weatherdata *newNodeCopy;
weatherdata *currentNode;
weatherdata *nextNode;
newNodeCopy = new weatherdata; // <-- NEW
newNodeCopy = newNode;
/*_____ lINKED lIST FOR TIMESTAMP _____*/
//checks the duplicate list so as not to add a deleted triple
if (isItInDuplicateList(newNode) == 1){
doubleMarker = 1;
}
//if something exists in the list do this: traverse the list, check for duplicates.
if ((timeHead != nullptr) && (doubleMarker != 1)){
currentNode = timeHead;
while (currentNode != nullptr){
//if its the same as another item DELETE
if (newNode->time == currentNode->time) {
addToDuplicateList(newNode);
deleteNodeFromList(newNode);
doubleMarker = 1; // <-- this double marker will ensure that the function doesnt add a duplicate item
break;
}
currentNode = currentNode->timeN;
}
}
//if the incoming number is not a duplicate of something we already have on our list we add it
if (doubleMarker != 1){
//very first item on list
if (timeHead == nullptr){
timeHead = newNodeCopy;
}
//first position on list
else if (newNode->time < timeHead->time){
nextNode = timeHead;
timeHead = newNodeCopy;
newNodeCopy->timeN = nextNode;
nextNode->timeP = newNodeCopy;
}
//either between 2 entries or at the end of the list
else {
//traverse the list and find the appropriate placement for the newNode
currentNode = timeHead;
nextNode = timeHead->timeN;
//while "not yet at the end of the list"
while (nextNode != nullptr){
//newNode belongs somewhere in between two other entries
if ((currentNode->time < newNode->time) && (newNode->time < nextNode->time)){
currentNode->timeN = newNodeCopy;
newNodeCopy->timeP = currentNode;
newNodeCopy->timeN = nextNode;
nextNode->timeP = newNodeCopy;
break;
}
//otherwise increment currentNode and nextNode and compare again
else {
currentNode = nextNode;
nextNode = nextNode->timeN;
}
}
//newNode goes at the end of the linked List
if (nextNode == nullptr){
currentNode->timeN = newNodeCopy;
newNodeCopy->timeP = currentNode;
}
}
}
/*_____ lINKED lIST FOR TEMPERATURE _____*/
//if the incoming number is not a duplicate of something we already have on our list we add it
if (doubleMarker != 1){
//very first item on list
if (tempHead == nullptr){
tempHead = newNodeCopy;
}
//first position on list
else if (newNode->temp < tempHead->temp){
nextNode = tempHead;
tempHead = newNodeCopy;
newNodeCopy->tempN = nextNode;
nextNode->tempP = newNodeCopy;
}
//either between 2 entries or at the end of the list
else {
//traverse the list and find the appropriate placement for the newNode
currentNode = tempHead;
nextNode = tempHead->tempN;
//while "not yet at the end of the list"
while (nextNode != nullptr){
//newNode belongs somewhere in between two other entries
if ((currentNode->temp <= newNode->temp) && (newNode->temp <= nextNode->temp)){
currentNode->tempN = newNodeCopy;
newNodeCopy->tempN = nextNode;
nextNode->tempP = newNodeCopy;
break;
}
//otherwise increment currentNode and nextNode and compare again
else {
currentNode = nextNode;
nextNode = nextNode->tempN;
}
}
//newNode goes at the end of the linked List
if (nextNode == nullptr){
currentNode->tempN = newNodeCopy;
newNodeCopy->tempP = currentNode;
}
}
}
/*_____ lINKED lIST FOR WINDSPEED _____*/
//if the incoming number is not a duplicate of something we already have on our list we add it
if (doubleMarker != 1){
//very first item on list
if (windHead == nullptr){
windHead = newNodeCopy;
}
//first position on list
else if (newNode->wind < windHead->wind){
nextNode = windHead;
windHead = newNodeCopy;
newNodeCopy->windN = nextNode;
nextNode->windP = newNodeCopy;
}
//either between 2 entries or at the end of the list
else {
//traverse the list and find the appropriate placement for the newNode
currentNode = windHead;
nextNode = windHead->windN;
//while "not yet at the end of the list"
while (nextNode != nullptr){
//newNode belongs somewhere in between two other entries
if ((currentNode->wind <= newNode->wind) && (newNode->wind <= nextNode->wind)){
currentNode->windN = newNodeCopy;
newNodeCopy->windN = nextNode;
nextNode->windP = newNodeCopy;
break;
}
//otherwise increment currentNode and nextNode and compare again
else {
currentNode = nextNode;
nextNode = nextNode->windN;
}
}
//newNode goes at the end of the linked List
if (nextNode == nullptr){
currentNode->windN = newNodeCopy;
newNodeCopy->windP = currentNode;
}
}
}
}
//ADD TO DUPLICATE LIST
void linkedlist::addToDuplicateList(weatherdata *duplicateNode){
weatherdata *currentNode;
weatherdata *nextNode;
weatherdata *addDuplicateNode;
addDuplicateNode = new weatherdata; // <-- NEW
//make a complete copy for the duplicate list (since were going to delete that node)
addDuplicateNode->time = duplicateNode->time;
addDuplicateNode->temp = duplicateNode->temp;
addDuplicateNode->wind = duplicateNode->wind;
addDuplicateNode->timeN = duplicateNode->timeN;
addDuplicateNode->timeP = duplicateNode->timeP;
addDuplicateNode->tempN = duplicateNode->tempN;
addDuplicateNode->tempP = duplicateNode->tempP;
addDuplicateNode->windN = duplicateNode->windN;
addDuplicateNode->windP = duplicateNode->windP;
addDuplicateNode->duplN = duplicateNode->duplN;
if (duplHead == nullptr){
duplHead = addDuplicateNode;
}
else {
currentNode = duplHead;
nextNode = duplHead->duplN;
while (nextNode != nullptr){
currentNode = nextNode;
nextNode = nextNode->duplN;
}
currentNode->duplN = addDuplicateNode;
}
}
/DELETE FROM LINKEDLIST
void linkedlist::deleteNodeFromList(weatherdata *toBeDeletedNode){
weatherdata *currentNode;
weatherdata *nextNode;
currentNode = timeHead;
nextNode = timeHead->timeN;
while (nextNode != nullptr){
if (nextNode->time == toBeDeletedNode->time){
currentNode->timeN = nextNode->timeN;
//currentNode->tempN = nextNode->tempN;
//cout << ".";
delete toBeDeletedNode;
toBeDeletedNode = nullptr;
break;
}
currentNode = nextNode;
nextNode = nextNode->timeN;
}
}
//DUPLICATE LIST CHECK
bool linkedlist::isItInDuplicateList(weatherdata *checkThisNode){
bool found = false;
weatherdata *currentNode;
currentNode = duplHead;
if (duplHead == nullptr){
found = false;
}
else {
do {
if (currentNode->time == checkThisNode->time) {
found = true;
break;
}
currentNode = currentNode->duplN;
} while (currentNode != nullptr);
}
return found;
}
So either the first (long) function linkedlist addToLinkedList();
or the last (short) function linkedlist deleteNodeFromList();
If you need me to post anymore code please let me know and I'll so so.
Again, I feel like I'm either not making the doubly linked list correctly or not deleting it right.
Thanks again!
First take a look at these lines:
newNodeCopy = new weatherdata; // <-- NEW
newNodeCopy = newNode;
In the first line you create a new object of type weatherdata and saves a pointer to the new object in newNodeCopy.
In the second line you overwrite the value of newNodeCopy with the value of newNode which means you have lost the pointer to the new object (i.e. you have a memory leak).
If you want to copy the values from the object that newNode points to into the newly created object, you need to do:
*newNodeCopy = *newNode;
In general I'll recommend that you split the function into three smaller functions (i.e. one for each list). Smaller functions are easier to understand and debug.
Also I noticed this part:
if (isItInDuplicateList(newNode) == 1){
doubleMarker = 1;
}
In all the remaining code in the function you do:
if (doubleMarker != 1){
.....
}
In other words - once doubleMarker is set to 1, you don't execute more code. Therefore you can simplify your code by returning right away. Like:
if (isItInDuplicateList(newNode) == 1){
return;
}
Then you can remove all the if (doubleMarker != 1){ and your code gets more simple to read, understand and debug.
The delete function
Your void linkedlist::deleteNodeFromList(weatherdata *toBeDeletedNode) have some serious problems - consider this:
1) What will happen if timeHead is nullptr ?
2) Where do you check if timeHead->time == toBeDeletedNode->time ?
3) Where do you update the timeP pointer ?
The answers are:
1) Program crash
2) Never - so you can't delete the head element.
3) Never - so your list is broken! You need to add code that updates the "previous" pointer
I was trying to write a code to reverse the linked list but getting wrong output.
Is there something I am missing.
Here is the function
void reverselinklist( struct node **headreverse)
{
struct node *p = *headreverse;
if(p->next == NULL)
{
*headreverse = p;
return;
}
reverselinklist(&(p->next));
p->next->next = p;
p->next = NULL;
}
After display function
Input 409765
Output 4
*headreverse = p is meaningless. You should set *headreverse = p->next each time to move forward, until the last node is reached.
Anyway, I changed your code to make it work:
void reverselinklist(struct node **headreverse)
{
struct node *p = *headreverse;
if(p->next == NULL){
return;
}
*headreverse = p->next;
reverselinklist(headreverse);
p->next->next = p;
p->next = NULL;
}
For single list use two two pointers, to update list as you can not go back.
Here is my code. Hope it will help you to understand concept.
void reverselinklist(struct node** head_ref)
{
struct node* first;
struct node* rest;
first = *head_ref;
rest = first->next;
if (rest == NULL)
return;
reverselinklist(&rest);
first->next->next = first;
first->next = NULL;
*head_ref = rest;
}
If it could me more precise please provide suggestions.
Your headreverse is not being assigned to the new head of the list. Be sure to use 2 arguments for your function, 1) head of the initial list 2) current node(same as your headreverse)
if(p->next == NULL)
{
*head = p; //instead of headreverse use head
return;
}
I'm trying to find a way of deleting a linked list without recursion, because a stack overflow isn't really something nice.
I have a struct as follows:
typedef struct _my_Item
{
_my_Item(const std::string& name)
{
m_name = name;
}
~my_Item()
{
delete next; // this recursively deletes the "tail" of the list
next = NULL;
}
struct _my_Item *next;
std::string m_name;
// ... More members here...
}
In some piece of code (not relevant here) I'm constructing a list from a data file using the above structure. I keep the pointer to the head of the list in a variable and can work with it. All fine.
When I finally call the destructor on the head of the list, the destructor gets called and the delete next; causes a recursion to delete the "tail" of the list (which is the entire list without the first element). Now since the list is quite long, I see a stack overflow sometimes.
Is there a nice way to get around this problem?
~my_Item()
{
while (next)
{
_my_Item* item = next;
next = item->next;
item->next = NULL; // this prevents the recursion
delete item;
}
}
Create a class representing the list itself that will encapsulate nodes deletion in its destructor via a for/while loop. Doing it the way you do leaves the possibility to delete part of the list and leave dangling pointer.
One suggestion would be to remove the delete code from the destructor and use a pointer to delete the list.
struct _my_Item * nodeToDelete = NULL;
while(firstNode != NULL)
{
nodeToDelete = firstNode;
firstNode = firstNode->next;
delete nodeToDelete;
}
// I wrote this java code to delete a node from BST
// I only used one recursion call to remove successor
public Boolean delete(int data){
if(isEmpty() || !search(data))
return false;
return delete(null,root,data);
}
public Boolean delete(Node parent,Node temp,int data) {
while(true){
if(data == temp.getData()) {
break;
} else if(data < temp.getData()) {
parent = temp;
temp = temp.getLeft();
} else {
parent = temp;
temp = temp.getRight();
}
}
if(parent == null && (temp.getLeft() == null || temp.getRight() == null)){
if(temp.getLeft() == null)
root = temp.getRight();
else
root = temp.getLeft();
} else if(temp.getLeft() == null || temp.getRight() == null) {
if (parent.getLeft() == temp) {
if (temp.getLeft() == null)
parent.setLeft(temp.getRight());
else
parent.setLeft(temp.getLeft());
} else if (parent.getRight() == temp) {
if (temp.getLeft() == null)
parent.setRight(temp.getRight());
else
parent.setRight(temp.getLeft());
}
}else{
int min = findMin(temp.getRight());
temp.setData(min);
delete(temp,temp.getRight(),min);
}
return true;
}
I'm new to C++ and I'm trying to write an algorithm to search a linked list, but I'm having a little trouble with my logic. The ??? question marks in bold are the parts I'm having trouble with. I appreciate any help with this.
ListNode *MyLinkedList::Search(int key)
{
ListNode *temp = head; // Assume ListNode is a structure and contains the variable int key;
// Search for the key
while((temp != NULL) && (key != temp->key))
{
temp = temp -> next; // Advance to next node
{
if(**???**) // Make sure node is found
{
return **???**; // If found, return appropriate value
}
else
{
return NULL; // return NULL when not found
}
}
If the key was found key == temp->key will be true and temp != NULL will be false, so:
if(key == temp->key) // Make sure node is found
{
return temp; // If found, return appropriate value
}
OR:
if (temp != NULL) // Make sure node is found
{
return temp; // If found, return appropriate value
}
Try this code:
ListNode *MyLinkedList::Search(int key, ListNode *head)
{
ListNode *temp = head; // Assume ListNode is a structure and contains the variable int key;
// Search for the key
while(temp != NULL)
{
if (key == temp->key)
return temp;
temp = temp -> next; // Advance to next node
}
return NULL; // return NULL when not found
}
EDIT
You should use the list from stl and the find algorithm, if you aren't required to write your own container; They are tested and safe:
http://en.cppreference.com/w/cpp/container/list
http://en.cppreference.com/w/cpp/algorithm/find
You don't need an if. Just return temp. If the correct key is present in the list, temp would be pointing to it, otherwise it's NULL.
This will work for you
if(temp != NULL) // Make sure node is found
{
return temp; // Make sure node is found
}
You could do this:
if(temp != NULL) // Make sure node is found
{
return temp; // If found, return appropriate value
}
But much simpler is just
return temp;
since if temp is null, you want to return null anyway.
Given a Binary tree , how can we find the sum of each vertical level efficiently using doubly linked list ..
Yes , i know we can find it using hash table ... But How using doubly linked list
please explain with code and example !!
Thanks in advance
This begs the question, "homework?"
node { sum = 0; node *next=NULL; node *prev=NULL; }
allocate node root_node
dfs(root,root_node){
root_node.sum++
if (leftchild) // check whether the child exists in tree
if (!left_node) // check for left child in linked list
allocate node left_node
dfs(leftchild,left_node)
if (rightchild) // check whether the child exists in tree
if (!right_node) // check for right child in linked list
allocate node right_node
dfs(rightchild,right_node)
}
PS: I refrain from answering the problem in full(i.e. with example) because I think with high possibility this is a homework problem.
Here is the Java Implementation
public static Collection<Integer> verticalSumUsingDLL(BinaryTreeNode<Integer> node) {
if (node == null) {
return Collections.emptyList();
}
LinearNode<Integer> head = new LinearNode<Integer>(node.getData());
verticalSumUsingDLL(head, node);
List<Integer> result = new ArrayList<Integer>();
while(head.prev != null) {
head = head.prev;
}
while (head != null) {
result.add(head.data);
head = head.next;
}
return result;
}
private static void verticalSumUsingDLL(LinearNode<Integer> dll, BinaryTreeNode<Integer> node) {
if (node == null) {
return ;
}
if (node.hasLeftChild()) {
if (dll.prev == null) {
LinearNode<Integer> temp = new LinearNode<Integer>(node.getLeft().getData());
dll.prev = temp;
temp.next = dll;
} else {
dll.prev.data = dll.prev.data + node.getLeft().getData();
}
verticalSumUsingDLL(dll.prev, node.getLeft());
}
if (node.hasRightChild()) {
if (dll.next == null) {
LinearNode<Integer> temp = new LinearNode<Integer>(node.getRight().getData());
dll.next = temp;
temp.prev = dll;
} else {
dll.next.data = dll.next.data + node.getRight().getData();
}
verticalSumUsingDLL(dll.next, node.getRight());
}
}
Here is the unit test case
#Test
public void verticalSumUsingDLLOfBinaryTreeTest() {
BinaryTreeNode<Integer> node = BinaryTreeUtil.<Integer>fromInAndPostOrder(new Integer[]{4,2,5,1,6,3,7}, new Integer[]{4,5,2,6,7,3,1});
Collection<Integer> verticalSum = BinaryTreeUtil.verticalSumUsingDLL(node);
assertThat(verticalSum.toArray(new Integer[0]), equalTo(new Integer[]{4,2,12,3,7}));
}