如何反向链接列表? (C和Python实现)

时间:2020-02-23 14:41:43  来源:igfitidea点击:

链表是一种简单但引人入胜的数据结构,可用于存储线性连接的非连续数据。

使用链接列表时,我们经常会遇到有趣的操作问题,因为它们需要开箱即用的思维方式,并且具有单链接列表的有限属性。

在本文中,我们将讨论反向链接单链列表的问题。

反向链接列表

让我们直接深入讨论该解决方案。
我们将讨论两种方法:

  • 迭代解决方案(使用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())