Recursive method to find value in linked list - c++

template<class Type>
int StringList<Type>::find(Type value)
{
int count = 0;
// Start of linked list
Node<Type> *current = head;
// Traverse list until end (NULL)
while (current != NULL)
{
// Increase counter if found
if (current->data == value)
{
count++;
}
// If not, move to the next node
current = current->next;
}
cout << value << " was found " << count << " times" << endl;
return 0;
// same function but using Recursive method
// Start of linked list
Node<Type> *current = head;
int count = 0;
// Thinking this is the base case, since its similar to the while loop
if (current == NULL)
{
return 0;
}
// same as the while loop, finding the value increase the count, or in this case just prints to console
if ((current->data == value))
{
cout << "Found match" << endl;
return 0;
}
else
{ // If it didnt find a match, move the list forward and call the function again
current = current->next;
return find(value);
}
}
the function is supposed to find the value searched and return how many times that certain value was in the linked list.
how can I turn the first method, which uses a while loop, into something that does the same thing but uses recursion?

For starters instead of the return type int it is better to use an unsigned type like for example size_t
You can use the following approach. Define two methods. The first one is a public non-static method find defined like
template<class Type>
size_t StringList<Type>::find( const Type &value ) const
{
return find( head, value );
}
The second one is a private static method with two parameters defined like
template<class Type>
static size_t StringList<Type>::find( Node<Type> *current, const Type &value )
{
return current == nullptr ? 0 : ( current->data == value ) + find( current->next, value );
}

In order to use recursion, you will need to change the signature of your find function (or add a new function with the different signature) to take a node pointer as a parameter:
template<class Type>
int StringList<Type>::find(Type value, Node<Type> *where)
{
if (where != nullptr)
{
// Do things
}
}
Then, when you traverse the list, you pass where->next to the function. Once you hit the end of the list, with a nullptr value, the stack unrolls.
A key aspect of recursion as that the function or method being used only has to process a single node of your container. It then calls itself with the next node to be processed until there are no more nodes. In order to make this work, that function needs the node to process as a parameter, which is where your current code runs into problems.
Keep in mind that the elegance and simplicity of recursion is not free. Every call that a method makes to itself eats up stack, so a sufficiently large container can result in a crash if the stack for your process is depleted.

how can I turn the first method, which uses a while loop, into
something that does the same thing but uses recursion?
The following would be closer to what you want. You really should provide an [MCVE] ... the lack of which forces many guesses and assumptions about your code.
// It looks like StringList is a class (I ignored template issues),
// and it appears that your class holds 'anchors' such as head
// StringList is probably the public interface.
//
// To find and count a targetValue, the code starts
// at the head node, and recurses through the node list.
// I would make the following a public method.
//
int StringList::findAndCountTargetValue(int targetValue)
{
int retVal = 0;
if (nullptr != head) // exists elements to search?
retVal = head->countTV(targetValue); // recurse the nodes
// else no match is possible
return(retVal);
}
// visit each node in the list
int Node::countTV(const int targetValue)
{
int retVal = 0; // init the count
if (data != targetValue) // no match
{
if(nullptr != next) // more elements?
retVal += next->countTV() // continue recursive count
}
else
{
std::cout << "Found match" << std::endl; // for diag only
retVal += 1; // because 1 match has been found
if(nullptr != next) // more elments
retVal += next->countTV(); // continue recursive count
}
return (retVal); // always return value from each level
}

Related

recursive function that takes a pointer to the middle of an infinite doubly linked list and Search for a key

