Sorting an array using subscripts without moving array elements - c

I have to sort an array of non-negative ints using mergesort in C, but there's a catch - I cant move around the actual array elements, like if I have {3,5,6,7,0,4,1,2}, the desired output should be
First element is at subscript: 4
0 3 5
1 5 2
2 6 3
3 7 -1
4 0 6
5 4 1
6 1 7
7 2 0
See how the ordering of the original input stays the same but only the keys get swapped as the numbers are compared? So far, my main functions are:
void Merge(int *A,int *L,int leftCount,int *R,int rightCount)
{
int i,j,k;
// i - to mark the index of left sub-array (L)
// j - to mark the index of right sub-array (R)
// k - to mark the index of merged sub-array (A)
i = 0; j = 0; k =0;
while(i<leftCount && j< rightCount)
{
if(L[i] <= R[j])
{
//something important;
i++;
}
else
{
//something important;
j++;
}
}
i=0;
j=0;
while(i < leftCount) A[k++] = L[i++]; //merge all input sequences without swapping initial order
while(j < rightCount) A[k++] = R[j++];
}
// Recursive function to sort an array of integers.
void MergeSort(int *A,int n)
{
int mid,i,k, *L, *R;
if(n < 2)
{
return;
}
mid = n/2; // find the mid index.
// create left and right subarrays
// mid elements (from index 0 till mid-1) should be part of left sub-array
// and (n-mid) elements (from mid to n-1) will be part of right sub-array
L = (int*)malloc(mid*sizeof(int));
R = (int*)malloc((n- mid)*sizeof(int));
for(i = 0;i<mid;i++) L[i] = A[i]; // creating left subarray
for(i = mid;i<n;i++) R[i-mid] = A[i]; // creating right subarray
MergeSort(L,mid); // sorting the left subarray
MergeSort(R,n-mid); // sorting the right subarray
Merge(A,L,mid,R,n-mid); // Merging L and R into A as sorted list.
free(L);
free(R);
}
I know that I have to initialize the index of all the elements as -1 at the bottom of the recursion tree when there are only single elements during the merge-sort. And then I have to change those indices accordingly as I compare array elements from Left array vs Right array. But thats where Im stuck. My professor told the class to use a linked list - but Im having a tough time visualizing HOW i can implement a linked list to achieve this indexing thing. I dont want my homework to be done by someone else, I just want someone to explain in pseudocode how I should go about it, and then I can write the actual code myself. But Im so lost, Im sorry if the question is poorly asked, but Im brand spanking new here and Im freaking out :(

Ok. lets start with a simple example, a list of 4 elements to sort, lets go through the process of what your function needs to do and how it does it in terms of linked lists:
#->[3]->[1]->[4]->[2]->$
Ok, so here # is your pointer to the first element, in this case [3], which has a pointer to the second, and so on. I shall use ->$ as a null pointer (not pointing to anything) and ->* as a 'I don't care' pointer (where a pointer may exist, but want to show a conceptional break in the list)
We now perform multiple passes to merge these into one sorted list.
This is the first pass, so we treat it as if we have multiple lists of length 1:
#->* [3]->* [1]->* [4]->* [2]->*
In reality, these remain linked for now, but this is the conceptional model.
so what to we need 'know' at this time?
the end of the list before list #1
reference to beginning of list #1
reference to beginning of list #2
reference to item after list #2
Then we merge the two sublists (2) and (3) onto the end of (1), by taking the minimum of the heads of the lists, detaching that, and ammending it to (1), moving onto the next value in that list if it exists
conceptional
//sublists length 1. we'll work on the first pair
#->* [3]->* [1]->* [4]->* [2]->*
//smallest element from sublists added to new sublist
#->* [3]->* [4]->* [2]->* //
[1]->*
//above repeated until sublists are both exhausted
#->* [4]->* [2]->*
[1]->[3]->*
//we now have a sorted sublist
#->* [1]->[3]->* [4]->* [2]->*
actual
//(1-4) are pointers to the list as per description above
#->[3]->[1]->[4]->[2]->$
| | | |
1 2 3 4
//set the end of the lists (2) and (3) to point to null, so
//when we reach this we know we have reached the end of the
//sublist (integrity remains because of pointers (1-4)
#->* [3]->$ [1]->$ [4]->[2]->$
| | | |
1 2 3 4
//the smallest (not null) of (2) and (3) is referenced by (1),
//update both pointers (1) and (2) or (3) to point to the next
//item
#->[1]->* [3]->$ $ [4]->[2]->$
| | | |
1 2 3 4
//repeat until both (2) and (3) point to null
#->[1]->[3]->* $ $ [4]->[2]->$
| | | |
1 2 3 4
We now have a linked list with the first sublist in it. Now, we keep track of (1), and move on to the second pair of sublists, starting with (4), repeating the process.
Once (2),(3) and (4) are all null, we have completed the pass. We now have sorted sublists, and a single linked list again:
#->[1]->[3]->[2]->[4]->$ $ $ $
| | | |
1 2 3 4
Now we do the same, only with sublists twice the length. (and repeat)
The list is sorted when sublist length >= length of linked list.
At no point during this have we actually moved any data around, only modified the links between the items in the linked list.
This should give you a solid idea of what you need to do from here.
I've extended this to some actual code:
See it here
I wrote it in python, so it satisfies your desire for pseudocode, as it isn't code for the language that you are writing in.
pertinent function with additional comments:
def mergesort(unsorted):
#dummy start node, python doesn't have pointers, but we can use the reference in here in the same way
start = llist(None)
start.append(unsorted)
list_length = unsorted.length()
sublist_length = 1
#when there are no sublists left, we are sorted
while sublist_length < list_length:
last = start
sub_a = start.next
#while there are unsorted sublists left to merge
while sub_a:
#these cuts produce our sublists (sub_a and sub_b) of the correct length
#end is the unsorted content
sub_b = sub_a.cut(sublist_length)
end = sub_b.cut(sublist_length) if sub_b else None
#I've written this so is there are any values to merge, there will be at least one in sub_a
#This means I only need to check sub_a
while sub_a:
#sort the sublists based on the value of their first item
sub_a, sub_b = sub_a.order(sub_b)
#cut off the smallest value to add to the 'sorted' linked list
node = sub_a
sub_a = sub_a.cut(1)
last = last.append(node)
#because we cut the first item out of sub_a, it might be empty, so swap the references if so
#this ensures that sub_a is populated if we want to continue
if not sub_a:
sub_a, sub_b = sub_b, None
#set up the next iteration, pointing at the unsorted sublists remaining
sub_a = end
#double the siblist size for the next pass
sublist_length *=2
return start.next

Create a linked list of items whereby each list item has both the value and index of each array item. So aside from prev/next, each item in the linked list is a struct that has struct members uint value; and uint index; .
Pre-populate the link-list just by iterating the array and for each array element, append a new linked-list item to the list and set the value and index of the array element in each linked-list item as they are added to the list.
Use the pre-populated linked-list as a "proxy" for the actual array values and sort the linked list as if it were the original array. I.e. instead of sorting based on myArray[i], sort based on currentLinkListItem.value .

As speaking of linked lists:
typedef struct ValueNode
{
struct ValueNode* next;
int* value;
} ValueNode;
typedef struct ListNode
{
struct ListNode* next;
ValueNode* value;
} ListNode;
Singly linked lists are sufficient...
Now first the merge algorithm:
ValueNode* merge(ValueNode* x, ValueNode* y)
{
// just assuming both are != NULL...
ValueNode dummy;
ValueNode* xy = &dummy;
while(x && y)
{
ValueNode** min = *x->value < *y->value ? &x : &y;
xy->next = *min;
*min = (*min)->next;
xy = xy->next;
}
// just append the rest of the lists - if any...
if(x)
{
xy->next = x;
}
else if(y)
{
xy->next = y;
}
return dummy.next;
}
The dummy is just for not having to check the for NULL within the loop...
Now let's use it:
int array[] = { 3, 5, 6, 7, 0, 4, 1, 2 };
ListNode head;
ListNode* tmp = &head;
for(unsigned int i = 0; i < sizeof(array)/sizeof(*array); ++i)
{
// skipping the normally obligatory tests for result being 0...
ValueNode* node = (ValueNode*) malloc(sizeof(ValueNode));
node->value = array + i;
node->next = NULL;
tmp->next = (ListNode*) malloc(sizeof(ListNode));
tmp = tmp->next;
tmp->value = node;
}
tmp->next = NULL;
Now we have set up a list of lists, each containing one single element. Now we merge pairwise two subsequent lists. We need to pay attention: If we merge two lists into one, keep it as the new head and merge the next one into it, and so on, then we would have implemented selection sort! So we need to make sure that we do not touch an already merged array before all others are merged. That is why the next step looks a little complicated...
while(head.next->next) // more than one single list element?
{
tmp = head.next;
while(tmp)
{
ListNode* next = tmp->next;
if(next)
{
// we keep the merged list in the current node:
tmp->value = merge(tmp->value, next->value);
// and remove the subsequent node from it:
tmp->next = next->next;
free(next);
}
// this is the important step:
// tmp contains an already merged list
// -> we need to go on with the NEXT pair!
tmp = tmp->next;
// additionally, if we have an odd number of lists,
// thus at the end no next any more, we set tmp to NULL,
// too, so we will leave the loop in both cases...
}
}
Finally, we could print the result; note that we only have one single linked list left within your outer linked list:
ValueNode* temp = head.next->value;
while(temp)
{
printf("%d\n", *temp->value);
temp = temp->next;
}
What is yet missing is freeing the allocated memory - I'll leave that to you...

Related

Deduplication optimization

The problem is as follows. I want a function that, given a list and a max number of occurrences "x", deletes all elements of the list that appear more than x times or x times.
I found a pretty straightforward solution, which is to check for each of the elements. This said, to repeat the find and delete functions many times seems computationally-wise not optimal to me.
I was wondering whether you could provide a better algorithm (i excluded allocating memory for a matrix from the min to the max... just too much for the task... say you have few very big numbers and your memory won't do it.)
My code follows.
typedef struct n_s
{
int val;
struct n_s *next;
}
n_t;
// deletes all elements equal to del in list with head h
n_t * delete(n_t *h, int del);
// returns the first occurrence of find in list with head h, otherwise gives NULL
n_t * find(n_t *h, int find);
n_t *
delFromList(n_t *h, int x)
{
int val;
n_t *el, *posInter;
// empty list case
if (h == NULL)
return NULL;
// first element
val=h->val;
if ( (posInter = find(h -> next,val))
&& (find(posInter -> next, val)))
h = delete(h, val);
// loop from second element
el = h;
while (el -> next)
{
val = el -> next -> val;
// check whether you want to delete the next one,
// and then if you do so, check again on the "new" next one
if ((posInter = find(el -> next -> next, val))
&& (find(posInter -> next, val)))
el -> next = delete(el -> next, val);
// in case you did not delete the nexy node, you can move on
else
el = el -> next;
}
return h;
}
I know that the el->next->next may look confusing, but I find it less intuitive to use variables such as "next", "past"... so, sorry for your headache.
One option for an algorithm with improved performance is:
Define a data structure D with two members, one for the value of a list element and one to count the number of times it appears.
Initialize an empty balanced tree ordered by value.
Iterate through the list. For each item in the list, look it up in the tree. If it is not present, insert a D structure into that tree with its value member copied from the list element and its count set to one. If it is present in the tree, increments its count. If its count equals or exceeds the threshold, remove it from the list.
Lookups and insertions in a balanced tree are O(log n). A linked list of n items uses n of them, and deletions from a linked list are O(1). So the total time is O(n log n).
Use a counting map to count the number of times each element appears. The keys are the elements, and the values are the counts.
Then, go through your array a second time, deleting anything which meets your threshold.
O(n) time, O(n) extra space.

How to traverse through n elements in a doubly linked list in C?

As the title suggests, I have to iterate through a doubly linked list. The only problem is that I have to iterate through "n" elements.
For example, if I'm given a list of, 1 3 2 2 1 1, I have to iterate left or right depending on the value I'm on so:
1 -> 3 -> 1 -> 1. I can move over the same value as the value in the list. Since I start at 1, I can move left or right 1 element (can only go right). When I land on 3 I can move left or right 3 elements etc.
while (temp->next != NULL) {
//traverse n elements left or right
}
If I always just had to traverse 1 elements at a time it's as easy as
temp = temp->next;
If someone could explain a strategy to traversing 'n' elements depending on the value of the node, that would be much appreciated.
edit: You can only go in the direction if there are enough elements in that direction. So in the case of 1 -> 3, you can only go 3 to the right after.
I think your question is to traverse through n elements, where n is the value of the current node.
The code would be like ~
int tr;
while (temp->next != NULL)
{
tr=temp->data; // temp->data holds the value of the current node.
Node *leftptr = temp, *rightptr = temp;
while(tr!=0 && rightptr!=NULL) //moves right side
{
rightptr = rightptr->next;
tr--;
}
tr=temp->data;
while(tr!=0 && leftptr!=NULL) //moves left side
{
leftptr = leftptr->prev;
tr--;
}
}
You can implement your algorithm and choose how to traverse, given both the traversal rules.

A function implementation to cut a portion of a link list and append it to the end of the list

Consider the following function :
void CustomAppender(int totalNodesToSkip, int totalNodesToCut);
Here totalNodesToSkip and totalNodesToCut are both the inputs given. So it is required to cut a portion of a given linklist of length totalNodesToCut from the totalNodesToSkip numbered node from the beginning.
Consider the list following:
List_1: a->b->c->d->e->f->g->h->i->j->k
Input to the function is CustomAppender(2,3).
Then in the first pass it should the list should become:
List_2: a->b->f->g->h->i->j->k->c->d->e.
So here the portion c->d->e moved to the tail. And this process need to be repeated untill we reach to the end of the given list. That is we need to stop when we reach node 'k' of list 1.
To solve the problem simple approach is by according to the given input take the portion to cut as:
Keep a marker to the end point 'k' in *Marker.
*startPTR pointing node c.
*endPTR pointing node e. (Both can be iterated with the given input.)
And point b nodes next as endPTR's next.
'k' node's next points to startPTR.
Finally endPTR points to NULL.
Above steps can be repeated untill we reach the Marker.
This is working fine.
But my question is is there anyway to implement it in any different way so that I use lesser pointers and much faster approach. As this procedure is costing O(n^2) runtime.
Please suggest any other way.
You can do it in a single pass of the list.
starting at the head of the list, move forward `(skip-1)` nodes. Call this `skip_ptr`.
start another pointer, call it `glue_ptr`. Move it forward `(cut-1)` nodes.
At this point, skip_ptr references the last node to be skipped and glue_ptr references the last node to be cut.
Now, glue them together and mark the end of the cut list.
cut_ptr = skip_ptr.next; // save c->d->e
skip_ptr.next = glue_ptr.next; // attach a->b to f->g ...
glue_ptr.next = null; // mark e as the end of the cut list
So now you have a->b->f->g->h->i->j->k, and cut_ptr points to c->d->e.
Now, if you set glue_ptr = skip_ptr.next and move glue_ptr forward until glue_ptr.next == null, you can then write:
glue_ptr.next = cut_ptr; // attaches the cut part to the end of the list
You just have to keep track of the pieces. But it does the operation in a single pass: O(n).
Update
If you have to repeatedly skip and cut so that the original list:
a,b,c,d,e,f,g,h,i,j,k
becomes
a,b,f,g,k,c,d,e,h,i,j
You can still do it with a single pass over the list. Here's C# code that shows how it's done. Should be easily converted to C.
private void CustomAppender(LLNode list, int skip, int cut)
{
LLNode skip_ptr = list;
LLNode cut_list = null;
LLNode cut_ptr = null;
while (skip_ptr.Next != null)
{
// skip over 'skip' items
for (int i = 1; i < skip && skip_ptr.Next != null; ++i)
{
skip_ptr = skip_ptr.Next;
}
// skip_ptr.next is the start of the next group we want to cut.
// move forward to the last node to be cut.
for (int i = 0; i < cut && skip_ptr.Next != null; ++i)
{
LLNode nodeToCut = skip_ptr.Next;
skip_ptr.Next = nodeToCut.Next;
nodeToCut.Next = null;
if (cut_list == null)
{
cut_list = nodeToCut;
}
else
{
cut_ptr.Next = nodeToCut;
}
cut_ptr = nodeToCut;
}
if (skip_ptr.Next != null)
skip_ptr = skip_ptr.Next;
}
// So now we have two lists.
// skip_ptr points to the last node in the list.
// Append cut_list to the end.
skip_ptr.Next = cut_list;
}
i first of count the total number of elements. As we have to do splitting in elemenys into 3 chains. Now from total subtract the skipped numbers. As split the chain i.e
a->b c->d->e->f-g->h->i->j->k
Now, we have the number left. Now take yhe modulus of remanin number. in case module is 0 then do nothing else whatevey number comes split from last after counting.
As in above you have taken 3 thus no operation is needed to reveser thing but in of 2 the split out be as:
a->b c->d->e->f-g->h->i->j k
now change the last element chain 2 second element chain thus :
a->b k c->d->e->f-g->h->i->j
now combine them
a->b->k->c->d->e->f-g->h->i->j

Linked List loop

What exactly does this code fragment do?
#include <stdio.h>
List *makeList(int n) {
List *l, *l1 = NULL;
for (int i = 0; i < n; i++) {
l = malloc(sizeof(List));
l->val = n-i;
l->next = l1;
l1 = l;
}
return l;
}
My notes say that "Given a number n,
build a list of length n where
the ith element of the list
contains i"
But I don't get that...
The tricky thing here is that the list is built backwards, note that each element's value is set to n - i, and i counts from 0 to n - 1. So, the first element will get value n, the next one will get n - 1, and so on.
This is probably done in order to save on a variable (!); otherwise it would be required to have another pointer to remember the first node, in order to have something to return.
Also, it doesn't check the return value of malloc(), which is always scary.
For n = 0, it will return an undefined value (the value of l), which is really scary.
It creates a linked list of n nodes and returns the head of list. The values are : 1,2,3,...n (from head to tail).
It looks like this:
1 -> 2 -> 3 -> ...... -> n -> (NULL)
Does it help?
This is creating list in reverse order. In other words at the beginning last element of list is being created and its value is list size (n) - 0 (i) which is list element number.
It does something like this; each box is one malloc:
n n-1 n-2 1
^ ^ ^ ^
+--|---+ +--|---+ +--|---+ +--|---+
| val | | val | | val | ... | val |
NULL <-- next | <-- next | <-- next | <-- next |
+------+ +------+ +------+ +------+
^^--- this is returned
The data structure struct List looks like this (more or less):
struct List
{
int val;
struct List * next;
};
Its name is misleading, as it should really be "ListNode" or something like that. There is usually no dedicated "list" data structure in C, just a collection of nodes. You simply pass around the head node and treat that as "the list".
(A dedicated holder structure for the entire list might be useful if you want to store the list size to access it in constant time, or if you have a doubly-linked list and want to have both head and tail pointer available in constant time.)
Let's trace your code.
List *l, *l1 = NULL;
defines two pointer variables of type List.
for (int i = 0; i < n; i++) {
you are starting a loop, which will traverse n times. Which means, if you call this function with 5, this loop will execute 5 times.
l = malloc(sizeof(List));
creates a List value in the memory, and stores the location of that value in the l pointer variable. For every pass through the loop, a different List value is created in the memory.
l->val = n-i;
assigns a value n-i to the val field of the newly created List value. For the first pass through the loop, i will be 0, so the val will contain 5 - 0, which is 5. For the second pass, i is 1, so for the second List, the val will contain 5 - 1, which is 4, and so on.
l->next = l1;
there is a next field in the List type, which is a pointer of the same type. For the first pass, li contains NULL, so it will point to null. For the second pass, l1 will contain the previously created List value, so the second List's next field will point it to that, and so on.
l1 = l;
stores the memory address of the newly created created element to be used in the next pass of the loop.
At a glance:
After the first pass of the loop (i = 0) -
5->NULL
After the second pass (i = 1),
4 -> 5 -> NULL
After the third (i = 2),
3 -> 4 -> 5 -> NULL
After the fourth (i = 3),
2 -> 3 -> 4 -> 5 -> NULL
After the fifth (and last) (i = 4),
1 -> 2 -> 3 -> 4 -> 5 -> NULL
The loop builds a linked list of List objects in backwards in memory. The first element is actually the 'ith' element when the list is complete. It is created, given value 'n' and terminated with NULL.
l->val = n
l->next = NULL
The next object is effectively inserted at the front of the list (l->next = l1).
l->val = n-1
l->next ------------> l->val = n
l->next = NULL
And so on, until i=n-1.
Finally (#i=n-1), the last object created is given the value of 1, the loop terminates, and a pointer to the last created object is returned.

adding two linked lists efficiently in C

I have two linked lists representing the digits of decimal numbers in order from most- to least-significant. for eg 4->7->9->6 and 5->7
The answer should be 4->8->5->3 without reversing the lists because reversing the lists would result in decrease of efficiency.
I am thinking of solving the problem using stack.I will traverse both the lists and push the data elements into two separate stacks.One for each linked list.Then I pop both the stacks together and add both the elements and if the result is a two digit no I 10 modulo it and store the carry in a temp variable.The remainder is stored in the node and the carry is added to the next sum and so on.
if the two stacks are s1 and s2 and the result linked list is res.
temp = 0;
res = (node*)(malloc(sizeof(node*));
while(s1->top!=-1 || s2->top!=-1)
{
temp = 0;
sum = pop(s1) + pop(s2);
n1 = (node*)(malloc(sizeof(node*));
temp = sum/10;
sum = sum%10;
sum = sum+temp;
n1->data = sum;
n1->next = res;
res = n1;
free n1;
//temp=0;
}
if((s1->top==-1)&&(s2->top==-1))
{
return res;
}
else if(s1->top==-1)
{
while(s2->top!=-1)
{
temp = 0;
sum = pop(s2);
sum = sum + temp;
temp = sum/10;
sum = sum%10;
n1 = (node*)(malloc(sizeof(node*));
n1->data = sum;
n1->next = res;
res = n1;
free n1;
}
}
else
{
while(s2->top!=-1)
{
temp = 0;
sum = pop(s2);
sum = sum+temp;
temp = sum/10;
sum = sum%10;
n1=(node*)(malloc(sizeof(node*));
n1->data = sum;
n1->next = res;
res = n1;
free n1;
}
}
return res;
I have come across this problem many times in interview questions but this is the best solution that I could think of.
If anyone can come with something more efficient in c i will be very glad.
Two passes, no stack:
Get the length of the two lists.
Create a solution list with one node. Initialize the value of this node to zero. This will hold the carry digit. Set a list pointer (call it the carry pointer) to the location of this node. Set a list pointer (call it the end pointer) to the location of this node.
Starting with the longer list, for each excess node, link a new node to the end pointer and assign it the value of the excess node. Set the end pointer to this new node. If the
value is less than 9, set the carry pointer to the new node.
Now we're left with both list pointers having the same number of nodes in each.
While the lists are not empty...
Link a new node to the end pointer and advance the end pointer to this node.
Get the values from each list and advance each list pointer to the next node.
Add the two values together.
If value is greater than nine, set the value to value mod 10, increment the value held in the carry pointer's node, move the carry pointer to the next node. If carry pointer's value is nine, set to zero and go to next node.
If value is nine. Set it. Do nothing else.
If value is less than nine. Set it. Set carry pointer to current node.
When you're done with both lists, check if the solution pointer's node value is zero. If it is, set the solution pointer to the next node, deleting the unneeded extra digit.
This is how I would go about solving this:
Step 1: Make a pass on both linked lists, find lengths
say len(L1) = m and len(L2) = n
Step 2: Find difference of lengths
if ( m > n )
d = m - n
else if ( n > m )
d = n - m
else
d = 0
Step 3: Move a temporary pointer d ahead of the larger list
Step 4: Now we have two linked lists to add whose lengths are same, so add them recursively, maintaining a carry.
Step 5:
( Note: if ( d == 0 ) don't perform this step )
After step 4, we've got partial output list, and now we have to put remaining of the larger list at the beginning of output list.
if ( d > 0 )
-Travel larger list till d positions recursively
-Append sum = value_at_end + carry (update carry if sum >= 10) to output list at beginning
-Repeat until difference is consumed
Note: I'm solving the problem as its put before me, not by suggesting the change in underlying data structure.
Time complexity:
Making single passes on both the lists to find their lengths: O(m+n)
Summing two linked lists of equal size (m - d and n) recursively: O(n), assuming m > n
Appending remaining of larger list to output list: O(d)
Total: O( (m+n) + (n) + (d) ) OR O(m+n)
Space complexity:
step 2 of time complexity: O(n), run time stack space
step 3 of time complexity: O(d), run time stack space
Total: O(n + d) OR O(n)
I'd just find the total value of each linked list separately, add them together, then transform that number into a new linked list. So convert 4->7->9->6 and 5->7 to integers with the values 4796 and 57, respectively. Add those together to get 4853, then transform that into a linked list containing 4->8->5->3. You can do the transformations with simple math.
Doing it your way would be a lot easier if you changed the way that the numbers are represented in the first place. Make it so the ones digit is always first, followed by the tens digit, followed by hundreds, etc.
EDIT: Since you're apparently using enormous numbers: have you considered making them doubly-linked lists? Then you wouldn't need to reverse it, per se. Just traverse it backwards.
Using a stack is no more efficient than reversing the lists (actually it is reversing the lists). If your stack object is dynamically allocated this is no big deal, but if you create it with call recursion, you'll easily get Stack Overflow of the bad sort. :-)
If you doubly link the lists, you can add the digits and use the backwards links to find out where to put your carried value. http://en.wikipedia.org/wiki/Doubly_linked_list

Resources