给定指向链表头节点的指针,任务是反转链表。我们需要通过改变节点之间的链接来反转列表。
例子:
输入:以下链表的头部
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)
