Left-Child Right-Sibling move a sibling to a child node? - c++

I have for example a Left-Child Right-Sibling tree:
If for example, I want to make E (including its child nodes E,K,L,P,Q) a child to H node. So H will contain N,O, E(and its children)
I intend to add the children to the parent node, then delete the old nodes but then there are new parent-children pairs. What is the shortest way for this?
Here's some code to reproduce:
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
struct Node
{
string data;
struct Node *next;
struct Node *child;
};
// Creating new Node
Node* newNode(string data)
{
Node *newNode = new Node;
newNode->next = newNode->child = NULL;
newNode->data = data;
return newNode;
}
// Adds a sibling to a list with starting with n
Node *addSibling(Node *n, string data)
{
if (n == NULL)
return NULL;
while (n->next)
n = n->next;
return (n->next = newNode(data));
}
// Add child Node to a Node
Node *addChild(Node * n, string data)
{
if (n == NULL)
return NULL;
// Check if child list is not empty.
if (n->child)
return addSibling(n->child, data);
else
return (n->child = newNode(data));
}
// Traverses tree in level order
void traverseTree(Node * root)
{
if (root == NULL)
return;
while (root)
{
cout << " " << root->data;
if (root->child)
traverseTree(root->child);
root = root->next;
}
}
//Driver code
int main()
{
Node *root = newNode("A");
Node *nB = addChild(root, "B");
Node *nC = addChild(root, "C");
Node *nD = addChild(root, "D");
Node *nE = addChild(root, "E");
Node *nF = addChild(root, "F");
Node *nG = addChild(root, "G");
Node *nH = addChild(nB, "H");
Node *nI = addChild(nB, "I");
Node *nJ = addChild(nB, "J");
Node *nK = addChild(nE, "K");
Node *nL = addChild(nE, "L");
Node *nM = addChild(nG, "M");
Node *nN = addChild(nH, "N");
Node *nO = addChild(nH, "O");
Node *nP = addChild(nK, "P");
Node *nQ = addChild(nL, "Q");
traverseTree(root);
return 0;
}

Related

Linked list infinite loop c++

