[英]Swap reversing a linked list in c
给定一个列表,我想通过将第一个与最后一个交换,第二个与第二个倒数交换,以反转列表,依此类推。
我写了这个函数来交换每对,其中pos1
和pos2
是要交换的两个位置。
maxPos
是两个位置中最大的一个, node1
和node2
是遍历列表后找到的两个节点。
int swap(struct node *list, int pos1, int pos2) {
if (node1 != NULL && node2 != NULL) {
if (prev1 != NULL)
prev1->next = node2;
if (prev2 != NULL)
prev2->next = node1;
temp = node1->next;
node1->next = node2->next;
node2->next = temp;
if (prev1 == NULL)
head = node2;
else if (prev2 == NULL)
head = node1;
}
return 1;
}
而不是为每个对递归调用它,即。 (1,n-1)
, (2,n-2)
, (3,n-3)
每次都必须遍历该列表,我想知道是否有办法迭代地解决它。
您真的要交换节点内容吗?
您可以使用一个非常简单的函数来迭代地反转列表:
struct node {
// whatever payload fields...
struct node *next;
};
struct node *reverse_list(struct node *list) {
struct node *last = NULL;
while (list != NULL) {
struct node *next = list->next;
list->next = last;
last = list;
list = next;
}
return last;
}
当使用带有锚元素的列表(例如,第一个元素是节点但不用于存储数据)时,可以使用
struct node **list_nth(struct node *node, size_t idx)
{
for (;idx > 0 && node; --idx)
node = node->next;
return node ? &(node->next) : NULL;
}
void list_swap(struct node *head, size_t idx_a, size_t idx_b)
{
struct node **a = list_nth(head, min(idx_a, idx_b));
struct node **b = list_nth(head, max(idx_a, idx_b));
struct node *tmp;
if (idx_a == idx_b)
return;
if (!a || !b)
abort();
if ((*a)->next == *b) {
tmp = *a;
*a = *b;
tmp->next = (*b)->next;
(*a)->next = tmp;
} else {
tmp = (*a)->next;
(*a)->next = (*b)->next;
(*b)->next = tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
}
用于交换操作。 但是对于单个链表,由于昂贵的节点查找,您的反向操作的复杂度为O(n ^ 2)。
如其他地方所述,要反转列表:
您必须声明一个新方法来反转整个列表,该方法将仅被调用一次。 同样,您最好使用双链表来解决此问题。
节点结构:
struct node {
int data;
struct node *next;
struct node *prev;
};
方法:
void reverse() {
struct node *temp = head; // assuming you have the head node as a global variable.
struct node *lastPtr = head;
for (int i = 0; i < len; i++) { // assuming you have length as a global variable.
lastPtr = lastPtr->next;
}
for (int i = 0; i < len / 2; i++) {
temp->data += lastPtr->data;
lastPtr->data = temp->data - lastPtr->data;
temp->data -= lastPtr->data;
temp = temp->next;
lastPtr = lastPtr->prev;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.