Provide a recursive function that takes a pointer to the middle of an infinite
doubly linked list along with an integer key and searches the list for the given key. The
list grows infinitely in both directions. Your algorithm should be able to find the key if it is
present in the list, otherwise it should continue the search infinitely.
This is The question i'm provided with and i can't understand how To recursivly search on both sides. either i'll have to write 2 functions i.e one for searching left other for right side.
but can it e searched in one function?
this is my code:
void searchmiddle(Node<T>* middle, int key,int index) {
if (middle == NULL) {
return ;
}
if (head == NULL) {
return ;
}
/* if (middle->next == head) {
return false ;
}*/
if (middle->data == key) {
cout << "key found at index "<<index << endl;
key = 0;
return ;
}
searchmiddle(middle->prev, key, index - 1);
searchmiddle(middle->next, key, index + 1);
}
code works for key next to middle pointer..
You could relay the call to a function that instead takes two Node<T>*, left and right. You then check if either one is the correct node and return if anyone is, otherwise you call the same function again recursively while stepping both left and `right.
template<class T>
Node<T>* searchmiddle(Node<T>* left, Node<T>* right, const T& key) {
if (left->data == key) return left;
if (right->data == key) return right;
return searchmiddle(left->prev, right->next, key);
}
template<class T>
Node<T>* searchmiddle(Node<T>* middle, const T& key) {
return searchmiddle(middle, middle->next, key);
}
This is purely theoretical though since it'll most probably stop working when the stack is full. It also doesn't check for nullptr since the list is said to be infinite.
Nothing in the requirement says anything about printing an index so I made it return a pointer to the found Node<T> instead.
You should not use recursion, because the requirement is that the search should continue infinitely for as long as there is no match. The call stack is limited, and recursion consumes it, meaning the recursion cannot go on indefinitely.
By consequence, the search should happen through iteration and not recursion.
You should use two pointers, one that will move along the prev pointers to the left, and the other that will move along the next pointers to the right. As apparently it is needed to report the index where the match was found, you should accompany those two pointers with an index.
There should not be a reference to a head pointer (where is it defined?), as an infinite list has no head. The challenge description suggests that the list extends continually in both directions, so there will be no end node like a head or a tail.
The code could be something like this:
void searchmiddle(Node<T>* middle, int key, int index) {
Node<T>* left = middle;
int leftIndex = index;
Node<T>* right = middle->next;
int rightIndex = index + 1;
while (1) { // Search continues as long there is no match
if (left->data == key) {
cout << "key found at index " << leftIndex << endl;
return;
}
left = left->prev;
leftIndex--;
if (right->data == key) {
cout << "key found at index " << rightIndex << endl;
return;
}
right = right->prev;
rightIndex++;
}
}
This is quite a theoretical challenge, as the only way to have a really infinite linked list, is to make it circular. It also means that there is a possibility that the key will never be found giving you a function that never finishes.

C Creating a binary tree based on a sequence

I need help adjusting the createTree function.
Which accepts a string and after that character by character traverses it, creating a binary tree based on it
If it encounters the character 0, it recursively creates two sub-branches.
If it encounters another character, it saves it in the leaf node.
For the string in the example, I need to make a tree as in the picture, but the function does not work properly for me. Thank you in advance for your advice.
int x = 0;
Node* createTree(string str, int si, int ei)
{
if (si > ei)
return NULL;
Node *root = new Node((str[si] - '0'));
if(str[si] != '0')
{
x++;
root->m_Data = (str[si] - '0');
return root;
}
if(str[si]=='0')
{
x++;
root->m_Left = createTree(str,x,ei);
root->m_Right = createTree(str,x,ei);
}
return root;
}
int main ()
{
string str = "050067089";
Node *node = createTree(str,0,str.length());
printPreorder(node);
return 0;
}
The problem can quite easily be broken down into small steps (what you partly did in your question).
Start iterating at the first character
Create the root node
If the current character is non-zero, set the value of this node to this character
If current character is a zero, set this node to zero, create a left and a right node and get back to step 3 for every one of them. (That's the recursive part.)
Below is my implementation of this algorithm.
First, a little bit of setting up:
#include <iostream>
#include <string>
#include <memory>
struct Node;
// Iterator to a constant character, NOT a constant iterator
using StrConstIt = std::string::const_iterator;
using UniqueNode = std::unique_ptr<Node>;
struct Node
{
int value;
UniqueNode p_left;
UniqueNode p_right;
Node(int value)
: value(value) {}
Node(int value, UniqueNode p_left, UniqueNode p_right)
: value(value), p_left(std::move(p_left)), p_right(std::move(p_right)) {}
};
As you can see, I'm using std::unique_ptr for managing memory. This way, you don't have to worry about manually deallocating memory. Using smart pointers is often considered the more "modern" approach, and they should virtually always be preferred over raw pointers.
UniqueNode p_createNodeAndUpdateIterator(StrConstIt& it, StrConstIt stringEnd)
{
if (it >= stringEnd)
return nullptr;
UniqueNode node;
if (*it == '0')
// Create node with appropriate value
// Create branches and increment iterator
node = std::make_unique<Node>(
0,
p_createNodeAndUpdateIterator(++it, stringEnd),
p_createNodeAndUpdateIterator(it, stringEnd)
);
else
{
// Create leaf node with appropriate value
node = std::make_unique<Node>(*it - '0');
// Increment iterator
++it;
}
return node;
}
UniqueNode p_createTree(StrConstIt begin, StrConstIt end)
{
return p_createNodeAndUpdateIterator(begin, end);
}
The first function takes a reference to the iterator to the next character it should process. That is because you can't know how much characters a branch will have in its leaf nodes beforehand. Therefore, as the function's name suggests, it will update the iterator with the processing of each character.
I'm using iterators instead of a string and indices. They are clearer and easier to work with in my opinion — changing it back should be fairly easy anyway.
The second function is basically syntactic sugar: it is just there so that you don't have to pass an lvalue as the first argument.
You can then just call p_createTree with:
int main()
{
std::string str = "050067089";
UniqueNode p_root = p_createTree(str.begin(), str.end());
return 0;
}
I also wrote a function to print out the tree's nodes for debugging:
void printTree(const UniqueNode& p_root, int indentation = 0)
{
// Print the value of the node
for (int i(0); i < indentation; ++i)
std::cout << "| ";
std::cout << p_root->value << '\n';
// Do nothing more in case of a leaf node
if (!p_root->p_left.get() && !p_root->p_right.get())
;
// Otherwise, print a blank line for empty children
else
{
if (p_root->p_left.get())
printTree(p_root->p_left, indentation + 1);
else
std::cout << '\n';
if (p_root->p_right.get())
printTree(p_root->p_right, indentation + 1);
else
std::cout << '\n';
}
}
Assuming that the code which is not included in your question is correct, there is only one issue that could pose a problem if more than one tree is built. The problem is that x is a global variable which your functions change as a side-effect. But if that x is not reset before creating another tree, things will go wrong.
It is better to make x a local variable, and pass it by reference.
A minor thing: don't use NULL but nullptr.
Below your code with that change and the class definition included. I also include a printSideways function, which makes it easier to see that the tree has the expected shape:
#include <iostream>
using namespace std;
class Node {
public:
int m_Data;
Node* m_Left = nullptr;
Node* m_Right = nullptr;
Node(int v) : m_Data(v) {}
};
// Instead of si, accept x by reference:
Node* createTree(string str, int &x, int ei)
{
if (x >= ei)
return nullptr;
Node *root = new Node((str[x] - '0'));
if(str[x] != '0')
{
root->m_Data = (str[x] - '0');
x++;
return root;
}
if(str[x]=='0')
{
x++;
root->m_Left = createTree(str,x,ei);
root->m_Right = createTree(str,x,ei);
}
return root;
}
// Overload with a wrapper that defines x
Node* createTree(string str)
{
int x = 0;
return createTree(str, x, str.length());
}
// Utility function to visualise the tree with the root at the left
void printSideways(Node *node, string tab) {
if (node == nullptr) return;
printSideways(node->m_Right, tab + " ");
cout << tab << node->m_Data << "\n";
printSideways(node->m_Left, tab + " ");
}
// Wrapper for above function
void printSideways(Node *node) {
printSideways(node, "");
}
int main ()
{
string str = "050067089";
Node *node = createTree(str);
printSideways(node);
return 0;
}
So, as you see, nothing much was altered. Just si was replaced with x, which is passed around by reference, and x is defined locally in a wrapper function.
Here is the output:
9
0
8
0
7
0
6
0
5

search function causes program to crash

I have been going through the debugger but can't seem to pinpoint exactly what is going wrong. I have come to my own conclusion i must be missing a nullptr check somewhere or something. If anyone can provide some help it would be greatly appreciated.
error message from debugger
error msg
which looks like makes the program crash on this line:
if (node->children_[index] == nullptr) {
search function
Node* search(const string& word, Node* node, int index) const {
Node* temp;
//same as recurssive lookup just difference is returns node weather terminal or not
if (index < word.length()) {
index = node->getIndex(word[index]);
if (node->children_[index] == nullptr) {
return nullptr;
}
else {
temp = search(word, node->children_[index], index++);
}
}
return temp; // this would give you ending node of partialWord
}
Node struct for reference
struct Node {
bool isTerminal_;
char ch_;
Node* children_[26];
Node(char c = '\0') {
isTerminal_ = false;
ch_ = c;
for (int i = 0; i < 26; i++) {
children_[i] = nullptr;
}
}
//given lower case alphabetic charachters ch, returns
//the associated index 'a' --> 0, 'b' --> 1...'z' --> 25
int getIndex(char ch) {
return ch - 'a';
}
};
Node* root_;
int suggest(const string& partialWord, string suggestions[]) const {
Node* temp;
temp = search(partialWord, root_, 0);
int count = 0;
suggest(partialWord, temp, suggestions, count);
return count;
}
Might be a very simple thing. Without digging I am not sure about the rank of the -> operator versus the == operator. I would take a second and try putting parenthesis around the "node->children_[index] == nullptr" part like this:
(node->children_[index]) == nullptr
just to make sure that the logic runs like you seem to intend.
Dr t
I believe the root cause is that you're using index for two distinct purposes: as an index into the word you're looking for, and as an index into the node's children.
When you get to the recursion, index has changed meaning, and it's all downhill from there.
You're also passing index++ to the recursion, but the value of index++ is the value it had before the increment.
You should pass index + 1.
[An issue in a different program would be that the order of evaluation of function parameters is unspecified, and you should never both modify a variable and use it in the same parameter list. (I would go so far as to say that you should never modify anything in a parameter list, but many disagree.)
But you shouldn't use the same variable here at all, so...]
I would personally restructure the code a little, something like this:
Node* search(const string& word, Node* node, int index) const {
// Return immediately on failure.
if (index >= word.length())
{
return nullptr;
}
int child_index = node->getIndex(word[index]);
// The two interesting cases: we either have this child or we don't.
if (node->children_[child_index] == nullptr) {
return nullptr;
}
else {
return search(word, node->children_[child_index], index + 1);
}
}
(Side note: returning a pointer to a non-const internal Node from a const function is questionable.)

singly linked chain printing c++

I am trying to pick my chain in the format {1,2,3,4,etc}. You can find the header file below which will have the layout of the nodes. I am just confused on how I should go about cycling through my list to print out Item.
Any guidance would be greatly appreciated!
set.h
using namespace std;
#include <iostream>
class Set
{
private:
struct Node
{
int Item; // User data item
Node * Succ; // Link to the node's successor
};
unsigned Num; // Current count of items in the set
Node * Head; // Link to the head of the chain
public:
// Return information about the set
//
bool is_empty() const { return Num == 0; }
unsigned size() const { return Num; }
// Initialize the set to empty
//
Set();
// Insert a specified item into the set, if possible
//
bool insert( int );
// Display the set
//
void display( ostream& ) const;
};
Here are two recommendations: 1) Sort the list first, then print all nodes; 2) Create another list (indices) to the data and sort those links (don't need data in those nodes).
Sorting List First
An often used technique is to order the nodes in the order you want them printed. This should involve changing the link fields.
Next, start at the head node and print each node in the list (or the data of each node in the list).
Using an Index list
Create another linked list without the data fields. The links in this list point to the data fields in the original list. Order the new list in the order you want the nodes printed.
This technique preserves the order of creation of the first list and allows different ordering schemes.
Changing Links
Since you're writing your own Linked List, the changing of the links is left as an exercise as I'm not getting paid to write your code. There are many examples on SO as well as the web for sorting and traversing linked lists.
You just want to do something like this:
void Set::display(ostream &out) const {
for(int i=0; i<Num; i++) {
out << Pool[i] << " ";
}
out << endl;
}
An ostream behaves as cout would.
It's hard to get your question. If you want to print the array to screen you should consider writing a display() like:
#include <iostream>
#include <iterator>
void Set::display() const {
ostream_iterator<int> out_it (cout," ");
copy(Pool,Pool+Num,out_it);
cout << endl;
}
or if you want to write to a ostream& (as it is pointed out in the answer by #alestanis)
#include <iostream>
#include <iterator>
void Set::display(ostream &out) const {
ostream_iterator<int> out_it (out," ");
copy(Pool,Pool+Num,out_it);
out << endl;
}
Without testing, I'd do something like this. (Assumes the last node has Succ set to NULL, as I would recommend it does.)
void LoopList(struct Node *head)
{
for (struct Node *p = head; p != null; p = p->Succ)
{
// Do whatever with this node
Print(p);
}
}
I think I was over thinking it. Anyway here is what I ended up doing. Now I just need to add some formatting for the commas and im all set.
Node * Temp;
Temp = new (nothrow) Node;
Temp = Head;
out << "{";
while(Temp->Succ)
{
out << Temp->Item;
Temp = Temp->Succ;
}
out << '}' << endl;
Suppose your list is cyclical, you can use this:
struct Node *n = begin;
if (n != NULL) {
//do something on it
...
for (n = begin->Succ; n != begin; n = n->Succ) {
}
}
or
struct Node *n = begin;
if (n != NULL) {
do {
//do something
...
n = n->Succ;
} while (n != begin)
}

Insertion error in Binary Search tree

void BST::insert(string word)
{
insert(buildWord(word),root);
}
//Above is the gateway insertion function that calls the function below
//in order to build the Node, then passes the Node into the insert function
//below that
Node* BST::buildWord(string word)
{
Node* newWord = new Node;
newWord->left = NULL;
newWord->right = NULL;
newWord->word = normalizeString(word);
return newWord;
}
//The normalizeString() returns a lowercase string, no problems there
void BST::insert(Node* newWord,Node* wordPntr)
{
if(wordPntr == NULL)
{
cout << "wordPntr is NULL" << endl;
wordPntr = newWord;
cout << wordPntr->word << endl;
}
else if(newWord->word.compare(wordPntr->word) < 0)
{
cout << "word alphabetized before" << endl;
insert(newWord,wordPntr->left);
}
else if(newWord->word.compare(wordPntr->word) > 0)
{
cout << "word alphabetized after" << endl;
insert(newWord, wordPntr->right);
}
else
{
delete newWord;
}
}
So my problem is this: I call the gateway insert() externally (also no problems with the inflow of data) and every time it tells me that the root, or the initial Node* is NULL. But that should only be the case before the first insert. Each time the function is called, it sticks the newWord right at the root.
To clarify: These functions are part of the BST class, and root is a Node* and a private member of BST.h
It's possible it is quite obvious, and I have just been staring too long. Any help would be appreciated.
Also, this is a school-assigned project.
Best
Like user946850 says, the variable wordPntr is a local variable, if you change it to point to something else it will not be reflected in the calling function.
There are two ways of fixing this:
The old C way, by using a pointer to a pointer:
void BST::insert(Node *newWord, Node **wordPntr)
{
// ...
*wordPntr = newWord;
// ...
}
You call it this way:
some_object.insert(newWord, &rootPntr);
Using C++ references:
void BST::insert(Node *newWord, Node *&wordPntr)
{
// Nothing here or in the caller changes
// ...
}
To help you understand this better, I suggest you read more about scope and lifetime of variables.
The assignment wordPntr = newWord; is local to the insert function, it should somehow set the root of the tree in this case.