I've created two linked lists it's supposed to do a union and a merge. If I run the functions separately it does the task it's supposed to do merge or union. But when I try to output both simultaneously, the code infinitely keeps going. I don't know if it has to do with my null or the functions themselves.
#include <iostream>
using namespace std;
struct Node{
int num;
Node *next;
};
//
Node * unionLL (Node * LA, Node * LB)
{
if(LA == NULL)
{
return LB;
}
if(LB == NULL)
{
return LA;
}
Node *temp = NULL;//Creation of a node name temp as a place holder
if(LA != NULL) // if LA is less than LB
{
temp = LA;
temp->next = unionLL(LA->next, LB);
}
else if(LB != NULL)
{
temp = LB;
temp->next = unionLL(LA,LB->next);
}
return temp;
}
Node * mergeLL (Node * LA, Node * LB) // method
{
if(LA == NULL)
{
return LB;
}
if(LB == NULL)
{
return LA;
}
Node *temp = NULL;//Creation of a node name temp as a place holder
if(LA->num<=LB->num) // if LA is less than LB
{
temp = LA;
temp->next = mergeLL(LA->next, LB);
}
else if(LB->num<=LA->num)
{
temp = LB;
temp->next = mergeLL(LA,LB->next);
}
return temp;
}
int main()
{
// set 1
Node *head = new Node(); // Creation of node
Node *neighbor1 = new Node();
Node *neighbor2 = new Node();
Node *neighbor3 = new Node();
neighbor3->num=11;
neighbor2->num=8;
neighbor1->num=5;
head->num= 3; // head is leading node
head->next =neighbor1;
neighbor1->next = neighbor2;
neighbor2->next = neighbor3;
neighbor3->next = NULL;
// set 2
Node *head2 = new Node(); // Creation of node
Node *neighbor6 = new Node();
Node *neighbor7 = new Node();
Node *neighbor8 = new Node();
Node *neighbor9 = new Node();
Node *neighbor10 = new Node();
head2->num= 2; // head is leading node
neighbor6->num=6; // neighbor points to num which value is 6
neighbor7->num=8;
neighbor8->num=9;
neighbor9->num=22;
neighbor10->num=24;
head2->next =neighbor6; //link to next element
neighbor6->next = neighbor7;
neighbor7->next = neighbor8;
neighbor8->next = neighbor9;
neighbor9->next = neighbor10;
neighbor10->next = NULL;
Node *head3 = head;
Node *head4 = head2;
Node *Merge = mergeLL(head,head2);
cout<<"mergeLL(LA, LB) = ";
while(Merge != NULL)
{
cout<<Merge->num; cout<<" "; //end is no new line
Merge= Merge->next;
}
Node *unionLLL = unionLL(head3,head4);
cout<<"unionLLL(LA, LB) = ";
while(unionLLL != NULL)
{
cout<<unionLLL->num; cout<< " ";
unionLLL= unionLLL->next;
}
return 0;
}
You are modifying the original linked lists in your mergeLL and unionLL functions. This is done when you change ->next to point to a different Node then it originally did. It is making some circular loops where head points to head2 and that is why it never reaches the end. Your mergeLL and unionLL functions need to create new Node() inside there, so that the original lists stay intact. Just copying the head node as you do in main doesn't preserve the original linked list order.
I've created a helpful printList function, that you can see the addresses, which can help you debug/design the linked list you want.
void printList(Node *head, const char *name)
{
cout << name << ":";
while (head != NULL)
{
cout << " " << head->num << "(" << head << ")";
head = head->next;
}
cout << "\n";
}
int main {
...
printList(head, "head");
printList(head2, "head2");
Node *Merge = mergeLL(head, head2);
printList(Merge, "mergeLL(LA, LB)");
printList(head, "head");
printList(head2, "head2");
...
}
returns
head: 3(0x1817eb0) 5(0x1817ed0) 8(0x1817ef0) 11(0x1817f10)
head2: 2(0x1817f30) 6(0x1817f50) 8(0x1817f70) 9(0x1817f90) 22(0x1817fb0) 24(0x1817fd0)
mergeLL(LA, LB): 2(0x1817f30) 3(0x1817eb0) 5(0x1817ed0) 6(0x1817f50) 8(0x1817ef0) 8(0x1817f70) 9(0x1817f90) 11(0x1817f10) 22(0x1817fb0) 24(0x1817fd0)
head: 3(0x1817eb0) 5(0x1817ed0) 6(0x1817f50) 8(0x1817ef0) 8(0x1817f70) 9(0x1817f90) 11(0x1817f10) 22(0x1817fb0) 24(0x1817fd0)
head2: 2(0x1817f30) 3(0x1817eb0) 5(0x1817ed0) 6(0x1817f50) 8(0x1817ef0) 8(0x1817f70) 9(0x1817f90) 11(0x1817f10) 22(0x1817fb0) 24(0x1817fd0)

How Can I Create A Single function that can create multiple Linked Lists

