学习的是↓
【强烈推荐】深入浅出数据结构 - 顶尖程序员图文讲解 - UP主翻译校对 (已完结)
以下为个人学习笔记(视频P9-P11)
三种方法实现反转一个链表[c++]
【前提:在main函数中我们将向Reverse函数
传递head指针(头结点)】
1、迭代法
①如果将head指针声明为全局变量,我们就可以在Reverse函数中直接使用全局变量head,不需要进行参数传入:
#include <iostream>
using namespace std;
struct Node {
int data;
Node *next;
};
Node *head = nullptr;//将head指针声明为全局变量
Node* Insert(int x)//尾插法
{
Node *temp = new Node();
temp->data = x;
temp->next = nullptr;
if (head == nullptr) {
head = temp;
} else {
Node *temp1 = head;
while (temp1->next != nullptr) {
temp1 = temp1->next;
}
temp1->next = temp;
}
return head;
}
void Print() {
Node *temp = head;
cout << "The List is:";
while (temp != nullptr) {
cout << temp->data;
temp = temp->next;
}
cout << endl;
}
// 迭代法反转链表
void Reverse() {
Node *current, *prev, *next;
current = head;
prev = nullptr;
while (current != nullptr) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
}
int main() {
head=nullptr;
Insert(2);
Insert(4);
Insert(5);
Print();
Reverse();Print();
return 0;
}
②在main函数中将head声明为局部变量,并且在ReverseAndPrint函数中不改变外部实际的head指针的值:
#include<iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* Insert(Node*& head, int x) {
Node* temp = new Node();
temp->data = x;
temp->next = NULL;
if(head == NULL) {
head = temp;
return head;
}
else {
Node* temp1 = head;
while(temp1->next != NULL) {
temp1 = temp1->next;
}
temp1->next = temp;
}
return head;
}
void Print(Node* head) {
cout << "The List is:";
Node* temp = head;
while(temp != NULL) {
cout << temp->data;
temp = temp->next;
}
cout << endl;
}
void ReverseAndPrint(Node* p) {
Node *current, *prev, *next;
current = p;
prev = nullptr;
while (current != nullptr) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
p = prev;
Print(p);//调用打印函数
//↓或者直接在ReverseAndPrint函数中打印
/*Node *temp = p;
cout << "The Reversed List is:";
while (temp != nullptr) {
cout << temp->data;
temp = temp->next;
}
cout << endl;*/
}
int main() {
Node* head = NULL;//既是声明又是定义
Insert(head, 2); Print(head);
Insert(head, 4); Print(head);
Insert(head, 6); Print(head);
ReverseAndPrint(head);
return 0;
}
这里ReverseAndPrint函数内部传入了参数head。
在 C++ 中,函数参数是按值传递的,即函数内部的操作不会影响到外部实际参数的值。虽然在函数内部对 head 指针进行了修改,但这只是修改了内部head指针的副本(复制品),并不影响外部实际的head指针的值。
想要在函数内部修改外部实际参数的值,可以将参数声明为引用或者使用指针的指针。
③在ReversePrint函数内部修改外部实际head指针的值
#include<iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* Insert(Node*& head, int x) {
Node* temp = new Node();
temp->data = x;
temp->next = NULL;
if(head == NULL) {
head = temp;
return head;
}
else {
Node* temp1 = head;
while(temp1->next != NULL) {
temp1 = temp1->next;
}
temp1->next = temp;
}
return head;
}
void Print(Node* head) {
cout << "The List is:";
Node* temp = head;
while(temp != NULL) {
cout << temp->data;
temp = temp->next;
}
cout << endl;
}
Node* Reverse(Node*& p) //将参数改为引用
{
Node* current, * next, * prev;
current = p;
prev = NULL;
while(current != NULL) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
p = prev;
return p;
}
int main() {
Node* head = NULL;
Insert(head, 2); Print(head);
Insert(head, 4); Print(head);
Insert(head, 6); Print(head);
Reverse(head); Print(head);
return 0;
}
2、递归法(只是反向打印链表,并不调转连接)
递归完成后依次返回,是从上一次调用的地方继续向下执行,执行完再返回上上次的调用点,再往下直至将最初一次调用结束
void Reverse(Node*p)
{
if(p==nullptr)
{
cout << "The List is:";
return;
}
Reverse(p->next);
cout << p->data;
}
3、递归法(调转连接)
void Reverse(Node*p)
{
if(p->next==nullptr){
head=p;
return;
}
Reverse(p->next);
Node*q=p->next;
q->next=p;
p->next=nullptr;
}