C program to make a second copy of a linked list

半城伤御伤魂 提交于 2019-12-06 02:47:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!