as shown in the code , i have to use 2 similar functions for creating 2 linked lists . isn't there a way i can create as many lists as i want with just one function , i tried using struct Node **p and struct Node *p as a parameter to the function but the didn't work
can someone help me to create multiple linked lists using this same function
and i want to create a append function not a insert function which asks for position as well.
#include <iostream>
using namespace std;
struct Node
{
int data = 10 ;
struct Node *next;
} *first , *second , *third;
void Display(struct Node *p)
{
while (p)
{
cout<<p->data<<" ";
p = p->next ;
}
cout<<"\n";
}
void Append_1(int elem)
{
Node* t , *last;
t = new Node;
t->data = elem;
t->next = NULL;
if(first == 0)
first = last = t;
else
{
last->next = t;
last = t;
}
}
void Append_2(int elem)
{
Node* t , *last;
t = new Node;
t->data = elem;
t->next = NULL;
if(second == 0)
second = last = t;
else
{
last->next = t;
last = t;
}
}
//void SortMerge(struct Node *p , struct Node *q);
int main()
{
Append_1(3);
Append_1(7);
Display(first);
Append_2(10);
Append_2(14);
Append_2(21);
Display(second);
//SortMerge(first , second);
Display(third);
return 0;
}
You can create a class like here:
struct Node{
int data;
Node* next;
Node* previous;
};
class Graph{
public:
Graph(int = 0);
~Graph();
void display_left_right();
void display_right_left();
void append(int);
void append_at_pos(int,int);
void prepend(int);
int get_num_elt();
int get_data_at_pos(int);
private:
Node* head;
Node* tail;
int num_elt=0;
};
Graph::Graph(int first_data){
head = new Node;
head->next = NULL;
head->previous = NULL;
head->data = first_data;
tail = head;
num_elt++;
}
Graph::~Graph(){
Node* main_traverser = head;
while(main_traverser){
main_traverser = head->next;
delete head;
head = main_traverser;
}
std::cout <<"Graph deleted!" << std::endl;
}
void Graph::display_left_right(){
Node* traverser = head;
while(traverser != NULL){
std::cout << traverser->data << " ";
traverser = traverser->next;
}
std::cout << std::endl;
}
void Graph::display_right_left(){
Node* traverser = tail;
while(traverser != NULL){
std::cout << traverser->data << " ";
traverser = traverser->previous;
}
std::cout << std::endl;
}
void Graph::append(int new_data){
Node* add = new Node;
add->data = new_data;
add->next = NULL;
add->previous = tail;
tail->next = add;
tail = add;
num_elt++;
}
void Graph::append_at_pos(int pos, int new_data){
if(pos > num_elt+1 || pos<=0){std::cout << "Wrong position!" << std::endl; return;}
if(pos==1){
prepend(new_data);
return;
}
if(pos==num_elt+1){
append(new_data);
return;
}
Node* add = new Node;
Node* traverser = head;
add->data = new_data;
for(int i=0; i<pos-2; i++){
traverser = traverser->next;
}
add->next = traverser->next;
add->previous = traverser;
traverser->next->previous = add;
traverser->next = add;
}
void Graph::prepend(int new_data){
Node* add = new Node;
add->next = head;
add->previous = NULL;
add->data = new_data;
head->previous = add;
head = add;
num_elt++;
}
int Graph::get_num_elt(){
return num_elt;
}
int Graph::get_data_at_pos(int pos){
Node* traverser = head;
if(pos <=0 || pos> num_elt){std::cout << "Wrong position!" << std::endl; return 0;}
for(int i=0; i<pos-1; i++){
traverser = traverser->next;
}
return traverser->data;
}
main(){
Graph a(2);
a.append(3);
a.append(4);
a.prepend(1);
a.display_left_right();
a.append_at_pos(1,6);
a.display_left_right();
std::cout << "data at 1: " << a.get_data_at_pos(1) << std::endl;
}
When you say "create multiple linked lists," I think you mean creating nodes to a linked list, which you have 2 append functions. I think the reason you have these 2 functions is because you do not know where to start traversing your linked list. For this reason, I think in your main function you should declare the head of the linked list, a single node that is the start. Set it's data and next to null, and then pass the head value into a function so it can start traversing from the head. Here is a generic append function that adds a node on the end, where the parameters are a reference to the head node, and the value for the new node:
void append(Node ** head, int new_data)
{
Node * select_node = * head;
// select node is set to the head node, and will traverse until it is at the end
while (select_node -> next != NULL)
{
// select node is set to the next node until it is NULL (end of linked list)
select_node = select_node -> next;
}
// now that select node is the last node, we need to make it's next value a node
// and that node should be a new node (allocated in heap) with the value of the input value
//and the next value be NULL (because it's the end of the linked list)
Node * next_node = new Node();
next_node -> data = new_data;
next_node -> next = NULL;
select_node -> next = next_node;
}

Explain left child right sibling traversal

