I was solving a problem in which given a linked list of characters , we have to move the vowels to the beginning such that both vowels and consonants are in chronological order. That is in the order in which they appear in original list.
Input : S->T->A->C->K->O->V->E->R->F->L->O->W
Output : A->O->E->O->S->T->C->K->V->R->F->L->W
I did it by traversing through the list once and created two lists called vowels and consonants and later merged them.
Can it be done without creating extra lists ? I mean in-place maybe using pointer manipulation?
Remember the beginning of the list. When you meet a vowel, move it to the beginning of the list; the vowel becomes the new beginning that you remember.
1. Traverse the list
2. When you encounter a vowel, check with head if its smaller or greater
3. If smaller, re-place new vowel before head, else move head and check again
4. In the end relocate head to first
temp = head;
while(current.next != null) {
if(current.isVowel()) {
if(head.isVowel()) {
//check the precedence
//Re-place the current with temp
}
else {
//Re-place current in front of head
}
}
current = current.next;
}
This is an abstract understanding. Implement it properly.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
struct list {
struct list *next;
int ch;
};
#define IS_VOWEL(p) strchr("aeiouy", tolower(p->ch))
struct list *shuffle ( struct list *lst )
{
struct list *new=NULL, **dst, **src;
dst = &new;
for (src = &lst; *src; ) {
struct list *this;
this= *src;
if (!IS_VOWEL(this)) { src= &(*src)->next; continue; }
*src = this->next;
this->next = *dst;
*dst = this;
dst = & (*dst)->next;
}
*dst = lst;
return new;
}
int main (void)
{
struct list arr[] = { {arr+1, 'S'} , {arr+2, 'T'} , {arr+3, 'A'}
, {arr+4, 'C'} , {arr+5, 'K'} , {arr+6, 'O'}
, {arr+7, 'V'} , {arr+8, 'E'} , {arr+9, 'R'}
, {arr+10, 'F'} , {arr+11, 'L'} , {arr+12, 'O'} , {NULL, 'W'} };
struct list *result;
result = shuffle (arr);
for ( ; result; result = result->next ) {
printf( "-> %c" , result->ch );
}
printf( "\n" );
return 0;
}
OUTPUT:
-> A-> O-> E-> O-> S-> T-> C-> K-> V-> R-> F-> L-> W
You can quite easily modify pointers to create two independent lists without actually having to duplicate any of the nodes, which is what I assume you mean when you say you want to avoid creating new lists. Only the pointers in the original nodes are modified.
First let's create the structures for the list:
#include <stdio.h>
#include <stdlib.h>
// Structure for singly linked list.
typedef struct sNode {
char ch;
struct sNode *next;
} tNode;
And next we provide two utility functions, the first to append a character to the list:
// Append to list, not very efficient but debug code anyway.
static tNode *append (tNode *head, char ch) {
// Allocate new node and populate it.
tNode *next = malloc (sizeof (tNode));
if (next == NULL) {
puts ("Out of memory");
exit (1);
}
next->ch = ch;
next->next = NULL;
// First in list, just return it.
if (head == NULL)
return next;
// Else get last, adjust pointer and return head.
tNode *this = head;
while (this->next != NULL)
this = this->next;
this->next = next;
return head;
}
And the second to dump a list for debugging purposes:
// Debug code to dump a list.
static void dump (tNode *this) {
if (this == NULL)
return;
printf ("(%08x)%c", this, this->ch);
while ((this = this->next) != NULL)
printf (" -> (%08x)%c", this, this->ch);
putchar ('\n');
}
Beyond that, we need an easy way to tell if a node is a vowel or not. For our purposes, we'll only use uppercase letters:
// Check for vowel (uppercase only here).
static int isVowel (tNode *this) {
char ch = this->ch;
return (ch == 'A') || (ch == 'E') || (ch == 'I')
|| (ch == 'O') || (ch == 'U');
}
Now this is the important bit, the bit that turns the single list into two distinct lists (one vowel, one consonant). Which list is which type depends on what the first entry in the list is.
What is basically does is to create a sub-list out of all the common nodes at the start of the list ("ST" in this case), another sub-list of the next non-matching type ("A"), and then starts processing the remaining nodes one by one, starting with "C".
As each subsequent node is examined, the pointers are adjusted to add it to either the first or second list (again, without actually creating new nodes). Once we reach the NULL at then end of the list, we then decide whether to append the second list to the first, or vice versa (vowels have to come first).
The code for all this pointer manipulation is shown below:
// Meat of the solution, reorganise the list.
static tNode *regroup (tNode *this) {
// No reorg on empty list.
if (this == NULL)
return this;
// Find first/last of type 1 (matches head), first of type 2.
tNode *firstTyp1 = this, *firstTyp2 = this, *lastTyp1 = this, *lastTyp2;
while ((firstTyp2 != NULL) && (isVowel (firstTyp1) == isVowel (firstTyp2 ))) {
lastTyp1 = firstTyp2;
firstTyp2 = firstTyp2->next;
}
// No type 2 means only one type, return list as is.
if (firstTyp2 == NULL)
return firstTyp1;
// Type 2 list has one entry, next node after that is for checking.
lastTyp2 = firstTyp2;
this = firstTyp2->next;
//dump (firstTyp1);
//dump (firstTyp2);
//putchar ('\n');
// Process nodes until list is exhausted.
while (this != NULL) {
// Adjust pointers to add to correct list.
if (isVowel (this) == isVowel (lastTyp1)) {
lastTyp2->next = this->next;
lastTyp1->next = this;
lastTyp1 = this;
} else {
lastTyp1->next = this->next;
lastTyp2->next = this;
lastTyp2 = this;
}
// Advance to next node.
this = this->next;
//dump (firstTyp1);
//dump (firstTyp2);
//putchar ('\n');
}
// Attach last of one list to first of the other,
// depending on which is the vowel list.
if (isVowel (firstTyp1)) {
lastTyp1->next = firstTyp2;
return firstTyp1;
}
lastTyp2->next = firstTyp1;
return firstTyp2;
}
And, finally, no complex program would be complete without a test harness of some description, so here it is, something to create and dump the list in its initial form, then reorganise it and dump the result:
int main (void) {
char *str = "STACKOVERFLOW";
tNode *list = NULL;
while (*str != '\0')
list = append (list, *(str++));
dump (list);
puts("");
list = regroup (list);
dump (list);
return 0;
}
Upon entering, compiling and running all that code, the results are as expected:
(09c03008)S -> (09c03018)T -> (09c03028)A -> (09c03038)C ->
(09c03048)K -> (09c03058)O -> (09c03068)V -> (09c03078)E ->
(09c03088)R -> (09c03098)F -> (09c030a8)L -> (09c030b8)O ->
(09c030c8)W
(09c03028)A -> (09c03058)O -> (09c03078)E -> (09c030b8)O ->
(09c03008)S -> (09c03018)T -> (09c03038)C -> (09c03048)K ->
(09c03068)V -> (09c03088)R -> (09c03098)F -> (09c030a8)L ->
(09c030c8)W
In case that's hard to read, I'll get rid of the pointers and just list the characters in order:
S -> T -> A -> C -> K -> O -> V -> E -> R -> F -> L -> O -> W
A -> O -> E -> O -> S -> T -> C -> K -> V -> R -> F -> L -> W
Related
I am trying to find the distance of a node from the root of a binary tree but I am getting right answer up to only 3 branches only. like for the node(4) I am getting 3 and for the node (9) and node(10) I am getting 3
#include<bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
node(int val)
{
data = val;
left = NULL;
right = NULL;
}
};
int find_node(node* root,int n)
{
static int length=1;
if (root== NULL)
{
return 0;
}
if (root->data==n)
{
return length;
}
length=length+(find_node(root->left,n)||find_node(root->right,n));
// find_node(root->left,n);
// find_node(root->right,n);
return length;
}
int main ()
{
struct node* root = new node(1);
root->left = new node(2);
root->right = new node(3);
root->left->left = new node(4);
root->left->right = new node(5);
root->right->left = new node(6);
root->right->right = new node(7);
root->right->right->right = new node(9);
root->right->right->right->right = new node(10);
cout <<find_node(root,10);
return 0;}
When your code reaches the first leaf node (with data 4), the following assignment will assign 1:
length=length+(find_node(root->left,n)||find_node(root->right,n));
Because the expression resolves to 1+(0||0), i.e. 1. And so 1 is returned.
The caller (at the node with data 2) will thus receive this 1, and so the above statement will yield 2, since it resolves to 1+(1||......), which is 2 -- the second operand of || is not evaluated.
The parent caller (at the node with data 1), will thus receive this 2. The assignment there resolves to 1+(2||.....), which is again 2 -- realise that || is a logical operator, so it can only evaluate to a boolean value (i.e. 0 or 1).
The issues
In summmary:
You should not use || as it can only evaluate to 0 or 1, losing the actual value from recursion that you need.
You should not use a static variable. For one, it would not reset if you would make a second call to this function from the main program code. Instead, every recursive call should just "mind its own business" and return the depth of n from the given root. The caller should add 1 to that if n was found.
Correction
int find_node(node* root, int n)
{
if (root == NULL)
{
return 0;
}
if (root->data == n)
{
return 1;
}
int length = find_node(root->left, n);
if (!length)
{
length = find_node(root->right, n);
}
if (!length)
{
return 0;
}
return 1 + length;
}
I've been trying to figure out how to prevent a user from entering a duplicate value and honestly I am struggling so much for an answer that's probably really simple once I see it, but I can't. The function is below along with the struct node. I would really appreciate it if someone could help me out here.
struct node {
int data = -1;
node * current;
node * next;
};
node * start = NULL;
```
void addNode(struct node & n) {
if (n.data == -1) {
cout << "List not created yet." << endl;
} else {
node * temp;
node * temp2;
temp = new node;
cout << "What number would you like to enter:" << endl;
cin >> temp -> data;
cout << endl;
int value;
value = temp -> data;
temp = start;
while (temp != NULL) {
if (temp -> data == value) {
cout << "Duplicate Number!" << endl;
} else {
temp = temp -> next;
}
temp = temp -> next;
}
if (start == NULL) {
start = temp;
} else {
temp2 = start;
while (temp2 -> next != NULL) {
temp2 = temp2 -> next;
}
temp2 -> next = temp;
}
}
}
Here are some remarks on your code:
Don't make start a global variable. Instead make it local to main and pass it as argument to the addNode function
Use nullptr instead of NULL
Don't ask for the user's input inside the addNode function. By the principle of separation of concern, keep the I/O aspects outside that function.
Instead pass the value as argument to addNode
You should treat a node differently when it has the value -1. An empty list is not a list with one node that has the value -1. An empty list is a null pointer.
Even if a list is empty, it should be possible to add the first node with this function
Use more descriptive variable names. n for a node instance is not very clear. Also temp and temp2 are not very clear. One of the two is the newly created node, so it could be named newNode.
After you have created the new node, and assigned its reference to temp, you assign a new value to temp with temp = start, and so you've lost (and leaked) the newly created node.
In your loop, you'll execute temp = temp->next twice when the value does not match. This should of course only be done once per iteration.
Even when your code finds a duplicate and outputs a message, it still continues the process. Instead you should stop the process, and not create the node (or if you already did: dispose it with delete).
It is a pity that you need to traverse the list again from the start to find the last node and append the new node there. You should be able to do that in the first loop where you look for the duplicate.
Here is a correction:
bool addNode(node* &start, int value) {
node * current = start;
if (start != nullptr) {
while (current->data != value && current->next != nullptr) {
current = current->next;
}
if (current->data == value) {
return false; // duplicate!
}
}
node* newNode = new node;
newNode->data = value;
if (start != nullptr) {
current->next = newNode;
} else {
start = newNode;
}
return true;
}
Note that this function returns a boolean: if true then the node was inserted. The other case means there was a duplicate.
Your main function could look like this:
int main() {
// define start as local variable
node * start = nullptr; // Use nullptr instead of NULL
while (true) {
int value;
// Don't do I/O together with list-logic
cout << "What number would you like to enter:" << endl;
cin >> value;
cout << endl;
if (value == -1) break;
if (!addNode(start, value)) {
cout << "Duplicate Number!" << endl;
}
}
}
I am currently trying to formulate a mergeSort mechanism for a singly linked list. Through research and finding consistent ideas about A) a merge sort being the best way to sort a singly linked list, and B) that these are the key components for performing such an operation, I have arrived at this following code. It almost works exactly as intended, but will only return all of the integers larger than the last inputted number. For example, inputting 7, 6, 5, 4, 3, 2, 1 will return 1, 2, 3, 4, 5, 6, 7, but inputting 1, 2, 3, 4, 5 will only return 5. I've used random input orders so it's not a problem localised to just inputting the numbers in reverse order, but literally any order. If a number is smaller than the final number, it gets removed from the list in the sort process. I cannot locate the cause for this at all. My original problem was caused by an errant while loop that was stopping the iterations after one go, so once I removed that the merge sort was working, but for this problem I have just described.
Any and all advice or suggestions are more than welcome, and thanks for any input you have. My knowledge of linked lists and recursion isn't the greatest, so I really welcome all input/constructive criticism here.
public Node mergeSort(Node head) {
if (head == null || head.getNext() == null) return head;
Node midpoint = findMidpoint(head);
Node rightliststart = midpoint.getNext();
midpoint.setNext(null);
Node rightlist = mergeSort(rightliststart);
Node sorted = sort(leftlist, rightlist);
return sorted;
}
public Node findMidpoint(Node head) {
if (head == null) return head;
Node slowpointer = head;
Node fastpointer = slowpointer.getNext();
while (fastpointer != null) {
fastpointer = fastpointer.getNext();
if (fastpointer != null) {
slowpointer = slowpointer.getNext();
fastpointer = fastpointer.getNext();
}
}
return slowpointer;
}
public Node sort(Node one, Node two) {
Node temp = null;
if (one == null) return two;
if (two == null) return one;
if (one.getData() <= two.getData()) {
temp = one;
temp.setNext(sort(one.getNext(), two));
} else {
temp = two;
temp.setNext(sort(one, two.getNext()));
}
return temp;
}
Example merge code. This shows how the dummy node is used to simplify the code (avoids special case to update head on first node merged).
// merge two already sorted lists
static Node merge(Node list0, Node list1) {
if(list0 == null)
return list1;
if(list1 == null)
return list0;
Node temp = new Node(); // dummy node
Node dest = temp;
while(true){
if(list0.data <= list1.data){
dest.next = list0;
dest = list0;
list0 = list0.next;
if(list0 == null){
dest.next = list1;
break;
}
} else {
dest.next = list1;
dest = list1;
list1 = list1.next;
if(list1 == null){
dest.next = list0;
break;
}
}
}
return temp.next;
}
Example top down merge sort code. It scans the list one time to get the size of the list to avoid double scanning (fast, slow), only scanning n/2 nodes for each recursive split.
// return size of list
static int size(Node head) {
int i = 0;
while(head != null){
head = head.next;
i++;
}
return i;
}
// advance to node n
static Node advance(Node head, int n) {
while(0 < n--)
head = head.next;
return head;
}
// top down merge sort for single link list entry function
static Node sorttd(Node head) {
int n = size(head);
if(n < 2)
return head;
head = sorttdr(head, n);
return head;
}
// top down merge sort for single link list recursive function
static Node sorttdr(Node head, int n) {
if(n < 2)
return head;
int n2 = (n/2);
Node node = advance(head, n2-1);
Node next = node.next;
node.next = null;
head = sorttdr(head, n2);
next = sorttdr(next, n-n2);
head = merge(head, next);
return head;
}
Example bottom up merge sort code. It uses a small (32) array of lists, where array[i] is a list with 0 (empty slot) or 2^i nodes. array[{0 1 2 3 4 ...}] = sorted sub-lists with 0 or {1 2 4 8 16 ...} nodes. Nodes are merged into the array one at a time. A working list is created via a sequence of merge steps with a caller's list node and the leading non-empty slots in the array. The size of the working list doubles with each merge step. After each non-empty slot is used to merge into the working list, that slot is set to empty. After each sequence of merge steps is done, the first empty slot after the leading non-empty slots is set to the working list. A prior slots will now be empty. Once all nodes are merged into the array, the array is merged into a single sorted list. On a large list that doesn't fit in cache, and with randomly scattered nodes, there will be a lot of cache misses for each node accessed, in which case bottom up merge sort is about 30% faster than top down.
// bottom up merge sort for single link list
static Node sortbu(Node head) {
final int NUMLIST = 32;
Node[] alist = new Node[NUMLIST];
Node node;
Node next;
int i;
// if < 2 nodes, return
if(head == null || head.next == null)
return null;
node = head;
// merge node into array
while(node != null){
next = node.next;
node.next = null;
for(i = 0; (i < NUMLIST) && (alist[i] != null); i++){
node = merge(alist[i], node);
alist[i] = null;
}
if(i == NUMLIST) // don't go past end of array
i--;
alist[i] = node;
node = next;
}
// node == null
// merge array into single list
for(i = 0; i < NUMLIST; i++)
node = merge(alist[i], node);
return node;
}
I have a module A with objects linked from objects in another module B. In a view of A, I have a layout DXL column which lists all those linked B objects:
// DXL generated by DOORS traceability wizard on 02 May 2016.
// Wizard version 2.0, DOORS version 9.2.0.5
pragma runLim, 0
string limitModules[1] = {"40fedbf2697f0e24-00003921"}
void showIter(Object o, string linkModName, int depth, string build, string iter) {
Link l
Object othero
for l in all(o<-linkModName) do { // ****
otherVersion = sourceVersion l
otherMod = module(otherVersion)
if (null otherMod || isDeleted otherMod) continue
if (!equal(getItem otherMod, (itemFromID limitModules[depth-1]))) continue
othero = source l
if (null othero) {
load(otherVersion,false)
}
othero = source l
if (null othero) continue
if (isDeleted othero) continue
doneOne = true
if (depth == 1) {
disp = ""
obuild = probeRichAttr_(othero,"Build", false)
oiter = probeRichAttr_(othero,"Iteration (planned)", false)
string ocat = othero."Category"
if (obuild == build && oiter == iter) {
s = "(B" obuild "." oiter " - " ocat[0] ") " (identifier othero)
disp = disp s
s = probeRichAttr_(othero,"Object Text", false)
disp = disp " " s
displayRich("\\pard " disp)
}
}
}
}
void showIn(Object o, int depth) {
Link l
LinkRef lr
ModName_ otherMod = null
Module linkMod = null
ModuleVersion otherVersion = null
Object othero
string disp = null
string s = null
string plain, plainDisp
int plainTextLen
int count
bool doneOne = false
Item linkModItem = itemFromID("40fedbf2697f0e24-000039a3")
if (null linkModItem) {
displayRich("\\pard " "<<Link module not found>>")
} else if (type(linkModItem) != "Link") {
displayRich("\\pard " "<<Invalid link module index for this database>>")
} else {
string linkModName = fullName(linkModItem)
for lr in all(o<-linkModName) do {
otherMod = module (sourceVersion lr)
if (!null otherMod) {
if ((!isDeleted otherMod) && (null data(sourceVersion lr))) {
if (!equal(getItem otherMod, (itemFromID limitModules[depth-1]))) continue
load((sourceVersion lr),false)
}
}
}
//showIter(o, linkModName, depth, "1", "")
//showIter(o, linkModName, depth, "2", "")
showIter(o, linkModName, depth, "3", "3")
}
}
showIn(obj,1)
This script lists the linked objects in numerical order by object ID/key:
B object with ID# 3
B object with ID# 8
B object with ID# 21
B object with ID# 24
Yet in module B, without any sorting active, the objects are visible in insertion order, like this (i.e. according to where I made the insertion):
B object with ID# 24
B object with ID# 8
B object with ID# 21
B object with ID# 3
Is there a way to loop over B objects in insertion order, i.e. in order that they are displayed in B view when no sorting is active?
A "natural" order as you define it, is the order in which the source objects appear in the source module. This does not cover the case where source objects come from different modules, but this is just another problem..
A loop “.. for l in ....” has by definition no order defined, so in case you need one, you have to define your own order. In DXL, this is usually done by Skip lists.
You can create a skip list with the key being of type integer or string and the value being of type Link.
Then for each link, you can somehow calculate the correct order and add an entry where the key represents the order to the Skip list. A later loop „for l in skip“ will process the skip list in the order of the keys.
In your case, you can calculate the key by using a loop over all source objects, with the aid of a temporary skip list, like
int order = 0
Skip skOrderOfObject = create()
Object o
for o in entire (... source module...) do {
order ++
int absno = o."Absolute Number"
put (skOrderOfObject, order, absno)
}
Then to process each source object in your DXL column, you can do a
Skip skMySortedLinks = create()
...
for l in... {
Object oSource = source l
int iOrderOfThisObject
int absnoOfSource = oSource."Absolute Number"
find (skOrderOfObject, absnoOfSource, iOrderOfThisObject);
put (skMySortedLinks, iOrderOfThisObject, l)
}
and finally
Link l
for l in skMySortedLinks do {
... print whatever you want to print...
}
Given a one-way linked list, I want to update each element's value with the value of the previous node, for instance, if I have list 1 -> 2 -> 3 -> null, so after the run it'll be new_value -> 1 -> 2 -> null where new_value is given in each iteration.
What I've tried to do (pseudo-code) is:
list_head = head
for i = length-1 to 0:
current = head
do i times:
prev_data = current.data
current = current.next
current.data = prev_data
It doesn't seem to work properly, though...what am I missing? is there another way to do it?
EDIT: assume that new_value is already assigned to head at this point
Thanks in advance
You can implement list with arrays as well. Here is an implementation in javascript. Hope it helps.
var array = [1,2,3]; // list with array
var newValue = 4;
function push(value){
array.pop(); // to remove the last element
array.unshift(value); // to add the new element
console.log(array);
}
push(newValue);
I do not see a reason why you would need to use two loops - I suspect your issue has to do with the "do i times". Instead I would suggest to simply push the values through the list until the tail has been reached (and the last value is dropped). The following is an implementation of that idea using a very simple Node class:
function Node(data,next=null) {
this.data = data;
this.next = next;
this.toString = function() {
if(this.next) return this.data + " -> " + this.next.toString();
else return this.data + " -> null";
}
}
var head = new Node(1,new Node(2,new Node(3)));
console.log(head.toString())
var new_value = 0;
var curr = head;
do{
var old_value = curr.data;
curr.data = new_value;
new_value = old_value;
curr = curr.next;
} while(curr)
console.log(head.toString());