I am new to Linked List. I am trying to write a CopyList() code that can copy a linked list to a new list. There's a unique version using recursive and I don't really understand:
struct node
{
int data;
struct node *next;
};
struct node* CopyList(struct node* head) {
struct node* current = head;
if (current == NULL) return NULL;
else {
struct node* newList = malloc(sizeof(struct node));
newList->data = current->data;
newList->next = CopyList(current->next); // recur for the rest
return(newList);
}
}
My trouble of understanding is the line newList->next = CopyList(current->next);
So how does this work for copying and why?
Lets take an example. If you simply put the current->next in newList->next
i.e
newList->next = current->next. Then it will point to the next node of old list only. Not to the next node of new list.
So to make a different list (Copy list). You separately have to make a new node and return it to point to next of previous node.
This is the magical recursive statement.
newList->next = CopyList(current->next);
For each recursive step, this will delegate the task of creating remaining linked list, to the next recursive call.
For example: List is getting created from right to left.
CopyList (1->2->3->4->5)
|
|---------1-> CopyList (2->3->4->5)
|
|---------2-> CopyList (3->4->5)
|
|---------3-> CopyList (4->5)
|
|---------4-> CopyList (5)
|
|---------5-> CopyList (NULL)
Returns 5
Returns 4->5->NULL
Returns 3->4->5->NULL
Returns 2->3->4->5->NULL
Returns 1->2->3->4->5->NULL
As per wiki
A simple base case (or cases)—a terminating scenario that does not use recursion to produce an answer.
A set of rules that reduce all other cases toward the base case.
In your case, terminating scenario is if list reaches the end, just return null and a new node is created at every step that leads the list to the base scenario.
This is the recursion step. The previous two commands create a new node and copy the head of the current list to that object. Now, instead of iterating (looping) through the rest of the list, we call CopyList to copy the remainder of the list -- everything except the head node that we just copied.
CopyList returns a copy of that remainder, which we simply append to the copy of the head node ... and we're done.
Related
I am currently solving the problem of creating a singly linked list using pointers in Free Pascal. The task:
Write a program that reads integers from the standard input stream until the "end of file" situation occurs, after which it prints all the entered numbers TWICE in the order in which they were entered. The quantity of numbers is not known in advance, explicit restrictions on this number are prohibited.
In my program, the list is built in the wrong order. How to build the correct sequence?
program InputStreamNumbers;
type
itemptr = ^item;
item = record
data: Integer;
next: itemptr;
end;
var
first, tmp: itemptr;
n: Integer;
begin
first := nil; { make the list properly empty! }
while not SeekEof do { number reading loop }
begin
read(n);
new(tmp); { created }
tmp^.data := n; { fill out}
tmp^.next := first;
first := tmp; { include in the list}
end;
tmp := first; { go through the list from beginning to end }
while tmp <> nil do
begin
writeln(tmp^.data);
tmp := tmp^.next; { move to the next element}
end;
end.
When you add nodes to the list, you create a new node named tmp and assign its data. That's correct. But there is an error in how you add new items to the list. The error is in
tmp^.next := first; // this creates the backwards linkage
first := tmp;
If you can (assuming it's not against your task), add one variable more
last: itemptr;
which, as the name says, refers to the last item in the list.
The purpose is to have direct access to the end of the list, to make it easier to add items. Otherwise you would need to traverse the list from the beginning until you find the last item ( who's item.next is nil).
The list should end up like this:
first last
| |
v v
item.next -> item.next -> item.next -> item.next = nil
.data .data .data .data
I leave the implementation for you to do. But if it helps, initially first and last are nil. After one item is created, both first and last point to that one item. After a second item is created, first still points to the first created, but last points to the second ... and so on.
The problem statement is:
Given a Binary Tree, convert this binary tree to a Doubly Linked List.
A Binary Tree (BT) is a data structure in which each node has at most two children.
A Doubly Linked List contains a previous pointer, along with the next pointer and data.
The order of nodes in Doubly Linked List must be the same as Inorder of the given Binary Tree.
The doubly linked list should be returned by taking the next pointer as right and the previous pointer as left.
You need to return the head of the Doubly Linked List.
For example:
4
/ \
2 5
/ \
1 3
The doubly linked list would be: 1 2 3 4 5
My code is:
class BinaryTreeNode
{
public :
T data;
BinaryTreeNode<T> *left;
BinaryTreeNode<T> *right;
BinaryTreeNode(T data) {
this -> data = data;
left = NULL;
right = NULL;
}
};
void inorder(BinaryTreeNode<int>* root,BinaryTreeNode<int>* &prev,BinaryTreeNode<int>* &nroot){
if(!root) return;
inorder(root->left,prev,nroot);
if(prev == NULL) nroot=root;
else{
root->left = prev;
prev->right=root;
}
prev=root;
inorder(root->right,prev,nroot);
}
BinaryTreeNode<int>* BTtoDLL(BinaryTreeNode<int>* root) {
BinaryTreeNode<int>* prev=NULL;
BinaryTreeNode<int>* nroot=NULL;
inorder(root,prev,nroot);
return nroot;
}
I have doubt regarding root.
The root pointer works with passing by value and does not works when it is passed by reference.
When root is passed by reference, it does not work.
void inorder(BinaryTreeNode<int>*& root,BinaryTreeNode<int>*& prev,BinaryTreeNode<int>* &nroot){
if(!root) return;
inorder(root->left,prev,nroot);
if(prev == NULL) nroot=root;
else{
root->left = prev;
prev->right=root;
}
prev=root;
inorder(root->right,prev,nroot);
}
How can I know which variable should be passed by reference and which variable should by passed by value with regard to pointers?
At first glance, one problem is the API of inorder itself. You are assigning nroot = root; to see why this is a problem, consider this simpler example:
void set_x(int *x, int *y)
{
x = y;
}
Remember that pointers are really just memory addresses. So, the assignment of x = y says, "replace the memory address that x contains, and set it to whatever y contains". At no stage do you actually change the value at the memory address.
Now, considering nroot = root again, here you are just giving the local variable you have a new memory address, but not updating anything. So at your call side BTtoDLL, you provide it nullptr for the address, to which it never uses it, and never sets it. So, BTtoDLL will never see any change to nroot.
I'm new to Rust, and I'm trying to make an interface where the user can choose a file by typing the filename from a list of available files.
This function is supposed to return the DirEntry corresponding to the chosen file:
fn ask_user_to_pick_file(available_files: Vec<DirEntry>) -> DirEntry {
println!("Which month would you like to sum?");
print_file_names(&available_files);
let input = read_line_from_stdin();
let chosen = available_files.iter()
.find(|dir_entry| dir_entry.file_name().into_string().unwrap() == input )
.expect("didnt match any files");
return chosen
}
However, it appears chosen is somehow borrowed here? I get the following error:
35 | return chosen
| ^^^^^^ expected struct `DirEntry`, found `&DirEntry`
Is there a way I can "unborrow" it? Or do I have to implement the Copy trait for DirEntry?
If it matters I don't care about theVec after this method, so if "unborrowing" chosen destroys the Vec, thats okay by me (as long as the compiler agrees).
Use into_iter() instead of iter() so you get owned values instead of references out of the iterator. After that change the code will compile and work as expected:
fn ask_user_to_pick_file(available_files: Vec<DirEntry>) -> DirEntry {
println!("Which month would you like to sum?");
print_file_names(&available_files);
let input = read_line_from_stdin();
let chosen = available_files
.into_iter() // changed from iter() to into_iter() here
.find(|dir_entry| dir_entry.file_name().into_string().unwrap() == input)
.expect("didnt match any files");
chosen
}
I am stuck with a functionality that i have already done in python long time ago.
I draw a gantt chart in a specific way that i can't reproduce with elm.
here is my code :
https://ellie-app.com/8sYLsxTZHk5a1
The problem is in the "calcTaskPosition" function where i try to set the row of the task.
calcTaskPosition : Int -> Task -> List(Task)
calcTaskPosition row task =
let
precs = List.concatMap (calcTaskPosition (row+1)) (taskPrecs task)
in
{ task | col = (Maybe.withDefault -1 <|
List.maximum <|
List.map (\t -> t.col) precs) + 1
--, row = row
}
:: precs
In my example, tasks lines are set by the initTask function.
I wish to get the same task order whithout having to set explicit line position in the initTask function.
The first clue is when you look at svg you will notice that your "task1" is actually rendered twice. This is easier to see if you uncomment the line --, row = row in the snippet you posted.
In elm (and other functional languages) your tasks will not be manipulated in-place, but instead your tasks will be copied when you mutate them. So it is not really useful to keep col and row values in the model (for now).
Also, working with task ids makes more sense than directly linking objects.
With this in mind, I would create two different task records: One for keeping it in the model (Task in my example) and one for rendering it (I called it DrawableTask).
And then you need a transformation function like
toDrawableListOfTasks : List Task -> List DrawableTask
that will be called in the view.
The transformation function essentially uses your tasksNotInTaskPrecs where you select all tasks that can be immediately drawn (because their precs list is empty). I generalized it and called it allDependenciesMet instead and use it on every iteration to select the tasks that can be drawn.
All tasks that can be drawn will be added to a temporary list (in my case a dictionary for fast look-up of already entered tasks) and then the next iteration starts with all tasks that were not yet drawn.
When no tasks are left, you can return the list and the rendering pass will traverse the list once again.
order : Temp -> List Task -> List DrawableTask
order temp todo =
case List.partition (allDependenciesMet temp) todo of
( [], [] ) ->
-- We are done and can return the list
Dict.values temp
|> List.sortBy .row
( [], _ ) ->
Debug.todo "An invalid list of tasks was passed"
( drawableTasks, nextTodo ) ->
let
nextTemp =
List.indexedMap (toDrawable temp) drawableTasks
|> List.map (\t -> ( t.id, t ))
|> Dict.fromList
|> Dict.union temp
in
order nextTemp nextTodo
I'm not sure if this is understandable, but you should be able to follow https://ellie-app.com/8tdzrgLfBfya1
I've written a basic Node struct in D, designed to be used as a part of a tree-like structure. The code is as follows:
import std.algorithm: min;
alias Number = size_t;
struct Node {
private {
Node* left, right, parent;
Number val;
}
this(Number n) {val = n;}
this(ref Node u, ref Node v) {
this.left = &u;
this.right = &v;
val = min(u.val, v.val);
u.parent = &this;
v.parent = &this;
}
}
Now, I wrote a simple function which is supposed to give me a Node (meaning a whole tree) with the argument array providing the leaves, as follows.
alias Number = size_t;
Node make_tree (Number[] nums) {
if (nums.length == 1) {
return Node(nums[0]);
} else {
Number half = nums.length/2;
return Node(make_tree(nums[0..half]), make_tree(nums[half..$]));
}
}
Now, when I try to run it through dmd, I get the following error message:
Error: constructor Node.this (ulong n) is not callable using argument types (Node, Node)
This makes no sense to me - why is it trying to call a one-argument constructor when given two arguments?
The problem has nothing to do with constructors. It has to do with passing by ref. The constructor that you're trying to use
this(ref Node u, ref Node v) {...}
accepts its arguments by ref. That means that they must be lvalues (i.e. something that can be on the left-hand side of an assignment). But you're passing it the result of a function call which does not return by ref (so, it's returning a temporary, which is an rvalue - something that can go on the right-hand side of an assignment but not the left). So, what you're trying to do is illegal. Now, the error message isn't great, since it's giving an error with regards to the first constructor rather than the second, but regardless, you don't have a constructor which matches what you're trying to do. At the moment, I can think of 3 options:
Get rid of the ref on the constructor's parameters. If you're only going to be passing it the result of a function call like you're doing now, having it accept ref doesn't help you anyway. The returned value will be moved into the function's parameter, so no copy will take place, and ref isn't buying you anything. Certainly, assigning the return values to local variables so that you can pass them to the constructor as it's currently written would lose you something, since then you'd be making unnecessary copies.
Overload the constructor so that it accepts either ref or non-ref. e.g.
void foo(ref Bar b) { ... }
void foo(Bar b) { foo(b); } //this calls the other foo
In general, this works reasonably well when you have one parameter, but it would be a bit annoying here, because you end up with an exponential explosion of function signatures as you add parameters. So, for your constructor, you'd end up with
this(ref Node u, ref Node v) {...}
this(ref Node u, Node v) { this(u, v); }
this(Node u, ref Node v) { this(u, v); }
this(Node u, Node v) { this(u, v); }
And if you added a 3rd parameter, you'd end up with eight overloads. So, it really doesn't scale beyond a single parameter.
Templatize the constructor and use auto ref. This essentially does what #2 does, but you only have to write the function once:
this()(auto ref Node u, auto ref Node v) {...}
This will then generate a copy of the function to match the arguments given (up to 4 different versions of it with the full function body in each rather than 3 of them just forwarding to the 4th one), but you only had to write it once. And in this particular case, it's probably reasonable to templatize the function, since you're dealing with a struct. If Node were a class though, it might not make sense, since templated functions can't be virtual.
So, if you really want to be able to pass by ref, then in this particular case, you should probably go with #3 and templatize the constructor and use auto ref. However, personally, I wouldn't bother. I'd just go with #1. Your usage pattern here wouldn't get anything from auto ref, since you're always passing it two rvalues, and your Node struct isn't exactly huge anyway, so while you obviously wouldn't want to copy it if you don't need to, copying an lvalue to pass it to the constructor probably wouldn't matter much unless you were doing it a lot. But again, you're only going to end up with a copy if you pass it an lvalue, since an rvalue can be moved rather than copied, and you're only passing it rvalues right now (at least with the code shown here). So, unless you're doing something different with that constructor which would involve passing it lvalues, there's no point in worrying about lvalues - or about the Nodes being copied when they're returned from a function and passed into the constructor (since that's a move, not a copy). As such, just removing the refs would be the best choice.