I have a left child right sibling as below:
10
* |
* 2 -> 3 -> 4 -> 5
* | |
* 6 7 -> 8 -> 9 */
I want to traverse from root to the last node, the traversal function is as below:
void traverseTree(Node * root)
{
if (root == NULL)
return;
while (root)
{
cout << " " << root->data;
if (root->child)
traverseTree(root->child);
root = root->next;
}
}
As I understood, if the node has a child, then the pointer points to its child, otherwise points to the sibling (next). In this case, when the pointer points to element 6, it will go to the root->next element (which is NULL). However, the function can still be able to print the remaining element (5,7,8,9). Can any one help me explain how traverseTree works?
Here's the code to recreate the tree:
// CPP program to create a tree with left child
// right sibling representation.
#include<bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *next;
struct Node *child;
};
// Creating new Node
Node* newNode(int data)
{
Node *newNode = new Node;
newNode->next = newNode->child = NULL;
newNode->data = data;
return newNode;
}
// Adds a sibling to a list with starting with n
Node *addSibling(Node *n, int data)
{
if (n == NULL)
return NULL;
while (n->next)
n = n->next;
return (n->next = newNode(data));
}
// Add child Node to a Node
Node *addChild(Node * n, int data)
{
if (n == NULL)
return NULL;
// Check if child list is not empty.
if (n->child)
return addSibling(n->child, data);
else
return (n->child = newNode(data));
}
// Traverses tree in level order
void traverseTree(Node * root)
{
if (root == NULL)
return;
while (root)
{
cout << " " << root->data;
if (root->child)
traverseTree(root->child);
root = root->next;
}
}
//Driver code
int main()
{
Node *root = newNode(10);
Node *n1 = addChild(root, 2);
Node *n2 = addChild(root, 3);
Node *n3 = addChild(root, 4);
Node *n4 = addChild(n3, 6);
Node *n5 = addChild(root, 5);
Node *n6 = addChild(n5, 7);
Node *n7 = addChild(n5, 8);
Node *n8 = addChild(n5, 9);
traverseTree(root);
return 0;
}
After executing traverseTree(root->child) the control flow will continue from the next line. You're not returning from the function, just calling another function from within this function.
void traverseTree(Node * root)
{
if (root == NULL)
return;
while (root)
{
cout << " " << root->data;
if (root->child)
traverseTree(root->child); // First, if child exists, traverse child. No return statement following here.
root = root->next; // Next, traverse sibling
}
}
If you still have doubts it would do you good to read about the program flow when calling a function.
Update(completely irrelevant to the question): As requested by OP, solution using stack:
void traverseTree(Node * root)
{
if (root == NULL)
return;
stack<Node*> s;
s.push(root);
while (!s.empty())
{
Node* top = s.top();
cout << " " << top->data;
s.pop();
if (top->next) s.push(top->next);
if (top->child) s.push(top->child);
}
}

How to keep track of layers when traversing a binary tree?

