C 需要伪代码/算法的帮助-链表合并
在一篇文章中,我看到下面的代码是用C语言合并两个排序列表的答案C 需要伪代码/算法的帮助-链表合并,c,merge,linked-list,pseudocode,C,Merge,Linked List,Pseudocode,在一篇文章中,我看到下面的代码是用C语言合并两个排序列表的答案 #define SWAP_PTRS(a, b) do { void *t = (a); (a) = (b); (b) = t; } while (0) Node* MergeLists(Node* list1, Node* list2) { Node *list = NULL, **pnext = &list; if (list2 == NULL) return list1; while (lis
#define SWAP_PTRS(a, b) do { void *t = (a); (a) = (b); (b) = t; } while (0)
Node* MergeLists(Node* list1, Node* list2)
{
Node *list = NULL, **pnext = &list;
if (list2 == NULL)
return list1;
while (list1 != NULL)
{
if (list1->data > list2->data)
SWAP_PTRS(list1, list2);
*pnext = list1;
pnext = &list1->next;
list1 = *pnext;
}
*pnext = list2;
return list;
}
有人能把这解释成伪代码文本吗?无法在同一答案下发表评论,因此作为新问题发布。首先有一个预处理器指令:
#定义交换ptr(a,b)do{void*t=(a);(a)=(b);(b)=t;}而(0)
这意味着,当预处理器准备编译翻译单元时,每当遇到SWAP\u PTRS(a,b)
时,它都将替换为
do { void *t = (a); (a) = (b); (b) = t; } while (0)
让我们把它打开。它只是一个交换一对指针a
和b
的函数
因为循环是一个do。。。当
循环时,它将在测试循环条件之前执行。在循环内部,声明了一个新的void
指针t
。这与任何类型的指针都兼容,因此无论a
和b
是哪种类型的指针,它们都与t
兼容
那么这就是标准的互换:
a
分配给t
b
分配给a
t
分配给b
0
,因此条件的计算结果为false,do。。。而
循环结束。换句话说,它将被执行一次,而且只执行一次,这是需要的,因为目标只是交换一对指针
下面是实际的MergeLists
函数的伪代码
Algorithm MergeLists
Receives: pointer to head node of linked list list1
pointer to head node of linked list list2
Returns: pointer to head node of merged list
1. Declare pointer list for merged list and initialize to NULL
2. Declare pointer to pointer pNext and initialize it to the address of the merged list
3. if (list2 is NULL) // empty list
3.1 return list1 // nothing to merge
4. loop while list1 is not NULL
4.1 if (data in list1 is greater than data in list2)
4.1.1 swap list1 and list2
4.2 set dereferenced value of pNext to list1
4.3 set pNext to the address of the next node in list1
4.4 set list1 to the dereferenced value of pNext // same as list1 = list1->next
5. end loop for list1
6. set the dereferenced value of pNext to list2
7. return list
这是很难遵循的逻辑。当循环时,重物都在循环中。下面是一个细分:
有两个指向链表节点的指针,list1
和list2
。while循环的第一步将数据值较小的节点设置为list1
,另一个设置为list2
。如果需要,可以使用SWAP_PTRS宏进行设置
开始时,*pNext
指向此数据值较小的list1
。第一次通过循环时,由于*pNext
也是list
(合并列表),list
现在也将指向相同的位置
下一步将pNext
重置为list1
中下一个节点的地址。但是,这不会改变list
指向的位置(pNext是两级指针,在这一步中,我们将改变pNext
指向的位置,即不是*pNext指向的位置)
然后将list1
设置为*pNext
,即设置为list1->next
然后循环使用这个新列表1进入下一个迭代
基本上,它只是不断检查列表头部节点的数据值,并将数据值较小的节点添加到合并列表的末尾。当它到达任一列表的末尾时,循环将终止,另一个列表中的其余节点将附加到合并列表的末尾
希望这有意义!这是一个很好的解决方案,而且说实话,画出来要比用语言解释容易得多 为什么要为如此迟钝的代码而烦恼呢?有很多实现(包括栈上溢出)清楚地表达了正在发生的事情。我对其他实现已经很清楚了,我也写了一个实现。但这一个用指针对指针的方式吸引了我的眼球,所以我想理解。。。您正在尝试交换指针?使用^
这个…是的,我希望能看到这个图表:)不管怎样,你的努力让我的头脑变得更清晰了。我认为真正难以理解和解释的部分是:如果pNext
是指向列表节点的指针,那么*pNext
,即解引用值,是指向列表节点的指针。