小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
给定指向链表头节点的指针,任务是反转链表。我们需要通过改变节点之间的链接来反转列表。
例子:
输入:以下链表的头部
1->2->3->4->NULL
输出:链表应改为,
4->3->2->1->NULL输入:以下链表的头部
1->2->3->4->5->NULL
输出:链表应改为,
5->4->3->2->1->NULL输入:NULL
输出:NULL 输入:1->NULL
输出:1->NULL
-
将三个指针 prev 初始化为 NULL,curr 为 head,next 为 NULL。
-
遍历链表。 在循环中,执行以下操作。
// 在改变当前的下一个之前,存储下一个节点
next = curr->next
// 现在更改当前的下一个这是实际发生逆转的地方
curr->next = prev
// 将 prev 和 curr 向前移动一步 prev = curr
curr = next
#include <iostream>
using namespace std;
struct Node {
int data;
struct Node* next;
Node(int data)
{
this->data = data;
next = NULL;
}
};
struct LinkedList {
Node* head;
LinkedList() { head = NULL; }
void reverse()
{
Node* current = head;
Node *prev = NULL, *next = NULL;
while (current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
}
void print()
{
struct Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
void push(int data)
{
Node* temp = new Node(data);
temp->next = head;
head = temp;
}
};
int main()
{
LinkedList ll;
ll.push(20);
ll.push(4);
ll.push(15);
ll.push(85);
cout << "Given linked list\n";
ll.print();
ll.reverse();
cout << "\nReversed Linked list \n";
ll.print();
return 0;
}
输出:
Given linked list
85 15 4 20
Reversed Linked list
20 4 15 85
时间复杂度: O(n)
空间复杂度: O(1)
递归方法:
1)将列表分为两部分 - 第一个节点和
链表的其余部分。
2) 对链表的其余部分调用 reverse。
3)将休息链接到第一个。
4) 修复头部指针
#include <iostream>
using namespace std;
struct Node {
int data;
struct Node* next;
Node(int data)
{
this->data = data;
next = NULL;
}
};
struct LinkedList {
Node* head;
LinkedList()
{
head = NULL;
}
Node* reverse(Node* head)
{
if (head == NULL || head->next == NULL)
return head;
Node* rest = reverse(head->next);
head->next->next = head;
head->next = NULL;
return rest;
}
void print()
{
struct Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}
void push(int data)
{
Node* temp = new Node(data);
temp->next = head;
head = temp;
}
};
int main()
{
LinkedList ll;
ll.push(20);
ll.push(4);
ll.push(15);
ll.push(85);
cout << "Given linked list\n";
ll.print();
ll.head = ll.reverse(ll.head);
cout << "\nReversed Linked list \n";
ll.print();
return 0;
}
输出:
Given linked list
85 15 4 20
Reversed Linked list
20 4 15 85
时间复杂度: O(n)
空间复杂度: O(1)
一种更简单的尾递归方法
下面是这个方法的实现。
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node* next;
};
void reverseUtil(Node* curr, Node* prev, Node** head);
void reverse(Node** head)
{
if (!head)
return;
reverseUtil(*head, NULL, head);
}
void reverseUtil(Node* curr, Node* prev, Node** head)
{
if (!curr->next) {
*head = curr;
curr->next = prev;
return;
}
Node* next = curr->next;
curr->next = prev;
reverseUtil(next, curr, head);
}
Node* newNode(int key)
{
Node* temp = new Node;
temp->data = key;
temp->next = NULL;
return temp;
}
void printlist(Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
int main()
{
Node* head1 = newNode(1);
head1->next = newNode(2);
head1->next->next = newNode(3);
head1->next->next->next = newNode(4);
head1->next->next->next->next = newNode(5);
head1->next->next->next->next->next = newNode(6);
head1->next->next->next->next->next->next = newNode(7);
head1->next->next->next->next->next->next->next
= newNode(8);
cout << "Given linked list\n";
printlist(head1);
reverse(&head1);
cout << "\nReversed linked list\n";
printlist(head1);
return 0;
}
输出
Given linked list
1 2 3 4 5 6 7 8
Reversed linked list
8 7 6 5 4 3 2 1
使用堆栈:
- 将节点(值和地址)存储在堆栈中,直到输入所有值。
- 完成所有条目后,将 Head 指针更新到最后一个位置(即最后一个值)。
- 开始弹出节点(值和地址)并以相同的顺序存储它们,直到堆栈为空。
- 将堆栈中最后一个 Node 的 next 指针更新为 NULL。
下面是上述方法的实现:
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node* next;
};
void reverseLL(Node** head)
{
stack<Node*> s;
Node* temp = *head;
while (temp->next != NULL)
{
// Push all the nodes
// in to stack
s.push(temp);
temp = temp->next;
}
*head = temp;
while (!s.empty())
{
temp->next = s.top();
s.pop();
temp = temp->next;
}
temp->next = NULL;
}
void printlist(Node* temp)
{
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
void insert_back(Node** head, int value)
{
Node* temp = new Node();
temp->data = value;
temp->next = NULL;
if (*head == NULL)
{
*head = temp;
return;
}
else
{
Node* last_node = *head;
while (last_node->next != NULL)
{
last_node = last_node->next;
}
last_node->next = temp;
return;
}
}
int main()
{
Node* head = NULL;
insert_back(&head, 1);
insert_back(&head, 2);
insert_back(&head, 3);
insert_back(&head, 4);
cout << "Given linked list\n";
printlist(head);
reverseLL(&head);
cout << "\nReversed linked list\n";
printlist(head);
return 0;
}
**输出**
```C++
Given linked list
1 2 3 4
Reversed linked list
4 3 2 1
使用数组:
1. 创建一个链表。
2. 然后,做一个count(head)函数来统计节点数。
3. 用计数的大小初始化一个数组。
4. 并开始一个while(p->next!=NULL)循环并将所有节点的数据存储到数组中。
5. 然后将数组从最后一个索引打印到第一个。
#include <iostream>
#include<cstdlib>
using namespace std;
typedef struct node
{
int val;
struct node* next;
}node;
node* head=NULL;
int count(node* head)
{
node* p=head;
int k=1;
while(p!=NULL)
{
p=p->next;
k++;
}
return k;
}
node *ll_reverse(node* head)
{
node* p=head;
long int i=count(head),j=1;
long int arr[i];
while(i && p!=NULL)
{
arr[j++]=p->val;
p=p->next;
i--;
}
j--;
while(j)
{
cout<<arr[j--]<<" ";
}
return head;
}
node* insert_end(node* head,int data)
{
node* q=head,*p=(node*)malloc(sizeof(node));
p->val=data;
while(q->next!=NULL)
{
q=q->next;
}
q->next=p;
p->next=NULL;
return head;
}
node *create_ll(node* head,int data)
{
node* p=(node*)malloc(sizeof(node));
p->val=data;
if(head==NULL)
{
head=p;
p->next=NULL;
return head;
}
else
{
head=insert_end(head,data);
return head;
}
}
int main()
{
int i=5,j=1;
while(i--)
{
head=create_ll(head,j++);
}
head=ll_reverse(head);
return 0;
}
输入:1->2->3->4->5
输出:5->4->3->2->1
时间复杂度:O(n) 空间复杂度:O(n)
🥇 往期优质文章
数据结构单链表之链表介绍 | 第一套
数据结构单链表之链表与数组 | 第二套
数据结构单链表之链表插入 | 第三套
数据结构单链表之删除节点 | 第四套
数据结构单链表之删除给定位置的链表节点 | 第五套
数据结构单链表之查看数组与链表的方法 | 第六套-1
数据结构单链表之查看数组与链表的方法 | 第六套-2
数据结构单链表之查找链表的长度(迭代和递归) | 第七套
数据结构单链表之交换链表中的节点而不交换数据 | 第八套
📣尾注: 想要获取更多数据结构相关的知识,你可以关注我:海拥,我希望你觉得这篇文章有帮助。
如果你看到这里,感谢你的阅读 :)
💌 欢迎大家在评论区提出意见和建议!💌
如果你真的从这篇文章中学到了一些新东西,喜欢它,收藏它并与你的小伙伴分享。🤗最后,不要忘了❤或📑支持一下哦。