If I need to print out each elements of a binary tree constructed with the struct below. How could I keep track of which layer of elements I am printing?
struct for a binary tree node
For example:
any binary tree
Expected output:
layer 0: 12
layer -1: 28 19
layer -2: 94 32
layer -3: 65 18 72
Solution using queue based on GeeksForGeeks
#include <iostream>
#include <queue>
using namespace std;
// A Binary Tree Node
struct node
{
struct node *left;
int data;
struct node *right;
};
// Iterative method to do level order traversal
// line by line
void printLevelOrder(node *root)
{
// Base Case
if (root == NULL)
return;
// Create an empty queue for level order tarversal
queue<node *> q;
// Enqueue Root and initialize height
q.push(root);
int i = 0;
while (q.empty() == false)
{
cout << "layer " << i << ": ";
// nodeCount (queue size) indicates number
// of nodes at current lelvel.
int nodeCount = q.size();
// Dequeue all nodes of current level and
// Enqueue all nodes of next level
while (nodeCount > 0)
{
node *node = q.front();
cout << node->data << " ";
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
nodeCount--;
}
cout << endl;
--i;
}
}
// Utility function to create a new tree node
node *newNode(int data)
{
node *temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
// Driver program to test above functions
int main()
{
// Create binary tree
node *root = newNode(12);
root->left = newNode(28);
root->right = newNode(19);
root->left->left = newNode(94);
root->left->left->left = newNode(65);
root->left->left->right = newNode(18);
root->right->left = newNode(32);
root->right->left->right = newNode(72);
printLevelOrder(root);
return 0;
}
Solution using recursive function and helper function based on CrazyForCode:
#include <iostream>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
void printLevel(node *, int);
int height(struct node *node);
/* Function to print level order traversal a tree*/
void printLevelOrder(struct node *root)
{
int h = height(root);
int i;
for (i = 1; i <= h; i++){
printf("layer %d: ",i*-1+1);
printLevel(root, i);
cout << endl;
}
}
/* Print nodes at a given level */
void printLevel(struct node *root, int level)
{
if (root == NULL)
return;
if (level == 1)
{
printf("%d ", root->data);
}
else if (level > 1)
{
printLevel(root->left, level - 1);
printLevel(root->right, level - 1);
}
}
/* Compute the "height" of a tree */
int height(struct node *node)
{
if (node == NULL)
return 0;
else
{
int lheight = height(node->left);
int rheight = height(node->right);
if (lheight > rheight)
return (lheight + 1);
else
return (rheight + 1);
}
}
node *newNode(int data)
{
node *temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
int main()
{
// Create binary tree
node *root = newNode(12);
root->left = newNode(28);
root->right = newNode(19);
root->left->left = newNode(94);
root->left->left->left = newNode(65);
root->left->left->right = newNode(18);
root->right->left = newNode(32);
root->right->left->right = newNode(72);
printLevelOrder(root);
return 0;
}

C++ LinkedList Swap Nodes [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
debug help - swap 2 nodes of double link list
I'm trying to write an algorithm that can swap two nodes in a singly linkedlist in C++. Here's what i have so far:
void swap(ListNode *node1, ListNode *node2)
{
ListNode *prev1 = head;
ListNode *prev2 = head;
//Search previous node for node1:
while(prev1->next!=node1 || prev1 != node1)
prev1 = prev1->getNext();
//Search previous node for node2:
while(prev2->next!=node2 || prev2 != node2)
prev2 = prev2->getNext();
if(node1->next==node2)
{ //This means node1 == prev2?
tail = node1;
node1->next = NULL;
head = node2;
node2->next = node1;
}
else if(node2->next==node1)
{ // node2 == prev1
tail = node2;
node2->next = NULL;
head = node1;
node1->next = node2;
}
if(node1->next == NULL)
{ //node1 is last
node1->next = node2->next;
tail = node2;
node2->next = NULL;
prev1->next = node2;
prev2->next = node1;
}
}
But I realized the number of different cases I can get, like if there LL was only two elements, or if they gave us node 2 before node 1, etc etc. I realized it can't be this complicated and ugly. So how do you write an algorithm to swap two nodes?
Doing the whole task in one routine is wrong. Break it down into two simpler problems:
1) Remove a node from a list, including all special cases.
2) Insert a node in a list, including all special cases.
From there, the overall problem is easy, but since this is obviously homework, you're on your own.
This seems cleaner to me:
//Maybe this function should go instide ListNode itself...
ListNode *prev(ListNode *node) {
if (node == head)
return null;
ListNode *search = head;
while (search != node)
search = search->getNext();
return search;
}
void swap(ListNode *node1, ListNode *node2)
{
ListNode *prev1 = prev(node1),
*prev2 = prev(node2),
*next1 = node1->getNext(),
*next2 = node2->getNext();
if (prev1)
prev1->next = node2;
else
head = node2;
if (prev2)
prev2->next = node1;
else
head = node1;
if (!next1)
tail = node2;
else if (!next2)
tail = node1;
node1->next = next2;
node2->next = next1;
}
Haven't tested this ofc...
#include <stdio.h>
struct llist {
struct llist *next;
char *payload;
} llists[]=
{{ llists+1, "one"}
,{ llists+2, "two"}
,{ llists+3, "three"}
,{ llists+4, "four"}
,{ llists+5, "five"}
,{ llists+6, "six"}
,{ llists+7, "seven"}
,{ llists+8, "eight"}
,{ llists+9, "nine"}
,{ NULL, "ten"}
};
struct llist *head = llists;
void llistswap(struct llist *one, struct llist * two)
{
struct llist **hnd, **h1, **h2;
h1 = h2 = NULL;
for (hnd= &head; *hnd; hnd = &(*hnd)->next) {
struct llist *tmp;
if ((*hnd) == one) h1 = hnd;
else if ((*hnd) == two) h2 = hnd;
else continue;
if (!h1 || !h2) continue;
tmp = *h1;
*h1 = *h2;
*h2 = tmp;
tmp = (*h1)->next;
(*h1)->next = (*h2)->next;
(*h2)->next = tmp;
break;
}
}
void do_print(struct llist *lp)
{
for ( ; lp; lp = lp->next) {
printf("%s%c", lp->payload, (lp->next) ?',' : '\n' );
}
}
int main(void)
{
do_print (head);
llistswap ( llists+4, llists+7);
do_print (head);
return 0;
}