I'm trying to write a function to delete a node any where in a linear linked list recursively but it's not working so far. Deleting at the beginning works but not in the middle. Here is my code
int remove(node* &head, char* data_to_delete)
{
if(!head) return 0; // check if head is null
if(!strcmp(head->data,data_to_delete)) //check if the first node is data
{ node* temp = head->next; //save head->next
delete [] head->data; //deallocate data
delete head; //delete the node
head = temp; //connect the node
return 1;
}
if(head->next && !strcmp(head->next->data,data_to_delete))//check if head->next is not null and head->next->data is equal to data
{
node* temp = head->next->next;
delete [] head->next->data;
delete head->next;
head->next = temp;
return 1;
}
remove(head->next, data_to_delete);
}
Also how would I modify this if I want to drag along a previous pointer instead of looking ahead? Thanks!!!!
Related
I cannot get this tree to act correctly. i keep getting exit error codes. What is going on with the tree and how would i use the search function in main? it seems the methods are coded correctly but i am not using it correctly in main. i keep geting exit errors that are not 0 and none of the methods i try to use in the main function work. now i am just typing to fill in space because apparently my post is mostly code and not enough text!
//Binary Tree Practice
#include <iostream>
struct node{
int data;
node* right;
node* left;
};
class bTree{
public:
bTree(){
root=NULL;
}
~bTree(){
destroyTree();
}
void addNode(int key);
node *search(int key);
void destroyTree();
private:
node* root;
void addNode(int key,node*nod);
node *search(int key, node *leaf);
void destroyTree(node*&node);
};
node *bTree::search(int key)
{
return search(key, root);
}
void bTree::destroyTree()
{
destroyTree(root);
}
void bTree::addNode(int key)
{
if(root!=NULL)
addNode(key, root);
else
{
root=new node;
root->data=key;
root->left=NULL;
root->right=NULL;
}
}
void bTree::addNode(int key, node* nod) {//ADD a node in correct position.
if (key < nod->left->data) {
if (nod->left != NULL)
addNode(key, nod->left);//RECURSION traverse tree to the left until
find a NULL node
else {//When NULL node is found
nod->left = new node;
nod->left->data = key;
nod->left->left = NULL;
nod->right = NULL;
std::cout<<"node added"<<std::endl;
}
} else if (key > nod->right->data) {
if (nod->right != NULL)
addNode(key, nod->right);//RECURSIONTraverse right till find a null
node
else {//NULL node found
nod->right = new node;//Create new node
nod->right->data = key;//set NODE data to KEY
nod->right->right = NULL;
nod->left = NULL;
}
}
}
node *bTree::search(int key, node *leaf)
{
if(leaf!=NULL)
{
if(key==leaf->data)
return leaf;
if(key<leaf->data)
return search(key, leaf);
else
return search(key, leaf->right);
}
else return NULL;
}
void bTree:: destroyTree(node*&node){
if(node==NULL){
destroyTree(node->left);
destroyTree(node->right);
delete node;
}
}
int main() {
bTree *trees=new bTree();
trees->addNode(10);
trees->addNode(6);
trees->addNode(14);
node *check;
}
The first thing your addNode function with signature void bTree::addNode(int key, node* nod) does is this:
if (key < nod->left->data) {
The problem with your code is that nod->left will lead to a crash, since the left node has not been initialized and leads to an unauthorized memory access, or what is called a segmentation fault. Let's go through the main loop.
addNode(10) - The addNode function with signature void bTree::addNode(int key) is called, root is null, so root is created with left and right nodes set to NULL.
addNode(6) - The addNode function with signature void bTree::addNode(int key) is called, root is NOT null, so addNode with signature void bTree::addNode(int key, node* nod) is called. Then nod->left, and crash.
This is a common problem in low level programming, and my advice to you is to put debug prints inside the functions to see which parameters entered, and where exactly the code crashed. If you can pinpoint the exact line that leads to the crash (in thise case the line with nod->left) you can solve these kinds of problems more easily in the future.
In order to fix your issue, simply make sure to initialize the left and right nodes before you access them.
Below is my code. I'm trying to return head node back after I insert value to either left or right node. I understood the concept of insertion, but I'm unable to understand how can I return my head node back to that now it is back to original state with addition node added.
Here is exactly I don't understand.
When I insert my node how can I break the loop and return its head node back.
Recursion is stack concept which will output based on LIFO and if it is lifo how can I have head node returned back
Here's my code:
class Node {
int data;
Node left;
Node right;
}
static Node Insert(Node root,int value)
{
return nodeHelper(root,value);
}
static Node nodeHelper(Node root,int value){
Node nodeTracker = root;
Node temp;
if(root!=null){
if(value>root.data){
if(root.right==null){
temp =new Node();
temp.data = value;
root.right = temp;
return nodeTracker;
}
else{
nodeHelper(root.right,value);
}
}
else{
if(root.left==null){
temp=new Node();
temp.data = value;
root.left = temp;
return nodeTracker;
}
else{
nodeHelper(root.left,value);
}
}
}
else{
temp=new Node();
temp.data = value;
return temp;
}
}
}
To return the root of the tree, you need a third parameter that you pass around to keep track of the root. Like this:
Node* nodeHelper(Node* nodeTracker, Node* parent, int value)
Remove the local nodeTracker variable.
Your recursive calls become:
return nodeHelper(nodeTracker, parent.left, value);
(and, of course, same thing for the right branch)
And your initial call in the insert function is:
return nodeHelper(root, root, value);
Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.
In the following code, I'm trying to get a better hand at understanding how recursion actually work. I've always been a bit confused about it's actual working. I want to know what value does the inorder() function actually return in every step. From where does it get these values of 0,0,11,0,0,11,12,0,0,11 respectively. Could someone tell me the logic? It's a basic inorder tree traversal program.The reason why I'm trying to understand these outputs is because the same logic is somehow used to find the depth of the tree( I think) where with every recursion the value of depth increases without initialization.
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
};
struct node* newNode(int data)
{
struct node* node=(struct node*)malloc(sizeof(struct node));
node->data=data;
node->left=NULL;
node->right=NULL;
return node;
}
int inorder(struct node *temp) {
if (temp != NULL) {
printf("\nleft %d\n",inorder(temp->left));
printf("\n%d\n", temp->data);
printf("\nright %d\n",inorder(temp->right));
}
}
int main()
{
struct node *root=newNode(1);
root->left=newNode(2);
root->right=newNode(3);
root->left->left=newNode(4);
root->left->right=newNode(5);
inorder(root);
getchar();
return 0;
}
This function should be changed to the following (the first and last print in the original code will only get you more confused!):
int inorder(struct node *temp) {
if (temp != NULL) {
inorder(temp->left);
printf("%d\n", temp->data);
inorder(temp->right);
}
}
The recursion starts with the left branch of a specific node (usually the "root") - printing recursively (in-order) all the nodes on that left-branch, then printing the current node, moving on to printing recursively (in-order) all the nodes in the right branch.
By the way, if you want to keep that tree "ordered" (meaning, all the nodes on the left branch are smaller than the node, and all the nodes on the right branch are bigger or equal to the node) you should change:
root->left->left=newNode(4);
root->left->right=newNode(5);
to:
root->right->right=newNode(4);
root->right->right->right=newNode(5);
I have addFile function in my TableModel class which inserts a new record at the end.
void TableModel::addFile(const QString &path)
{
beginInsertRows(QModelIndex(), list.size(),list.size());
TableItem item;
item.filename = path;
QFile file(path);
item.size = file.size();
item.status = StatusNew;
list << item;
endInsertRows();
}
This function works fine but instead of appending record at the end I would like to insert it at the top. Any pointers on how to update my existing function ?
I have already tried some combinations but there is no Luck.
There are two things that you need to do. First is to adjust the call to beginInsertRows. Because it is here that we are telling the model that we are adding rows, where they will go, and how many we are adding. Here is the method description:
void QAbstractItemModel::beginInsertRows ( const QModelIndex & parent,
int first, int last )
So in your case since you want to add a row at the first index, and only one row, we pass 0 as the index of the first item, and 0 which is the index of the last item we are adding (because of course we are only adding one item).
beginInsertRows(modelIndex(), 0, 0);
Next we have to provide the data for the item. I assume that 'list' is a QList (if not it is probably similar). So we want to call the 'insert' method.
list.insert(0, item);
And that should be it.
For display you can try delegates as explained in the link (I haven't tried the example though). It will help the community if you can add your observations.
Thanks to everyone for replying. I have found the solution by my own:
In case if anyone is interested
void TableModel::addFile(const QString &path)
{
beginInsertRows(QModelIndex(), list.size(), list.size());
TableItem item;
item.filename = path;
QFile file(path);
item.size = file.size();
item.status = StatusNew;
list << item; // Why Assign first? Maybe not required
for (int i = list.size() - 1; i > 0; i--)
{
list[i] = list[i-1];
}
list[0] = item; // set newly added item at the top
endInsertRows();
}