I'm required to traverse through a singly linked list and find the negative nodes, delete them and return the number of delete nodes.
This is the code i have so far, but I always get counter=1 returned from the function
Is there anything wrong in the for loops and if statements, or is it something else
bool IntSLList::DeleteNegativeNodes()
{
int counter=0;
if(IsEmpty() == true)
counter++;
if(head->val<0)
{
DeleteFromHead();
counter++;
}
if(tail->val<0)
{
DeleteFromTail();
counter++;
}
IntSLLNode *node, *pred, *tmp;
node = pred = NULL;
for(pred = head, node = head->next;
node != NULL;
node = node->next, pred = pred->next)
{
if(node->val<0)
{
node->flag = 1;
}
}
for(tmp = head; tmp != NULL; tmp = tmp->next)
{
if(tmp->flag==1)
counter++;
delete tmp;
}
return counter;
}
int main()
{
int n,x,z;
IntSLList list1;
cout <<"Insert number of nodes u'd like inserted in list" << endl;
cin >> n;
for(int i=0;i<n;i++)
{
cin >> x;
list1.AddToTail(x);
}
z=list1.DeleteNegativeNodes();
cout << "Number of negative deletes nodes is : " << z << endl;
}
The problem is in the type of the return value. Check the signature of the method:
bool IntSLList::DeleteNegativeNodes()
Return type is bool there. When you return counter of type int from your method it's implicitly converted to bool. Zero value becomes false. All other values become true.
On the caller side:
z=list1.DeleteNegativeNodes();
bool value is implicitly converted to int. Because of it you get 1.
Change the return type of DeleteNegativeNodes to int to fix the problem.
In the second for you have
if(tmp->flag==1)
And I think you have to use
if(node->flag==1)
Related
I am trying to implement a simple open hash in c++ for the sake of learning. I am getting very confused about the interaction of functions with array pointers, and I am at the end of my wits.
The code:
struct node{
int data;
node* next;
node* prev;
bool state;
node(){
prev = next = NULL;
state = true;
}
};
//state true means empty, state false means full.
void insert(node *array,int value){
node *current = array;
if(array->state == true){
array->data = value;
array->state = false;
} else {
node* add = new node();
add->data = value;
add->state = false;
while(current->next != NULL){
current = current->next;
}
current->next = add;
add->prev = current;
}
}
void display(node *array, int size){
node *show = new node();
for(int i = 0; i< size; i++){
if(array->state == false){
cout<<array->data;
show = array;
while(show->next != NULL){
show = show->next;
cout<<" --> "<<show->data;
}
} else {
cout<<"Empty.";
}
cout<<"\n\n";
}
}
int main(){
int size;
cout<<"Enter size of the hash table: ";
cin>>size;
node *array = new node[size];
int value;
cout<<"Enter Value: ";
cin>>value;
int index = value%size;
//inserting single value
insert(&array[index],value);
//Hash table output.
display(array,size);
return 0;
}
When I run this code, instead of showing "empty" in places where the array's state is empty, it seems as if the entire array has the same value. The problem lies in the insert function, but I cannot figure it out.
You can simplify this by making the Hashtable an array of pointers to Node. A nullptr then means the slot is empty and you don't have empty and full nodes. Also Nodes only need a next pointer and usually new entries are added to the beginning of the buckets instead of the end (allows duplicate entries to "replace" older ones). Inserting at the beginning of a list becomes real easy with Node **.
#include <cstddef>
#include <iostream>
struct Table {
struct Node {
Node * next;
int data;
Node(Node **prev, int data_) : next{*prev}, data{data_} {
*prev = this;
}
};
std::size_t size;
Node **tbl;
Table(std::size_t size_) : size{size_}, tbl{new Node*[size]} { }
~Table() {
for (std::size_t i = 0; i < size; ++i) {
Node *p = tbl[i];
while(p) {
Node *t = p->next;
delete p;
p = t;
}
}
delete[] tbl;
}
void insert(int value) {
Node **slot = &tbl[value % size];
new Node(slot, value);
}
void display() const {
for(std::size_t i = 0; i < size; i++) {
std::cout << "Slot " << i << ":";
for (const Node *node = tbl[i]; node; node = node->next) {
std::cout << " " << node->data;
}
std::cout << std::endl;
}
}
};
int main(){
std::size_t size;
std::cout << "Enter size of the hash table: ";
std::cin >> size;
Table table{size};
int value;
std::cout << "Enter Value: ";
std::cin >> value;
//inserting single value
table.insert(value);
//Hash table output.
table.display();
return 0;
}
I am trying to implement Binary Search Tree in C++. This is the code I wrote. After giving a few inputs when I try to search for them, the output comes out "false" in every case except the value of the root node. When I tried to check if the loop was matching the values in the nodes properly, the programs crashes. However, without printing, the program would just output negative without crashing. Where did I mess up here?
#include<iostream>
using namespace std;
struct tree {
int data;
tree* left;
tree* right;
};
class BST{
public:
tree* rootTreeNode = NULL;
tree* createNode(int incomingData){
tree* newNode = new tree();
newNode->data = incomingData;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
void insert(tree* RootAddress, int DataToInsert){
if(RootAddress == NULL) {
if(rootTreeNode == NULL) {
rootTreeNode = createNode(DataToInsert);
}
else {
RootAddress = createNode(DataToInsert);
}
} else if(DataToInsert > RootAddress->data) {
insert(RootAddress->right, DataToInsert);
} else if(DataToInsert <= RootAddress->data) {
insert(RootAddress->left, DataToInsert);
}
}
bool search(tree* rootAdd, int dataToSearch){
if(rootAdd == NULL) {
return false;
}
else if(rootAdd->data == dataToSearch){
return true;
}
else if(dataToSearch > rootAdd->data ){
search(rootAdd->right, dataToSearch);
}
else if(dataToSearch <= rootAdd->data){
search(rootAdd->left, dataToSearch);
}
return false;
}
void disp(){
tree * curr = rootTreeNode;
while(1){
cout << curr->data <<endl;
int ch;
cout << "Enter 1 for left and 2 for right" <<endl;
cin >> ch;
if(ch == 1){
curr = curr->left;
}else if(ch == 2){
curr = curr->right;
} else if(ch == 3){
break;
}
}
}
};
int main() {
BST BinartSearchTree;
while(1) {
int c;
cout << "Enter (1) to insert a value.\nEnter (2) to search value.\nEnter (3) to Check the tree.\n.=> ";
cin >> c;
if(c == 1){
int input;
cout << "Enter your Data: ";
cin >> input;
BinartSearchTree.insert(BinartSearchTree.rootTreeNode, input);
} else if(c==2){
int x;
bool result;
cout << "Enter element you wanna search: ";
cin >> x;
result = BinartSearchTree.search(BinartSearchTree.rootTreeNode, x);
if(result) {
cout << "The given data Exists in the tree\n\n";
} else {
cout <<"The Data ain't in the tree\n\n";
}
} else if(c==3){
BinartSearchTree.disp();
}
}
}
In
void insert(tree* RootAddress, int DataToInsert)
tree* RootAddress is passed by value. "Wait a sec!" You say. "That's a pointer dude! Get off the crack!" The tree pointed at, if there is one, is passed by reference, but the pointer itself... is just a copy.
This means
RootAddress = createNode(DataToInsert);
assigns the new tree to a copy. The source tree has no idea that the copy is now pointing somewhere else.
Solution:
void insert(tree* & RootAddress, int DataToInsert)
Pass the pointer by reference.
Next,
search(rootAdd->right, dataToSearch);
does nothing with the value returned by search Whether the value was found or not the function falls through to
return false;
and always returns false for any node past the first. Not very useful.
Solution:
bool search(tree* rootAdd, int dataToSearch){
if(rootAdd == NULL) {
return false;
}
else if(rootAdd->data == dataToSearch){
return true;
}
else if(dataToSearch > rootAdd->data ){
return search(rootAdd->right, dataToSearch);
}
else if(dataToSearch < rootAdd->data){
return search(rootAdd->left, dataToSearch);
}
}
Other notes:
void disp()
does not check to make sure the iteration does not walk off the end of the tree. A test that curr is not NULL is necessary before cout << curr->data <<endl;
In addition the directing of tree iteration is going to make debugging exceptionally annoying. If this is part of a class assignment, check with the instructor that this is what they really want. If this is for your own nefarious purposes, you are probably better served by implementing one of the common traversal algorithms and printing the whole list.
and
Consider replacing tree* createNode(int incomingData) with a suitable Tree constructor
tree(int incomingData): data(incomingData), left(nullptr), right(nullptr)
{
}
or aggregate initialization
rootTreeNode = new tree{DataToInsert, nullptr, nullptr};
Methinks you might have the wrong inequality in the third "else" of your search function:
else if(dataToSearch >= rootAdd->data){
search(rootAdd->left, dataToSearch);
So I've posted about this recently, but I'm still at a loss for what is going wrong. Specifically, I can't seem to figure out what's causing my AVL Tree to take so long to sort. I read in a file of 500,000 random, unsorted numbers to sort by using a vector in a for loop to feed the tree the numbers one at a time. Now, I've also tested using a normal BST, as someone mentioned that having to create so many nodes one at a time might be why it's taking so long, but that completed in only 5 seconds, with only 12,164 nodes skipped due to being duplicates. My AVL Tree is taking upwards of 3 hours just to sort half the list, so something must be going wrong. Can anyone figure out what it is? As far as I know, the rebalancing and insertion logic is correct, because whenever I ran a bunch of test cases on it they all came out fine. I can't seem to track down where the problem is. Here's my full code for anyone that wants to check it out. Main is kind of a mess right now because of all the stuff I've included for testing purposes (like the tracking loop), but most of that will be gone in the final version.
EDIT:
This question has been answered.
#include <iostream>
#include<iomanip>
#include <time.h>
#include <vector>
#include <fstream>
using namespace std;
vector<int> numbers;
struct node
{
public:
int data, height;
node *leftChild, *rightChild;
};
node* root = NULL;
int findMin(node *p) // finds the smallest node in the tree
{
while (p->leftChild != NULL)
p = p->leftChild;
return p->data;
}
int findMax(node *p) // finds the largest node in the tree
{
while(p->rightChild != NULL)
p = p->rightChild;
return p->data;
}
int max(int a, int b) // gets the max of two integers
{
if(a > b)
return a;
else
return b;
}
int height(node *p) // gets the height of the tree
{
if(p == NULL)
return -1;
else
{
p->height = max(height(p->leftChild), height(p->rightChild)) + 1;
}
return p->height;
}
node* newNode(int element) // helper function to return a new node with empty subtrees
{
node* newPtr = new node;
newPtr->data = element;
newPtr->leftChild = NULL;
newPtr->rightChild = NULL;
newPtr->height = 1;
return newPtr;
}
node* rightRotate(node* p) // function to right rotate a tree rooted at p
{
node* child = p->leftChild; // rotate the tree
p->leftChild = child->rightChild;
child->rightChild = p;
// update the height for the nodes
p->height = height(p);
child->height = height(child);
// return new root
return child;
}
node* leftRotate(node* p) // function to left rotate a tree rooted at p
{
node* child = p->rightChild; // perform the rotation
p->rightChild = child->leftChild;
child->leftChild = p;
// update the heights for the nodes
p->height = height(p);
child->height = height(child);
// return new root
return child;
}
int getBalance(node *p)
{
if(p == NULL)
return 0;
else
return height(p->leftChild) - height(p->rightChild);
}
// recursive version of BST insert to insert the element in a sub tree rooted with root
// which returns new root of subtree
node* insert(node*& p, int element)
{
// perform the normal BST insertion
if(p == NULL) // if the tree is empty
return(newNode(element));
if(element < p->data)
{
p->leftChild = insert(p->leftChild, element);
}
else
{
p->rightChild = insert(p->rightChild, element);
}
// update the height for this node
p->height = height(p);
// get the balance factor to see if the tree is unbalanced
int balance = getBalance(p);
// the tree is unbalanced, there are 4 different types of rotation to make
// Single Right Rotation (Left Left Case)
if(balance > 1 && element < p->leftChild->data)
{
return rightRotate(p);
}
// Single Left Rotation (Right Right Case)
if(balance < -1 && element > p->rightChild->data)
{
return leftRotate(p);
}
// Left Right Rotation (double left rotation)
if(balance > 1 && element > p->leftChild->data)
{
p->leftChild = leftRotate(p->leftChild);
return rightRotate(p);
}
// Right Left Rotation
if(balance < -1 && element < p->rightChild->data)
{
p->rightChild = rightRotate(p->rightChild);
return leftRotate(p);
}
// cout << "Height: " << n->height << endl;
// return the unmodified root pointer in the case that the tree does not become unbalanced
return p;
}
void inorder(node *p)
{
if(p != NULL)
{
inorder(p->leftChild);
cout << p->data << ", ";
inorder(p->rightChild);
}
}
void preorder(node *p)
{
if(p != NULL)
{
cout << p->data << ", ";
preorder(p->leftChild);
preorder(p->rightChild);
}
}
void print(node* root)
{
/*cout << "Min Value: " << findMin(root) << endl;
cout << "Max Value: " << findMax(root) << endl;
cout << "Pre Order: ";
preorder(root); */
cout << endl << "Inorder: ";
inorder(root);
cout << endl << endl << endl << endl;
}
void read()
{
int num;
ifstream file_save("data.txt");
if(file_save.is_open())
{
while(!file_save.eof())
{
file_save >> num;
numbers.push_back(num);
}
file_save.close();
}
else
{
cout << "Error in opening file!!" << endl;
}
}
int main()
{
double duration;
time_t begin = time(0);
read();
int x = 0;
int track = 0;
for (std::vector<int>::const_iterator i = numbers.begin(); i != numbers.begin() + 100000; ++i)
{
root = insert(root, numbers[x]);
x++;
track++;
if( (track % 10000) == 0)
{
cout << track << " iterations" << endl;
time_t now = time(0);
cout << now - begin << " seconds" << endl;
}
}
time_t end = time(0);
duration = end - begin;
// print(root);
cout << "The algorithm took " << duration << " seconds to complete." << endl;
return 0;
}
There are many problems with this code.
while(eof) is wrong.
The main loop expects exactly 100000 elements.
All key comparisons are exact (<, >). There are no rotations performed when a duplicate element is inserted. Thus a tree of identical elements will not be balanced at all.
The height of an empty tree is hardcoded to -1, but the height of a single-node three is initially set to 1, thus violating the invariant height(node) = 1+max(height(node->leftChild))+height(node->rightChild)).
height traverses the entire tree every time it is called, thus making insertion O(n).
So, it seems to me that the reason that it was taking so long was because of too many recursive calls all over the place. This modified code has less recursive calls and thus bogs down the CPU with less stacks to have to process. At least, that's what I'm getting out of this.
void newHeight(node* p)
{
double leftHeight = height(p->leftChild);
double rightHeight = height(p->rightChild);
if(leftHeight > rightHeight)
p->height = leftHeight;
else
p->height = rightHeight;
}
node* rotateright(node* p) // the right rotation round p
{
node* q = p->leftChild;
p->leftChild = q->rightChild;
q->rightChild = p;
newHeight(p);
newHeight(q);
return q;
}
node* rotateleft(node* q) // the left rotation round q
{
node* p = q->rightChild;
q->rightChild = p->leftChild;
p->leftChild = q;
newHeight(q);
newHeight(p);
return p;
}
node* rebalance(node* p) // p node balance
{
newHeight(p);
if( getBalance(p)==2 )
{
if( getBalance(p->rightChild) < 0 )
p->rightChild = rotateright(p->rightChild);
return rotateleft(p);
}
if (getBalance(p)==-2 )
{
if( getBalance(p->leftChild) > 0 )
p->leftChild = rotateleft(p->leftChild);
return rotateright(p);
}
return p; // no balance needed
}
node* insert(node* p, int element) // k key insertion in the tree with p root
{
if(!p) return newNode(element);
if(element < p->data)
p->leftChild = insert(p->leftChild, element);
else
p->rightChild = insert(p->rightChild, element);
return rebalance(p);
}
Example:
Linked List A: 1->2->3
Linked List B: 4->5->6
My task is to make a function, that passes List B into List A at any given position (n).
For instance: After "2" = 1->4->5->6->2->3 (output).
I wasn't really sure, how to do this, so I used:
// Function that finds a number in a list and gets an address of that node.
Node* List::find(int i)
{
for (start();!end();next())
if(current->num==i) return current;
return NULL;
};
// Function, that puts freely desired number at position n in the list;
Example cin >> i; // i = 6;
1->2->6->desired number->...
Node* List::addAfter(int pos, int num)
{
Node* p = NULL; i
current = find(pos);
if (current != NULL)
{
p = new Node(num);
p->next = current->next;
current->next = p;
}
if (last == current) last = p;
current = p;
return p;
}
Both things works, but only as:
cout << "After which number?" << endl;
cin >> i; // **2**
l.addAfter(i, 1); // Before: 2->3->4 After: 2->1->3->4
l.print();
This works perfectly! But if I have two lists - l1 (2->3->4 and l2 6->7)
how can I put both together using this function?
Node* List::addAfter(int pos, I HAVE TO PASS L2 VALUES HERE)
How can I give this function l2 values as parameter?
Is there maybe a better way, to do this? I'd appreciate any help.
WHOLE CODE:
#include <iostream>
using namespace std;
class Node
{
public:
int num;
Node *next;
Node (int n) { num = n; next = NULL; };
};
class List
{
protected:
Node *first, *last;
public:
Node *current;
public:
List () { first = last = current = NULL; };
void add_element (int n);
void delete_element ();
void print(); // Izdrukā sarakstu
bool is_empty () { return (first == NULL); };
void start () { current = first; };
bool end () { return (current == NULL); };
void next(){if (!end())current = current -> next;};
Node* find(int i);
Node* addAfter(int i, List * l2);
~List();
};
int main()
{
List l, l2;
int k, i;
cout << "Type number: (0,to stop):\n";
cin >> k;
while (k!=0)
{
l.add_element (k);
cout << "Type number: (0, to stop):\n";
cin >> k;
};
cout << endl;
cout << "Type 2nd list numbers: (0,to stop):\n";
cin >> k;
while (k!=0)
{
l2.add_element (k);
cout << "Type 2nd list numbers: (0,to stop):\n";
cin >> k;
};
cout << endl;
l.print();
l2.print();
cout << "After which element do you want to insert second list?" << endl;
cin >> i;
l.addAfter(i, l2); // GETTING ERROR HERE.
l.print();
return 0;
}
simplest and easiest form is to pour out both stacks into an array
const int size = stackA.size() + stackB.size();
const stackASize = stackA.size();
const stackBSize = stackB.size();
int arrayOfStackA [size];
int arrayOfStackB [stackBSize];
//Pop StackA into ArrayA
for(int i=stackASize-1; i>0; i++)
{
arrayOfStackA[i] = stackA.pop();
}
//Pop StackB into ArrayB
for(int i=stackBSize-1; i>=0; i++)
{
arrayOfStackB[i] = stackB.pop();
}
Now find the index where you want to insert the data in array A.
In your case you want to enter stack b after 1 which in case of array is the index:1
int count = 0
for(int i=0;i<size;i++){
if(i<requiredIndexNumber){
//do nothing
}
else if(i>=requiredIndexNumber && count!=stackBSize){
int temp = arrayOfStackA[i];
arrayOfStackA[i] = arrayOfStackB[count++];
arrayOfStackA[stackASize+i] = temp;
}
}
This is the most easiest from of popping one stack into an other at any index
I was wondering how I would add a counter that represents the number of comparisons in my BST. I added a counter but my printTree function for some reason I keep getting 0 for the count. Am I suppose to count the number of comparisons made in the print function? Or should I have a separate function specifically for counting the number of comparisons made?
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
struct node
{
int data;
node* left;
node* right;
};
node* root = NULL;
node* createLeaf(int data)
{
node* n = new node;
n->data = data;
n->left = NULL;
n->right = NULL;
return n;
}
void addLeaf(node* &curr, int data)
{
//If curr = NULL then add node
if(curr == NULL)
{
curr = createLeaf(data);
}
//Left(Less than)
else if(data <= curr->data)
{
addLeaf (curr->left, data);
}
//Right(greater than)
else if(data >= curr->data)
{
addLeaf(curr->right, data);
}
}
int printTree(node* Ptr, ofstream& NewData, int count)
{
//Check if tree is empty
if(root != NULL)
{
return count++;
if(Ptr->left != NULL)
{
printTree(Ptr->left, NewData, count);
}
NewData << Ptr->data; //Store Data in output file
NewData << endl;
cout << Ptr->data << " ";
if(Ptr->right != NULL)
{
printTree(Ptr->right, NewData, count);
}
}
else
{
cout << "The Tree is empty\n";
}
return Ptr->data;
}
int main()
{
ifstream dataFile;
dataFile.open("Data.txt.");
int temp, count;
count = 0;
while(dataFile)
{
dataFile >> temp;
addLeaf(root, temp);
}
dataFile.close();
ofstream NewData;
NewData.open("NewData.txt");
count = printTree(root, NewData, count);
cout << "count:" << count;
NewData.close();
system("PAUSE");
return 0;
}
Simply pass the count variable by reference (Or use a pointer. Example uses pass by reference) and then increment without returning and this will give you a simple way of counting the number of comparisons. Edited snippets of your code are below.
Note: For future reference post incrementing value to be returned will do nothing if it is being returned. e.g. use return ++count; instead of return count++;. This is why you where getting zero as the value of your count variable. A simple way of explaining this behavior is that when you return a post-incremented value it returns the value and exists that function before incrementing it. Although from what I understand of the code you did not really want to be returning the count variable.
int printTree(node* Ptr, ofstream& NewData, int &count)
{ // ^ The & specifies that is to be passed
// by reference.
//Check if tree is empty
if(root != NULL)
{
// No longer returns instead just increments.
count++;
// Your code here.
}
// Your code here.
}
int main()
{
int count = 0;
// The rest of your code here ....
// Stores the return value from print tree root "ptr->data"
int data = 0;
// New caller will modify count as it is passed by reference, but will "return ptr->data;"
data = printTree(root, NewData, count);
cout << "count:" << count;
system("PAUSE");
return 0;
}
I'd do it by defining a tiny class that was devoted primarily to counting comparisons:
template <class T>
struct holder {
static int count;
T t;
holder(T T) : t(t) {}
operator T() const { return t; }
operator <(T const &r) { ++count; return t < r.t; }
};
int holder::count = 0;
Then a node would hold instances of these instead of holding ints directly:
struct node {
holder<int> data;
node *left;
node *right;
};
Do your work with your tree, and when you want to know the number of comparisons you've done so far, look at holder<int>::count; to get it.