给出一个列表,我想通过将第一个与最后一个交换,第二个与第二个倒数交换,以此类推。
我编写了此函数来交换每一对,其中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)
每次都必须遍历该列表,我想知道是否有办法迭代解决该问题。
答案 0 :(得分:1)
您真的要交换节点内容吗?
您可以使用一个非常简单的功能来迭代地反转列表:
<?php
namespace App\Controller;
use App\Entity\Contact;
use App\Form\ContactType;
use App\Repository\ContactRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/contact")
*/
class ContactController extends AbstractController
{
//...
/**
* @Route("/new", name="contact_new", methods={"GET","POST"})
*/
public function new(Request $request): Response
{
$contact = new Contact();
$form = $this->createForm(ContactType::class, $contact);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($contact);
$entityManager->flush();
return $this->redirectToRoute('contact_index');
}
return $this->render('contact/new.html.twig', [
'contact' => $contact,
'form' => $form->createView(),
]);
}
}
答案 1 :(得分:0)
在使用带有锚元素的列表时(例如,第一个元素是节点,但不用于存储数据),可以使用
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)。
如其他地方所述,用于反转列表:
答案 2 :(得分:-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;
}
}