I have implemented deque through linked list.
Below You can see my code:
#include <iostream>
using namespace std;
struct Node
{
int mData;
Node* pPrev, *pNext;
Node()
{
this->mData = mData;
pPrev = pNext = NULL;
}
Node(int value)
{
mData = value;
pPrev = pNext = NULL;
}
};
class Deque
{
private:
Node *pFront, *pRear;
int mSize;
public:
Deque()
{
pFront = pRear = NULL;
mSize = 0;
}
void pushFront(int data)
{
Node* newNode = new Node(data);
if (newNode == NULL)
{
cout << "Error";
}
else
{
if (pFront == NULL)
{
pRear = pFront = newNode;
}
else
{
newNode->pNext = pFront;
pFront->pPrev = newNode;
pFront = newNode;
}
mSize++;
}
}
void pushLast(int data)
{
Node* newNode = new Node(data);
if (newNode == NULL)
{
cout << "Error";
}
else
{
if (pRear == NULL)
{
pFront = pRear = newNode;
}
else
{
newNode->pPrev = pRear;
pRear->pNext = newNode;
pRear = newNode;
}
mSize++;
}
}
void deleteFront()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
Node* temp = pFront;
pFront = pFront->pNext;
if (pFront == NULL)
{
pRear = NULL;
}
else
{
pFront->pPrev = NULL;
}
free(temp);
mSize--;
}
}
void deleteLast()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
Node* temp = pRear;
pRear = pRear->pPrev;
if (pRear == NULL)
{
pFront = NULL;
}
else
{
pRear->pNext = NULL;
}
free(temp);
mSize--;
}
}
int getFront()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
return pFront->mData;
}
}
int getLast()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
return pRear->mData;
}
}
void swap()
{
if (isEmpty())
{
cout << "Deque is empty";
}
else
{
Node* temp = pFront;
while (temp->pNext != NULL) {
temp = temp->pNext;
}
Node* tmp2 = new Node();
tmp2->mData = temp->mData;
temp->mData = pFront->mData;
temp->pNext = NULL;
pFront->mData = tmp2->mData;
}
}
bool isEmpty()
{
return (mSize == 0);
}
int getSize()
{
return mSize;
}
void reverse()
{
auto curr = pFront; // current pointer
Node* prev = NULL; // previous pointer
while (curr) {
auto temp = curr->pNext;
curr->pNext = prev;
prev = curr;
pFront = prev;
curr = temp;
}
}
bool isBelong(int data)
{
Node* temp = pFront;
while (temp != NULL)
{
if (data == temp->mData)
{
return true;
}
temp = temp->pNext;
}
return false;
}
void clear()
{
pRear = NULL;
while (pFront != NULL)
{
Node* temp = pFront;
pFront = pFront->pNext;
delete temp;
}
pFront = NULL;
mSize = 0;
}
void show()
{
Node* node = pFront;
while (node != NULL)
{
cout << node->mData << " ";
node = node->pNext;
}
}
};
int main()
{
Deque deque; int num;
while (true)
{
int choice;
cout << "\n0.Exit.\n1.Insertion(head).\n2.Insertion(rear).\n3.Deletion(head).\n4.Deletion(rear).\n5.Get head.\n6.Get rear.\n7.Check emptyness.\n8.Check size.\n9.Clear deque.\n10.Swap front and rear.\n11.Check belonginess.\n12.Reverse deque.\n";
cin >> choice;
switch (choice)
{
case 0: return 0;
case 1:
cout << "Insertion to head - input value : "; cin >> num;
deque.pushFront(num);
deque.show();
system("pause");
system("cls");
break;
case 2:
cout << "Insertion to rear - input value : "; cin >> num;
deque.pushLast(num);
deque.show();
system("pause");
system("cls");
break;
case 3:
deque.deleteFront();
deque.show();
system("pause");
system("cls");
break;
case 4:
deque.deleteLast();
deque.show();
system("pause");
system("cls");
break;
case 5:
if (deque.isEmpty())
{
cout << "Deque is empty";
}
else
{
cout << "First element of deque : " << deque.getFront();
}
system("pause");
system("cls");
break;
case 6:
if (deque.isEmpty())
{
cout << "Deque is empty";
}
else
{
cout << "Last element of deque : " << deque.getLast();
}
system("pause");
system("cls");
break;
case 7:
if (deque.isEmpty())
{
cout << "Deque is empty";
}
else
{
cout << "Deque is not empty: "; deque.show();
}
system("pause");
system("cls");
break;
case 8:
cout << "Size of deque : " << deque.getSize();
system("pause");
system("cls");
break;
case 9:
deque.clear();
system("pause");
system("cls");
break;
case 10:
cout << "Deque before swap: "; deque.show(); cout << endl;
deque.swap();
cout << "Deque after swap: "; deque.show(); cout << endl;
system("pause");
system("cls");
break;
case 11:
cout << "Input number : "; int number; cin >> number;
if (deque.isBelong(number))
{
cout << number << " belongs.\n";
}
else
{
cout << number << " does not belong.\n";
}
system("pause");
system("cls");
break;
case 12:
cout << "Deque before reverse: "; deque.show(); cout << endl;
cout << "Deque after reverse: "; deque.reverse(); deque.show(); cout << endl;
system("pause");
system("cls");
break;
default:
cout << "There is no " << choice << " choice!" << endl;
system("pause");
system("cls");
break;
}
}
}
However, reverse() method works inappropriate way.
Testing code I noticed that several methods working inappropriate way after reversing:
getRear() - returns old value;
deleteLast() - crashes.
Reverse() method based totally on same method in linked list implementation,as swap(), although it works with some problems.
I have not looked through all your code though I am sure it has some bugs as for example in the default constructor of the class Node
Node()
{
this->mData = mData;
pPrev = pNext = NULL;
}
where uninitialized data member mData is assigned to itself.
Or if you are using the operator new then you should use the operator delete instead of the standard C function free as you are doing
free(temp);
Or another example. Your method reverse does not change the pointer pRear. Or the data member pPrev also is not changed for the pointer curr.
Or the method swap has a memory leak.
And so on.
I will show how the method Reverse can be implemented.
In fact what you need is to swap data members pPrev and pNext for each node of the list.
Here is a demonstration program. I have made some changes for your classes to simplify the implementation of the demonstration program. For example I have made the class Node an internal class of the class Deque (you should also do that.). In any case you can use the idea that is realized in the method Reverse in your own implementation of the method.
#include <iostream>
#include <utility>
class Deque
{
private:
struct Node
{
int mData;
Node *pPrev, *pNext;
} *pFront = nullptr, *pRear = nullptr;
int mSize = 0;
public:
void Push( int data )
{
Node *newNode = new Node{ data, pRear, nullptr };
if (pFront == nullptr)
{
pFront = newNode;
}
else
{
pRear->pNext = newNode;
}
pRear = newNode;
++mSize;
}
Deque & Reverse()
{
if (pFront && pFront->pNext)
{
std::swap( pFront, pRear );
for (Node *current = pFront; current; current = current->pNext)
{
std::swap( current->pPrev, current->pNext );
}
}
return *this;
}
std::ostream &Show( std::ostream &os = std::cout ) const
{
os << mSize << ": ";
for (Node *current = pFront; current; current = current->pNext)
{
os << current->mData << " -> ";
}
return os << "null";
}
std::ostream &ShowReversed( std::ostream &os = std::cout ) const
{
os << mSize << ": ";
for (Node *current = pRear; current; current = current->pPrev)
{
os << current->mData << " -> ";
}
return os << "null";
}
};
int main( void )
{
Deque deque;
const int N = 10;
for (int i = 0; i < N; i++)
{
deque.Push( i );
}
deque.Show() << '\n';
deque.ShowReversed() << '\n';
std::cout << '\n';
deque.Reverse();
deque.Show() << '\n';
deque.ShowReversed() << '\n';
std::cout << '\n';
}
The program output is
10: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
10: 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null
10: 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> null
10: 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null
Related
When I run my program, everything works as expected until the destructor of the LList class. On the line that says delete current;, I get the following error:
BlankConsoleLab.exe has triggered a breakpoint.
I have been trying to solve this issue for a long time. I would appreciate it if perhaps someone could try to point out what I am doing wrong here.
Below is my code for the program. Thank you
Linked List Class
class LList
{
private:
Node* head;
Node* tail;
int size = 0;
public:
LList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LList(Node* h, Node* t)
{
this->head = h;
this->tail = t;
}
~LList()
{
Node* current = head;
while (current != nullptr) {
Node* next = current->m_next;
delete current;
current = next;
}
}
void print()
{
//temporary node pointer to traverse through the linked list
Node* temp = head;
cout << endl << "<MY LINKED LIST>\n";
while (temp != nullptr)
{
cout << temp->m_data.firstName << " ";
cout << temp->m_data.lastName << " ";
cout << temp->m_data.hrWage << " ";
cout << temp->m_data.hrWork << " " << endl;
temp = temp->m_next;
}
cout << endl;
}
void removeFirst()
{
//case 1: linked list is empty (never enters loop)
//case 2: linked list is not empty
if (head != nullptr)
{
Node* temp = head;
head = head->m_next;
delete temp;
//decrease size tracker of the linked list
size--;
}
}
void removeLast()
{
//case 1: linked list is empty (never enters loop)
//case 2: linked list has one node
if (head->m_next == nullptr)
{
removeFirst();
}
//case 3: linked list has more than one node
else if (head != nullptr)
{
Node* cur = head;
Node* prev = nullptr;
while (cur->m_next != nullptr)
{
prev = cur;
cur = cur->m_next;
}
tail = prev;
tail->m_next = nullptr;
delete cur;
//decrease size tracker of the linked list
size--;
}
}
//void removeAt(int pos)
//{
// //Case 1: input is invalid (less than 1 or greater than size)
// if (pos < 1 && pos > size)
// {
// return;
// }
// //Case 2: input is position 1
// else if (pos == 1)
// {
// removeFirst();
// }
// //Case 3: input is the last position (input equals size)
// else if (pos == size)
// {
// removeLast();
// }
// //Case 4: input is valid, and not 1 or last position (greater than 1 and less than size)
// else if (head != nullptr)
// {
// Node* cur = head;
// Node* prev = nullptr;
// for (int i = 1; i < pos; i++)
// {
// prev = cur;
// cur = cur->m_next;
// }
// prev->m_next = cur->m_next;
// delete cur;
// size--;
// }
//}
Node* swap(Node* lh, Node* rh)
{
Node* temp = rh->m_next;
rh->m_next = lh;
lh->m_next = temp;
return rh;
}
void readBin()
{
ifstream file;
file.open("C:\\Users\\there\\source\\repos\\cst126-lab9-JEmersonLawrance\\BlankConsoleLab\\Employee Data.bin", ios::binary);
if (file)
{
Node* cur = head;
Node* prev = nullptr;
for (int i = 0; i < 4; i++)
{
file.read((char*)&cur->m_data.firstName, sizeof(cur->m_data.firstName));
file.read((char*)&cur->m_data.lastName, sizeof(cur->m_data.lastName));
file.read((char*)&cur->m_data.hrWage, sizeof(cur->m_data.hrWage));
file.read((char*)&cur->m_data.hrWork, sizeof(cur->m_data.hrWork));
prev = cur;
cur = cur->m_next;
}
return;
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
void writeBin()
{
ofstream file;
file.open("Employee Data Output.bin", ios::binary);
if (file)
{
Node* cur = head;
Node* prev = nullptr;
while (cur != nullptr)
{
file.write((char*)&cur->m_data.firstName, sizeof(cur->m_data.firstName));
file.write((char*)&cur->m_data.lastName, sizeof(cur->m_data.lastName));
file.write((char*)&cur->m_data.hrWage, sizeof(cur->m_data.hrWage));
file.write((char*)&cur->m_data.hrWork, sizeof(cur->m_data.hrWork));
prev = cur;
cur = cur->m_next;
}
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
};
Node Class
class Node
{
public:
Employee m_data;
Node* m_next;
Node()
{
m_data.firstName = "";
m_data.lastName = "";
m_data.hrWage = 0;
m_data.hrWork = 0;
m_next = nullptr;
}
Node(Node* next)
{
m_data.firstName = "";
m_data.lastName = "";
m_data.hrWage = 0;
m_data.hrWork = 0;
m_next = next;
}
Node(const Node& copy)
{
m_data.firstName = copy.m_data.firstName;
m_data.lastName = copy.m_data.lastName;
m_data.hrWage = copy.m_data.hrWage;
m_data.hrWork = copy.m_data.hrWork;
}
Node operator = (const Node& copy)
{
m_data.firstName = copy.m_data.firstName;
m_data.lastName = copy.m_data.lastName;
m_data.hrWage = copy.m_data.hrWage;
m_data.hrWork = copy.m_data.hrWork;
return *this;
}
~Node()
{
}
};
Employee Class
struct Employee
{
public:
string firstName;
string lastName;
int hrWage;
int hrWork;
Employee()
{
firstName = "";
lastName = "";
hrWage = 0;
hrWork = 0;
}
Employee(string first, string last, int wage, int work)
{
firstName = first;
lastName = last;
hrWage = wage;
hrWork = work;
}
~Employee()
{
}
void getInput()
{
for (int i = 0; i < 4; i++)
{
cout << "EMPLOYEE # " << i+1 << ":\n" << endl;
cout << "First name: ";
cin >> this[i].firstName;
cout << "Last name: ";
cin >> this[i].lastName;
cout << "Hourly Wage: ";
cin >> this[i].hrWage;
cout << "Hours Worked: ";
cin >> this[i].hrWork;
}
}
void writeBin()
{
ofstream file;
file.open("C:\\Users\\there\\source\\repos\\cst126-lab9-JEmersonLawrance\\BlankConsoleLab\\Employee Data.bin", ios::binary);
if (file)
{
for (int i = 0; i < 4; i++)
{
file.write((char*)&this[i].firstName, sizeof(this[i].firstName));
file.write((char*)&this[i].lastName, sizeof(this[i].lastName));
file.write((char*)&this[i].hrWage, sizeof(this[i]).hrWage);
file.write((char*)&this[i].hrWork, sizeof(this[i]).hrWork);
}
}
else
{
cout << "File could not be opened..\n" << endl;
}
file.close();
}
};
Main Function
int main()
{
cout << "In this program, LIST will read the user information"
<< " in from a binary file, and output it into a different binary"
<< " file.\n" << endl;
Employee data[4];
data->getInput();
data->writeBin();
//creating linked list
Node fourth;
Node third(&fourth);
Node second(&third);
Node first(&second);
LList LIST(&first, &fourth);
LIST.readBin();
LIST.writeBin();
LIST.print();
return 0;
}
In main(), you are constructing your LIST object with pointers to local Node objects that are created in automatic memory within main()'s call frame. When main() exits, all of its local variables are destroyed automatically. But, when the LIST object is destroyed, its destructor tries to call delete on those Node objects which were not created in dynamic memory with new. Thus, your code exhibits undefined behavior.
I am worked on a Linked list stack and a bunch of functions for it. What I do not understand currently is how come my "isEmpty" function is not working correctly. I believe that the way I have it written makes sense. By nature if Front is Null then the list should have to be empty which would mean that "isEmpty" would return false. The problem that I am having is that my program says that the list is always empty whether or not it actually is or not. I am not sure what the issue is. Any help would be appreciated.
struct node
{
int data;
node *next;
}*front = NULL, *rear = NULL, *p = NULL, *np = NULL;
void push(int x)
{
np = new node;
np->data = x;
np->next = NULL;
if(front == NULL)
{
front = rear = np;
rear->next = NULL;
}
else
{
rear->next = np;
rear = np;
rear->next = NULL;
}
}
int pop()
{
int x;
if (front == NULL)
{
cout<<"empty queue\n";
}
else
{
p = front;
x = p->data;
front = front->next;
delete(p);
return(x);
}
}
int peek()
{
int x;
if (front == NULL)
{
cout<<"empty queue\n";
}
else
{
p = front;
x = p->data;
front = front->next;
return(x);
}
}
bool isEmpty()
{
if (front == NULL)
{
return true;
}
else if (front != NULL)
{
return false;
}
}
void Display()
{
cout << front;
}
int main()
{
int n, c = 0, x;
bool is_empty = isEmpty();
cout<<"Enter the number of values to be pushed into queue\n";
cin>>n;
while (c < n)
{
cout<<"Enter the value to be entered into queue\n";
cin>>x;
push(x);
c++;
}
cout<<endl<<"Pop value: ";
if (front != NULL)
cout<<pop()<<endl;
cout<<endl<<"Peak value: ";
if (front != NULL)
cout<<peek()<<endl;
if (is_empty == true)
{
cout<<endl<<"The list is empty";
}
else if (is_empty == false)
{
cout<<endl<<"The list is not empty";
}
cout << endl << "The current contents of the stack are: ";
while(front != NULL)
{
Display();
if(front == NULL)
cout << "The stack is empty";
break;
}
getch();
}
There are some issues with your code.
You have defined an isEmpty() function, but you don't really it. You have declared a separate variable is_empty that you set to the return value of isEmpty() one time before you populate the list, and never update is_empty after making any changes to the list. That is why your code is always reporting the list is "empty" even if it is really not. You need to get rid of the is_empty variable and call isEmpty() every time you need to check for empty.
Also, the return value of peek() and pop() are indeterminate if front is NULL.
And peek() pops the front node from the list. Only pop() should be doing that.
And pop() does not check if rear is pointing at the node being popped. You are not resetting rear to NULL in that case.
And you don't free any nodes remaining in the list before exiting the program.
Try something more like this instead:
#include <iostream>
#include <limits>
struct node
{
int data;
node *next;
node(int value): data(value), next(NULL) {}
};
node *front = NULL;
node *rear = NULL;
void push(int x)
{
node **np = (rear) ? &(rear->next) : &front;
*np = new node(x);
rear = *np;
}
int peek()
{
if (front)
return front->data;
return -1;
}
int pop()
{
int x = peek();
if (front)
{
node *p = front;
front = front->next;
if (p == rear) rear = NULL;
delete p;
}
return x;
}
bool isEmpty()
{
return !front;
}
void clear()
{
while (front)
{
node *p = front;
front = front->next;
delete p;
}
rear = NULL;
}
void display()
{
node *n = front;
if (n)
{
cout << n->data;
while (n = n->next)
cout << ' ' << n->data;
}
}
int askForNumber(const char *prompt)
{
int n;
cout << prompt << ": ";
cin >> n;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return n;
}
int main()
{
int n, x;
n = askForNumber("Enter the number of values to be pushed into queue");
for(int c = 0; c < n; ++c)
{
x = askForNumber("Enter the value to be entered into queue");
push(x);
}
cout << endl;
cout << "Pop value: ";
if (!isEmpty())
cout << pop();
else
cout << "empty queue";
cout << endl;
cout << "Peak value: ";
if (!isEmpty())
cout << peek();
else
cout << "empty queue";
cout << endl;
if (isEmpty())
cout << "The list is empty";
else
cout << "The list is not empty";
cout << endl;
cout << "The current contents of the stack are:" << endl;
display();
cout << endl;
clear();
cin.get();
return 0;
}
I do not know why this code breaks ,probably when adding new node, on Windows .Returns "Process returned -1073741819 (0xC0000005)"),it was compiled with GNU GCC.It works perfectly fine on Linux.
Also tested on geeksforgeeks ide , this is the link https://ide.geeksforgeeks.org/feo8SYMsFP.
When debugged, SIGSEGV is returned when adding node but I am not sure why..
For example, input : 1 10 1 11 then it breaks..
#include <iostream>
#include <stdlib.h>
struct Node
{
int key;
Node * left;
Node * right;
};
class binarySearchTree
{
private:
Node *root;
Node *newNode(int key)
{
Node *temp = new Node;
temp->left = temp->right = NULL;
temp->key = key;
return temp;
}
void traverse_inorder(Node *temp)
{
if (temp==NULL)
return;
traverse_inorder(temp->left);
std::cout <<"Current key: "<< temp->key << "\n";
traverse_inorder(temp->right);
}
void find(Node* temp,int key)
{
if (temp==NULL)
return;
find(temp->left,key);
if (temp->key == key)
std::cout <<"Key " << key << " found\n";
find(temp->right,key);
}
Node* minValueNode(Node* n)
{
Node* x = n;
while (x->left != NULL)
x = x->left;
return x;
}
Node* deleteNode(Node* temp, int key)
{
if (temp == NULL)
return temp;
if (key < temp->key)
temp->left = deleteNode(temp->left, key);
else if (key > temp->key)
temp->right = deleteNode(temp->right, key);
else
{
if (temp->left == NULL)
{
Node *x = temp->right;
delete temp;
return x;
}
else if (root->right == NULL)
{
Node *x = temp->left;
delete temp;
return x;
}
Node* x = minValueNode(temp->right);
temp->key = x->key;
temp->right = deleteNode(temp->right, x->key);
}
return temp;
}
void delete_tree(Node *temp)
{
if (temp == NULL)
return;
delete_tree(temp->left);
delete_tree(temp->right);
delete temp;
}
void traverse_postorder(Node* temp)
{
if (temp == NULL)
return;
traverse_postorder(temp->left);
traverse_postorder(temp->right);
std::cout <<"Current key: "<< temp->key << "\n";
}
void traverse_preorder(Node* temp)
{
if (temp == NULL)
return;
std::cout <<"Current key: "<< temp->key << "\n";
traverse_preorder(temp->left);
traverse_preorder(temp->right);
}
void add(int key)
{
if (root == NULL)
root = newNode(key);
else
{
Node *temp = root;
while (true)
{
if (temp->key > key)
{
if (temp->left == NULL)
{
temp->left = newNode(key);
break;
}
else
temp = temp->left;
}
else if (temp->key < key)
{
if (temp->right == NULL)
{
temp->right =newNode(key);
break;
}
else
temp = temp->right;
}
else
{
std::cout << "Key already added!\n";
break;
}
}
}
}
public:
binarySearchTree()
{
root = NULL;
}
~binarySearchTree()
{
delete_tree(root);
}
void _find(int key)
{
find(root,key);
}
void _del(int key)
{
root = deleteNode(root,key);
}
void _traverse_postorder()
{
traverse_postorder(root);
}
void _traverse_preorder()
{
traverse_preorder(root);
}
void _traverse_inorder()
{
traverse_inorder(root);
}
void _add(int key)
{
add(key);
}
};
int main()
{
binarySearchTree bst;
std::cout << "Binary Search Tree Menu (1-add key, 2-search key, 3-remove key, 4-traverse inorder, 5-traverse postorder, 6-traverse preorder, q-exit)\n";
char input;
do
{
std::cout << "Awaiting input ";
std::cin >> input;
int key;
switch(input)
{
case '1':
std::cout << "Enter key.. ";
std::cin >> key;
bst._add(key);
break;
case '2':
std::cout << "Enter key.. ";
std::cin >> key;
bst._find(key);
break;
case '3':
std::cout << "Enter key.. ";
std::cin>>key;
bst._del(key);
break;
case '4':
bst._traverse_inorder();
break;
case '5':
bst._traverse_postorder();
break;
case '6':
bst._traverse_preorder();
break;
}
}
while (input != 'q');
std::cout << "Deleting Binary Search Tree...\n";
return 0;
}
This code:
struct Node
{
int key;
Node * left;
Node * right;
};
Node *newNode(int key)
{
Node *temp = new Node;
temp->key = key;
return temp;
}
means that newNode returns pointer to node with indeterminate values for left and right. Instead these should be null pointers, (e.g. use new Node(); instead of new Node;).
On the original system it probably happened to get zeroed memory from the allocator so the problem didn't show up.
I have made a C++ program for a binary tree. But the terminal is not asking the statement for inputting the direction for where the elements are to be placed.
Also when I replace the statement from " node *temp = new node " to "node *temp=NULL" the program stops working .
#include <iostream>
#include <cstring>
using namespace std;
class node {
int data;
node * left;
node * right;
public:
node * level_order(node * first);
node * create_bt(node * first);
void display(node * first);
};
//node *first=NULL;
node * node::create_bt(node * first) {
node * temp = new node;
int ele;
//char dir;
cout << "\n Enter data ";
cin >> ele;
temp->data = ele;
temp->left = NULL;
temp->right = NULL;
if (first == NULL) {
temp = first;
return first;
} else {
char dir[20];
cout << "\n Enter the direction ";
cin >> dir;
node * cur = first;
int j = 0;
while (dir[j] != '\0') {
if (dir[j] == 'l') {
cur = cur->left;
}
if (dir[j] == 'r') {
cur = cur->right;
}
j++;
}
cur = temp;
return first;
}
}
void node::display(node * first) {
if (first == NULL)
return;
cout << "\n " << first->data;
display(first->left);
display(first->right);
}
int main() {
int n;
node s;
node * first = NULL;
cout << "\n No of elements ";
cin >> n;
for (int i = 0; i < n; i++) {
first = s.create_bt(first);
}
s.display(first);
return 0;
}
first=s.create_bt(first); does not changes state, from NULL to 'l' or 'r'. You have to change that.
node*node::create_bt(node *first)
{
node *temp=new node;
int ele;
//char dir;
cout<<"\n Enter data ";
cin>>ele;
temp->data=ele;
temp->left=NULL;
temp->right=NULL;
char dir[20];
cout<<"\n Enter the direction ";
cin>>dir;
if(first==NULL)
{
temp=first;
return first;
}
else
{
node*cur=first;
int j=0;
while(dir[j]!='\0')
{
if(dir[j]=='l')
{
cur=cur->left;
}
if(dir[j]=='r')
{
cur=cur->right;
}
j++;
}
cur=temp;
return first;
}
}
I believe you re looking something like this. This is a basic binary tree, i had to make a basic one in order to understand how it works and how it chooses left and right. I make a class inside a class, in order to have access to my data members (node class, int data, *left , *right) and have them at the same time protected, all-in-one. As you can see "newnode" just creates a node and NULL s the pointers. Thats it. "Find" searches and finds a node with a current key, and returns it when exits. All the rest, i guess, you can understand them, as they are prety much the same with your code. The only thing you have to do is to define, when you want to direct the node you want. REMINDER: You have to find a way to utilize it, so the leafs will not end far-left or far-right.("Enter the direction"). I hope i helped you understand.
#include <iostream>
#include <conio.h>
using namespace std;
class mybTree {
class node {
public:
int data;
node * left;
node *right;
};
node *root;
node *newnode(int num){
node *newnode1;
newnode1 = new (nothrow) node;
newnode1->data = num;
newnode1->left = NULL;
newnode1->right = NULL;
return newnode1;
}
public:
node *find (int key) {
node *current;
current = root;
while (current->data !=key){
if (key<current->data){
current = current->left;
} else {
current = current->right;
}
if (current == NULL){
return NULL;
}
}
return NULL;
}
void display (node *ptr);
void display_tree();
bool insert(int num);
void post_order_delete(node *ptr);
mybTree();
~mybTree();
};
int main(){
char ch = ' ';
int a;
mybTree mybTree1;
while (ch !='0'){
cout << "0->Exit"<<endl<< "1-> add"<<endl<< "2-> find" <<endl<<"3-> Show me the tree\n";
ch = getch();
switch (ch) {
case '0':
break;
case '1':
cout << "number";
cin >> a;
if (!mybTree1.insert(a)){
cout << "Not enough memory" << endl;
}
break;
case '2' :
cout << "Number:" ;
cin >> a;
if (mybTree1.find(a)!=NULL) {
cout << "Found" << endl;
} else {
cout << "Not existed" << endl;
}
break;
case '3':
mybTree1.display_tree();
cout<<endl;
break;
default:
cout << "Wrong Message";
break;
}
}
return 0;
}
void mybTree::display(node *ptr) {
if (ptr == NULL){
return;
}
display(ptr->left);
cout << ptr->data<<endl;
display(ptr->right);
}
void mybTree::display_tree() {
//Displays the Tree
display(root);
}
bool mybTree::insert(int num) {
//It inserts a node. Desides left or right.
node *next,*current,*ptr;
int isleft;
next = current = root;
ptr = newnode(num);
if (ptr == NULL) {
return false;
}
if (root == NULL) {
root = ptr;
return true;
}
while (1){
if (num < current->data){
next = current->left;
isleft = 1;
} else {
next = current->right;
isleft = 0;
}
if (next == NULL){
if (isleft){
current->left = ptr;
} else {
current->right = ptr;
}
return true;
}
current=next;
}
return false;
}
void mybTree::post_order_delete(node *ptr) {
//deletes the node. Usefull for destructor
if (ptr == NULL){
return;
}
post_order_delete(ptr->left);
post_order_delete(ptr->right);
cout << ptr->data;
delete ptr;
}
mybTree::mybTree() {
//Constructor
root = NULL;
}
mybTree::~mybTree() {
//Destructor
post_order_delete(root);
root = NULL;
}
I have been working on a little personal project, and have run into a snag. The purpose of the project is to add to my Github, but I have been staring at my code off and on for the last week and cannot find where it goes wrong. The project is a test of my own ability, and my understanding of Linked Lists in C++. Before I go on, here is my code
#include <iostream>
using namespace std;
struct payload {
int ID;
int x;
int y;
string name;
};
struct node {
node* prev;
node* next;
bool isRoot;
payload data;
};
node* fillStruct(node* tmp);
void print(node* tmp);
int main(void) {
node* temp;
node* list;
node* iterator;
bool done = false;
int count = 0;
char answer;
do {
temp = new node();
temp = fillStruct(temp);
if (count == 0) {
list = new node();
list = temp;
list->prev = NULL;
list->next = NULL;
list->isRoot = true;
} else {
list->next = temp;
temp->prev = list;
list = new node();
list = temp;
}
count++;
cout << "Will more elements be added to the list?\n [Y or N]\n";
cin >> answer;
switch (answer) {
case 'y':
case 'Y':
break;
case 'n':
case 'N':
list->next = NULL;
done = true;
break;
default:
break;
}
} while (!done);
while (list->prev != NULL) {
list = list->prev;
}
int identifier = 100;
while (1) {
list->data.ID = identifier;
identifier++;
if (list->next == NULL)
break;
list = list->next;
}
while (list->prev != NULL) {
list = list->prev;
}
while (1) {
print(list);
if (list->next == NULL)
break;
list = list->next;
}
return 0;
}
node* fillStruct(node* tmp) {
if (!tmp) {
cerr << "Unauthorized access. Terminating program";
return tmp;
}
cout << "Please enter the X value.\n";
cin >> tmp->data.x;
cout << "Please enter the Y value.\n";
cin >> tmp->data.y;
cout << "Please enter the data name\n";
cin >> tmp->data.name;
return tmp;
}
void print(node* tmp) {
cout << "Identifier: " << tmp->data.ID << endl;
cout << " X: " << tmp->data.x << endl;
cout << " Y: " << tmp->data.y << endl;
cout << " Name: " << tmp->data.name << endl;
}
The code compiles and executes fine. The problem I am having is in the printing phase of the code. It cuts off the last element, and I cannot tell why. The second while(1), as I understand it, should terminate after it prints the final element. If anyone can offer guidance, I would greatly appreciate it. Thanks in advance, and as usual, if there's anything I can add to clarify, I will.
Following your code, it would seem better to keep list at the list head, and use a pointer for walking the list.
node* list = NULL;
node* ptr = NULL; // tail
do {
temp = new node();
temp = fillStruct(temp);
temp->prev = ptr;
temp->next = NULL;
if (ptr) {
ptr->next = temp;
}
ptr = temp;
if (!list) {
list = ptr;
}
count++;
cout << "Will more elements be added to the list?\n [Y or N]\n";
cin >> answer;
switch (answer) {
case 'y':
case 'Y':
break;
case 'n':
case 'N':
done = true;
break;
default:
break;
}
} while (!done);
int identifier = 100;
for (ptr = list; ptr; ptr = ptr->next) {
ptr->data.ID = identifier;
identifier++;
}
for (ptr = list; ptr; ptr = ptr->next) {
print(list);
}