C语言 C 程序制作链表的第二个副本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13633182/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:36:46  来源:igfitidea点击:

C program to make a second copy of a linked list

calgorithmlinked-list

提问by user

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.

我正在编写一个 C 代码来将链接列表的内容复制到另一个列表中。我想知道是否有更有效的方法来做到这一点。

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;
}

回答by axiom

For copying one linked list to another linked list, you have no other optionbut to iterate through one and keep copying the values to the second, in a total of O(n)time. You are alreadydoing it. There is no wayto do better unless there is some relation among the elements that are stored.

要将一个链表复制到另一个链表,您别无选择,只能遍历一个链表并在总O(n)时间内将值复制到第二个链表。你已经在做。有没有办法做的更好,除非有被存储的元素之间有一定的关系。

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.

注意:LOC 与效率没有直接关系。

回答by wildplasser

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;
}

回答by Useless

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 maybe 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;
      
  • 取决于迭代的相对成本
    • (这本身可能取决于您分配节点的方式和顺序,以及缓存和内存架构)
  • 免费商店分配
    • (这可能取决于您的堆处于什么状态,有多少其他线程可能正在访问它,主机操作系统中的物理内存状态等)
  • 这样做可能会更快:

    • 花一次迭代计算源列表的长度

      int len = 0;
      for (start2 = start1; start2 != NULL; start2 = start2->link)
          ++len;
      
    • 为单个块中的所有必需节点分配空间

      struct node *temp = malloc(len * sizeof(*temp));
      
    • 然后花第二次迭代连接你的节点数组

      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 willbe faster (and it's certainly uglier), but it maybe 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 freeindividual nodes at will.

正如我所说,我不保证它更快(而且它肯定更丑),但它可能会在某些系统上,在某些条件下使用某些编译器。当然,如果您的其余代码假设您可以随意使用free单个节点,那么它就不是初学者。



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 compilerand the above, which is frankly a bit ugly and would benefit from an explanatory comment.

然而,简单的迭代方法通常是一个很好的折衷方案,在优雅但可能会爆炸,除非你有一个花哨的 TCO-ing 编译器和上面的,坦率地说有点丑陋,并且会从解释性评论中受益。