these are the functions
//printList for Debugging
void printList(letterListT *head){
letterListT *temp = head;
while(temp != NULL){
printf("%c ", temp->letter);
temp = temp->nxt;
}
}
//Add the Specified Letter by Creating a New Node in the Letter List defined
void addLetter(letterListT *letListHead, char letter){
letterListT *newNode;
newNode = (letterListT *)malloc(sizeof(letterListT));
newNode->letter = letter;
newNode->nxt = letListHead->nxt;
letListHead->nxt = newNode;
}
and these are in main:
unusedLetList = (letterListT *)malloc(sizeof(letterListT));
unusedLetList->nxt = NULL;
for(i=122; i>=97; i--){ //ascii codes for z to a
addLetter(unusedLetList, i);
}
//printlists Test
printList(unusedLetList);
and this is the output...
p a b c d e f g h i j k l m n o p q r s t u v w x y z
my question is... where does this 'p' come from?!
The list head node.
unusedLetList = (letterListT *)malloc(sizeof(letterListT));
unusedLetList->nxt = NULL;
You create a head node here, and then add each letter after the head node. The head node has an uninitialized ->letter field. It could be anything; it happens to be p.
Related
The problem is taking a linked list and reversing the even nodes only. That is, a list 1->2->3->8 should become 1->8->3->2.
The solution I came up with traverses the list one and is constant in space. I believe that the problem has to be with copying the values of each node, rather than changing the pointers. They seem just not to be copied.
Here is the first version,
listnode * solve(listnode* A) {
if(A == NULL || A->next == NULL)
return A;
listnode * current = A, * prev = NULL;
size_t dim = 0;
int nextVal, hasPrevious = 0;
while(current != NULL) {
dim++;
if(dim % 2 == 0 && !hasPrevious) {
prev = current; //We store the previous value
hasPrevious = 1; //We now have a previous value
}
if(hasPrevious && dim % 2 == 0) {
nextVal = current->val; //I store the value to plug it into previous
current->val = prev->val; //Here I update next value with the previous value.
prev->val = nextVal; //And now previous value has nextValue
hasPrevious = 0; //We no longer have a previous value to copy
}
current = current->next;
}
return A;
}
The second solution is the same but using the -> operator when copying the values, but same result.
listnode * solve(listnode* A) {
if(A == NULL || A->next == NULL)
return A;
listnode * current = A, * prev = NULL;
size_t dim = 0;
int nextVal, hasPrevious = 0;
while(current != NULL) {
dim++;
//I work from the odd nodes such that I access the
//other nodes deferencing the pointer, and thus
//changing the content of the node.
if(dim % 2 == 1 && !hasPrevious) {
prev = current; //We store the previous value
hasPrevious = 1; //We now have a previous value
}
if(hasPrevious && dim % 2 == 1) {
nextVal = current->next->val; //I store the value to plug it into previous
current->next->val = prev->next->val; //Here I update next value with the previous value.
prev->next->val = nextVal; //And now previous value has nextValue
hasPrevious = 0; //We no longer have a previous value to copy
}
current = current->next;
}
return A;
}
T
Assuming a -> b -> c -> d -> e -> f -> g -> h -> i -> j should become a -> j -> c -> h -> e -> f -> g -> d -> i -> b, (i.e. put all the nodes at even positions (counting from 1) in reverse order), I do not believe that can be done in a single pass through the list, at least for a singly linked list. It can be done in two passes.
The way I would implement it is as follows:
Extract the even nodes onto a new list.
Reverse the order of the nodes of the new list.
Merge the new list back into the original list.
Since it is easy to construct a list in reverse order from single nodes, steps 1 and 2 can be combined into a single step. So the two passes are:
Extract the even nodes onto a new list in reverse order.
Merge the new list back into the original list.
This solution reorders the list nodes by pointer manipulation rather than by swapping the values contained within nodes. I think this is what is normally expected when solving linked list problems.
Example implementation:
#include <stddef.h>
#include "listnode.h"
listnode *solve(listnode *A) {
listnode *rev;
listnode *el;
listnode *ne;
/*
* First pass.
*
* Loop through pairs of nodes (el and ne) moving the second node
* of each pair to a new list (rev) in reverse order.
*/
rev = NULL;
el = A;
while (el != NULL && (ne = el->next) != NULL) {
el->next = ne->next;
el = ne->next;
ne->next = rev;
rev = ne;
}
/*
* Second pass.
*
* Merge the reversed list of nodes (second node of each pair in reverse
* order) back into the original list.
*/
el = A;
while (rev != NULL) {
ne = rev;
rev = ne->next;
ne->next = el->next;
el->next = ne;
el = ne->next;
}
/* Return start of reordered list. */
return A;
}
Output showing the wrong intersection of List 1 and List 2I am writing a function for the intersection of two linked lists but somehow I keep getting the wrong output.The idea is to initialize an empty list and to traverse through list 1 by using Find function to check if it intersects with list 2.If it does, then it is added to the list 4 (answer) which is returned after traversing through the list 1.
Here is the function, as well as the supporting functions it calls:
List Intersection(List L1, List L2) {
List L4 = MakeEmpty(NULL);
Position A = First(L1);
Position B = First(L2);
Position C = Header(L4);
while(A != NULL){
if(Find(A->Element, L2) != NULL) {
Insert(A->Element, L4, C);
A = A->Next;
C = C->Next;
} else {
A = A->Next;
}
}
return L4;
}
Position Find( ElementType X, List L ) {
Position P = L->Next;
while( P != NULL && P->Element != X )
P = P->Next;
return P;
}
void Insert( ElementType X, List L, Position P ) {
Position TmpCell = malloc( sizeof( struct Node ) );
// [check for null]
TmpCell->Element = X;
TmpCell->Next = P->Next;
P->Next = TmpCell;
}
Given the following definition of linked-list
typedef struct elemento {
int inf;
struct elemento *next;
} lista;
I'm trying to create a function
lista *SeekAndDestroy(lista *p, int k);
that, given a list *p and a positive integer k, which searches on the list, the first sequence of consecutive elements whose sum is exactly k and eliminate such elements from the list.
My try:
lista *SeekAndDestroy(lista *p, int k) {
lista *a, *nuovo;
int x = 0;
a = (lista *)malloc(sizeof(lista));
a->inf = p->inf;
nuovo = a;
p = p->next;
while (p != NULL) {
if (p->next != NULL) {
if ((p->inf + p->next->inf) == k) {
if (x != 1) {
p = p->next->next;
x = 1;
continue;
}
}
}
nuovo->next = (lista *)malloc(sizeof(lista));
nuovo = nuovo->next;
nuovo->inf = p->inf;
p = p->next;
}
nuovo->next = NULL;
return a;
}
This my solution has two main problems:
1) erases a maximum of two consecutive elements and not more
2) if the items to be deleted are the first two, the function does not work
How can i solve this problem? Thanks
For now, let's forget about linked list and pointer and stuffs. Say, we have to solve the problem for a given array. Can we do that? Sure!
for (int i = 0; i < array.length; ++i) {
for (int j = i; j < array.length; ++j) {
int sum = getRangeSum(array, i, j);
if (sum != k) continue;
// construct new array and return
}
}
This code can be optimized further but let's keep it simple for now. So, in linked list, similar approach can be used. And the delete part is also simple. You can keep a variable to keep track of the previous node of i. Let's call it iParent. Now, we can remove the [i, j] segment as iParent->next = j->next.
Obviously, you need to consider some corner cases like if such segment is not found or if the segment starts from the beginning of the linked list etc.
Here's a function I wrote to tackle the two problems faced by you and any other boundary conditions:
list* Seek_Destroy(list* head, int target){
if(head == NULL)
return NULL;
list* temp = head;
bool find_complete = false;
list *prev = temp;
//Loop for iterating until list is complete or target sum is found.
while( !find_complete){
//Create a pointer for loop calculations
list* sum_loop = temp;
//Initialize sum to 0
int sum =0;
//Loop for checking whether the sum is equal to the target
while(sum <= target && sum_loop->next!= NULL){
//Keep adding the sum
sum += sum_loop->inf;
if(sum == target){
//Set the flag for exiting outer loop
find_complete = true;
//Test whether head of the list is included in the sum
if (temp == head){
//Make head point to the struct after the last element included in the sum loop
head = sum_loop->next;
//Delete and free memory
while(temp!= sum_loop){
list* del = temp;
temp = temp->next;
free(del);
}
}else {
//Set the next pointer of previous element of the list to point after the last element included in the sum loop
prev->next= sum_loop->next;
//Delete and free memory
while(temp!= sum_loop){
list* del = temp;
temp = temp->next;
free(del);
}
}
break;
}
//Increment the pointer for the sum calculation
sum_loop = sum_loop->next;
}
prev = temp;
//Make temp point to next element in the list
temp = temp->next;
//IF entire list is traversed set the flag to true
if (temp ==NULL){
find_complete = true;
}
}
return head;
}
Assuming your numbers are all non-negative, there's a more efficient algorithm you can use. You simply run two pointers, ptrA and ptrB, through the list, maintaining the sum of the inclusive elements.
If the sum isn't what you need, you do one of two things. First, if your current sum is less than that needed, bring the next element into the array by advancing ptrB.
If your current sum is more than what you need, you take out the first element in your range by advancing ptrA. Both these operations should, of course, adjust the current range sum. There's an edge case here in that you don't want to do this if there's currently only one item in the range.
And it should go without saying that, if the current range sum is equal to what you need, you simply delete that range and exit.
In terms of pseudo-code, it would be something like:
def delExact(list, desiredSum):
# Check non-empty and start range.
if list is empty:
return
ptrA = list.first
ptrB = ptrA
rangeSum = ptrA.value
# Continue until match found
while rangeSum is not equal to desiredSum:
# Select add-another or remove-first.
if ptrA == ptrB, or rangeSum < desiredSum:
# Need to bring another in, returning if list exhausted.
ptrB = ptrB.next
if ptrB == null:
return
rangeSum = rangeSum + ptrB.value
else:
# Need to remove one.
rangeSum = rangeSum - ptrA.value
ptrA = ptrA.next
# If we exit the loop, we've found a sum match.
# Hence we need to delete ptrA through ptrB inclusive.
However, that two-pointer approach breaks down if negative numbers are allowed since you don't actually know what effect later elements may have.
In that case, you basically have to do an exhaustive search of all possibilities, and that basically boils down to:
for each element in list:
for each possible segment from that element on:
check and act on summed data
That's actually more of an English representation, the pseudo-code for such a beast would be along the lines of:
def delExact(list, desiredSum):
# For each list element.
ptrA = list.first
while ptrA is not null:
# For each possible segment starting at that element.
segmentSum = 0
ptrB = ptrA
while ptrB is not null:
add ptrB.value to segmentSum
# Delete segment if sum matches, then return.
if segmentSum is equal to desiredSum:
# Here we delete from ptrA through ptrB inclusive.
return
# Otherwise, keep adding elements to segment.
ptrB = ptrB.next
# No matching segment, move on to next element.
ptrA = ptrA.next
# No matching segment at any element, just return.
The use of either of those algorithms will solve your problem regarding only deleting two elements.
The problem of deleting at the start of the list is to simply recognise that fact (ptrA == list.first) and make sure you adjust the first pointer in that case. This is a standard edge case in linked list processing, and can be implemented as something like:
def deleteRangeInclusive(list, ptrA, ptrB):
# Adjust list to remove ptrA/ptrB segment,
# allowing for possibility ptrA may be the head.
if ptrA == list.first:
list.first = ptrB.next
else:
beforeA = list.first
while beforeA.next != ptrA:
beforeA = beforeA.next
beforeA.next = ptrB.next
# Now we can safely remove the ptrA-ptrB segment.
while ptrA != ptrB:
tempA = ptrA
ptrA = ptrA.next
delete element tempA
delete element ptrB
I solved like that:
Lista *Distruggi(Lista *p, int k) {
Lista *n = NULL, *nuova = NULL;
int z = 0;
for (Lista *i = p; i != NULL && z != 1; i = i->next) {
for (Lista *j = i; j != NULL; j = j->next) {
int sum = somma(i, j);
if (sum != k) continue;
n = (Lista *)malloc(sizeof(Lista));
n->inf = p->inf;
p = p->next;
nuova = n;
while (p != i) {
nuova->next = (Lista *)malloc(sizeof(Lista));
nuova = nuova->next;
nuova->inf = p->inf;
p = p->next;
}
while (j != NULL) {
nuova->next = (Lista *)malloc(sizeof(Lista));
nuova = nuova->next;
nuova->inf = j->inf;
j = j->next;
}
z = 1;
break;
}
}
if (z == 0) return p;//NO CHANGE
else {//CHANGE
nuova->next = NULL;
return n;
}
}
I'm trying to sort a doubly linked list, but I'm having some trouble. I'm a noob in C and I guess my problem is with pointers..
I just can't see how to swap two positions inside the list and so maybe that's the issue.
I tryied to sort it by using Bubblesort, even knowing that it's complexity is not so good because, how I'm still learning, thought that it was an easy way to start.
I also tryied reading some things about swaping elements in a linkedlist and how to sort them, but I'm really stuck with this problem...
PS: I started the for with the m->next cause my list has a header(m).
PS2:I'm getting the error "request for member ‘next’ in something not a structure or union", and don't know how to fix it
struct segment {
int x, y; /// position
char c; // letter
struct segment* next;
struct segment* prev;
};
void sortingSegments(struct segment* m) {
struct segment **j; struct segment **i;
for(i = &((m->next)->next); i !=NULL; i = i->next) {
for(j = &(m->next); j == i; j = j->next) {
if ((*j)->c > (*i)->c) {
struct segment **aux;
aux = i;
(*aux)->next = (*i)->next;
(*aux)->prev = (*i)->prev;
i = j;
(*i)->next = (*j)->next;
(*i)->prev = (*j)->prev;
j = aux;
(*j)->prev = (*aux)->prev;
(*j)->next = (*aux)->next;
}
}
}
}
Please read the comments and try to understand the linking of nodes.
It is based on the simple bubble sort described in wikipedia.
void sortingSegments(struct segment** m) {
struct segment *i, *tmp, *prev, *next;
int swapped = 1;
/*
* https://en.wikipedia.org/wiki/Bubble_sort#Pseudocode_implementation
* n = length(A)
* repeat
* swapped = false
* for i = 1 to n-1 inclusive do
* //if this pair is out of order
* if A[i - 1] > A[i] then
* // swap them and remember something changed
* swap(A[i - 1], A[i])
* swapped = true
* end if
* end for
* until not swapped
*/
// looping until no more swaps left
while (swapped) {
swapped = 0;
// we begin from the second item at each iteration
for (i = (*m)->next; i; i = i->next) {
// we need to swap i with i->prev
if (i->prev->c > i->c) {
prev = i->prev;
next = i->next;
// swapping first and second elements,
// so update m to reflect the change made
// to the head of the list
if (prev == *m) {
*m = i;
}
// so there is a prev of prev, update that two links
else {
prev->prev->next = i;
i->prev = prev->prev;
}
// so there is a next, update that two links
if (next) {
next->prev = prev;
prev->next = next;
}
// no next element, mark the end of the list
else {
prev->next = NULL;
}
// this is obvious, prev now becomes i's next
prev->prev = i;
i->next = prev;
// this is needed to reflect the change in i
i = prev;
swapped = 1;
}
}
}
}
Following this link, I modified the code to build a binary tree given the postorder and inorder traversals. But the output seems to generate some junk values. I couldn't understand where I have gone wrong. A preorder traversal has root at the beginning and a postorder traversal has root at the end. Using that logic, I modified the code. As follows:
struct tree* buildTree2(char in[], char post[], int inStrt, int inEnd)
{
static int postIndex = sizeof(post)/sizeof(post[0]) - 1; //postorder index
if(inStrt > inEnd)
return NULL;
struct tree* tNode = newNode(post[postIndex--]);
if(inStrt == inEnd)
return tNode;
else
{
int inIndex = search(in, inStrt, inEnd, tNode->data);
tNode->left = buildTree(in, post, inStrt, inIndex-1);
tNode->right = buildTree(in, post, inIndex+1, inEnd);
return tNode;
}
}
Output:
The inorder traversal of the build tree (using preorder traversal) is : D B E A F C
The inorder traversal of the build tree (using postorder traversal) is : D B I R O 7 = R N T V _ G D X t u o . a / .
Modified code:
struct tree* buildTree2(char in[], char post[], int inStrt, int inEnd, int postIndex)
{
//printf("\n %d ",postIndex);
if(inStrt > inEnd) //termination condition for buildTree(in, post, inIndex+1, inEnd)
return NULL;
struct tree* tNode = newNode(post[postIndex--]);
//check if node has children
if(inStrt == inEnd)
return tNode;
else
{
//get the index of the postorder variable in the inorder traversal
int inIndex = search(in, inStrt, inEnd, tNode->data);
//Recursively build the tree
tNode->left = buildTree2(in, post, inStrt, inIndex-1, postIndex);
//The inIndex value points to the tNode. So less than that is left sub tree and more than that is the right sub tree
tNode->right = buildTree2(in, post, inIndex+1, inEnd, postIndex);
return tNode;
}
}
Output:
The inorder traversal of the build tree (using preorder traversal) is : D B E A F C
The inorder traversal of the build tree (using postorder traversal) is : E B E
node<int> * consTree(int * post, int * in, int postS, int postE, int inS, int inE){
if(postS > postE)
return NULL;
int rootdata = post[postE];
int indexI = -1;
for(int i = inS; i <= inE; i++){
if(rootdata == in[i]){
indexI = i;
break;
}
}
int lpostS = postS;
int linS = inS;
int linE = indexI - 1;
int lpostE = postS + indexI - inS - 1;
int rpostS = postS + indexI - inS;
int rpostE = postE - 1;
int rinS = indexI + 1;
int rinE = inE;
node<int> * root = new node<int>(rootdata);
root -> left = consTree(post,in,lpostS,lpostE,linS,linE);
root -> right = consTree(post,in,rpostS,rpostE,rinS,rinE);
return root;
}
Basically you need to think , when the right order both traversal are passed in the recursive call the array passed remain same just the indexes are changed..in that case let say i have pass in right order traversal (arr,6,9) so the changes should be made between that indexes only.. not from the 0(starting index of array)