问题
I was writing a C code to copy the contents of a Linked List onto another list. I want to know if there is a more efficient way of doing this.
Which is better?
struct node *copy(struct node *start1)
{
struct node *start2=NULL,*previous=NULL;
while(start1!=NULL)
{
struct node * temp = (struct node *) malloc (sizeof(struct node));
temp->info=start1->info;
temp->link=NULL;
if(start2==NULL)
{
start2=temp;
previous=temp;
}
else
{
previous->link=temp;
previous=temp;
}
start1=start1->link;
}
return start2;
}
OR
struct node *copy(struct node *start1)
{
if(start1==NULL) return;
struct node *temp=(struct node *) malloc(sizeof(struct node));
temp->info=start1->info;
temp->link=copy(start1->link);
return temp;
}
回答1:
For copying one linked list to another linked list, you have no other option but to iterate through one and keep copying the values to the second, in a total of O(n)time.
You are already doing it. There is no way to do better unless there is some relation among the elements that are stored.
A recursive solution may be better to look at, but it will in fact be less efficient.
Edit: For the changed question
The Iterative version is better.
Note : LOC has no direct relation with efficiency.
回答2:
Without going recursive, this is about the most compact you can get:
struct node *copy(struct node *org)
{
struct node *new=NULL,**tail = &new;
for( ;org; org = org->link) {
*tail = malloc (sizeof **tail );
(*tail)->info = org->info;
(*tail)->link = NULL;
tail = &(*tail)->link;
}
return new;
}
回答3:
For speed, there may in fact be a better way of doing it. As always, the only real way to tell is to benchmark it.
- Depending on the relative cost of iteration
- (which may itself depend on how and in what order you allocated your nodes, as well as cache and memory architecture)
- versus free store allocation
- (which may depend on what state your heap is in, how many other threads are likely to be accessing it, the physical memory status in the host OS, etc.)
it may be faster to:
spend one iteration counting the length of the source list
int len = 0; for (start2 = start1; start2 != NULL; start2 = start2->link) ++len;allocate space for all required nodes in a single block
struct node *temp = malloc(len * sizeof(*temp));and then spend a second iteration linking up your array of nodes
int i = 0; for (start2 = start1; start2 != NULL; start2 = start2->link) { temp[i].info = start2->info; temp[i].link = &temp[i+1]; } temp[len-1].link = NULL;
As I say, I'm not promising it will be faster (and it's certainly uglier), but it may be on some systems, with some compilers, under some conditions. Of course, it's a non-starter if the rest of your code assumes you can free individual nodes at will.
For elegance, recursion naturally wins.
The simple iterative approach is usually going to be a good compromise, though, between elegant but might explode unless you have a fancy TCO-ing compiler and the above, which is frankly a bit ugly and would benefit from an explanatory comment.
来源:https://stackoverflow.com/questions/13633182/c-program-to-make-a-second-copy-of-a-linked-list