如何反向链接列表? (C和Python实现)
链表是一种简单但引人入胜的数据结构,可用于存储线性连接的非连续数据。
使用链接列表时,我们经常会遇到有趣的操作问题,因为它们需要开箱即用的思维方式,并且具有单链接列表的有限属性。
在本文中,我们将讨论反向链接单链列表的问题。
反向链接列表
让我们直接深入讨论该解决方案。
我们将讨论两种方法:
- 迭代解决方案(使用3个指针)
- 递归解决方案(使用伪2指针)
注意:建议您尝试解决问题,然后再寻求解决方案。
使用迭代解决方案反向链接列表
让我们先克服基本情况。
如果链表只有0个节点或者只有1个节点,那么反转链表是没有意义的,因此我们可以简单地返回then and there。假设现在有> = 2个节点,我们可以执行以下操作。
在上一个节点,当前节点,下一个节点上保留3个指针。
最初,将前一个节点指定为NULL,将当前节点指定为头,然后将下一个节点指定为头的后继。
反向上一个节点与当前节点之间的链接。
通过执行以下操作将所有指针向前移动:上一个节点=当前节点
当前节点=下一个节点
下一个节点=下一个节点->下一个
转到步骤5,直到当前节点不为NULL。
将head分配为上一个节点并返回。
遵循此范例的代码可在此处找到。
C语言代码
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
} *head = NULL;
struct node *make_node(int data){
struct node *new = (struct node *)malloc(sizeof(struct node));
new->next = NULL; new->data = data;
return new;
}
void push(int data){
struct node *new_node = make_node(data);
new_node->next = head;
head = new_node;
}
void print_list(){
struct node *cur = head;
while(cur){
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
void reverse_list(){
if(head == NULL || head->next == NULL)
return;
struct node *prev = NULL, *cur = head, *next;
while(cur){
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
head = prev;
}
int main(){
push(3);
push(4);
push(5);
push(6);
printf("Given Linked list is: ");
print_list();
reverse_list();
printf("Reversed Linked list is: ");
print_list();
return 0;
}
Python代码
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def reverse(self):
if self.head is None or self.head.next is None:
return
prev = None
cur = self.head
while cur:
next_element = cur.next
cur.next = prev
prev = cur
cur = next_element
self.head = prev
def push(self, data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
def print_list(self):
cur = self.head
l1 = []
while cur:
l1.append(cur.data)
cur = cur.next
return l1
head = LinkedList()
head.push(3)
head.push(4)
head.push(5)
head.push(6)
print("Given list is: ", head.print_list())
head.reverse()
print("Reversed list is: ", head.print_list())
使用递归解决方案反向链接列表
递归解决方案使用更自然且易于理解的算法,因此稍微易于理解。
但是,迭代和递归解决方案的工作方式相似。
我们主要使用递归来替换指针" next",因为我们可以递归到链表的末尾,并按照与迭代解决方案类似的方式进行操作。
唯一的区别是,由于使用了递归,我们在移至列表末尾后也向后移动。
另外,请注意,在递归解决方案中,我们不需要下一个指针,因为递归允许我们在链接列表中前进。
其中我们分为两部分来定义递归解决方案:
递归案例:我们首先要在链接列表中前进。
递归结束后,我们可以简单地将当前节点链接到上一个节点。
基本情况:如果当前元素为NULL,则在这种情况下,我们可以简单地将head分配为前一个节点,即链表的最后一个节点。
遵循此范例的代码可以在这里找到:
C语言代码
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
} *head = NULL;
struct node *make_node(int data){
struct node *new = (struct node *)malloc(sizeof(struct node));
new->next = NULL; new->data = data;
return new;
}
void push(int data){
struct node *new_node = make_node(data);
new_node->next = head;
head = new_node;
}
void print_list(){
struct node *cur = head;
while(cur){
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
struct node *reverse_list(struct node *prev, struct node *cur){
if(cur == NULL){
head = prev;
}
else{
reverse_list(cur, cur->next);
cur->next = prev;
}
}
int main(){
push(3);
push(4);
push(5);
push(6);
printf("Given Linked list is: ");
print_list();
reverse_list(NULL, head);
printf("Reversed Linked list is: ");
print_list();
return 0;
}
Python代码
class Node:
def __init__(self, data):
self.data = data
self.next = None
class LinkedList:
def __init__(self):
self.head = None
def _reverse(self, prev, cur):
if cur is None:
self.head = prev
else:
self._reverse(cur, cur.next)
cur.next = prev
def reverse(self):
self._reverse(None, self.head)
def push(self, data):
new_node = Node(data)
new_node.next = self.head
self.head = new_node
def print_list(self):
cur = self.head
l1 = []
while cur:
l1.append(cur.data)
cur = cur.next
return l1
head = LinkedList()
head.push(3)
head.push(4)
head.push(5)
head.push(6)
print("Given list is: ", head.print_list())
head.reverse()
print("Reversed list is: ", head.print_list())

