单链表的翻转是一道很基本的算法题。
方法1:将单链表储存为数组,然后按照数组的索引逆序进行反转。
方法2:使用三个指针遍历单链表,逐个链接点进行反转。
方法3:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
方法2:有3个指针,当前待处理节点的指针cur,因为cur要指向前一节点,因为要用指针记录前一节点pre,一旦cur指向的节点变化,那么就会出现断接,无法找到后续节点,所以要用save,保留cur的next节点
a1->a2->a3->a4
a1<-a2 a3->a4
方法3:创建一个头节点作为辅助手段,遍历所有节点,将其插入到头结点的后面。为了避免内存泄漏,要在结束时,将其释放掉。
#include <iostream>
#include<vector>
using namespace std;
typedef struct node
{
node *next;
int data;
node() :next(NULL), data(0){}
}node, *list;
void swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
node *change(vector<int> &a)
{
node *list = new node();
node *temp;
node *tail = list;
for (int i = 0; i < a.size(); i++)
{
temp = new node();
temp->data = a[i];
tail->next = temp;
tail = temp;
}
return list->next; //为了吻合题目,去掉头结点,注意这个地方有内存泄漏,丢掉了list
}
node *reverse2(list lis) //方法2,对应代码
{
node *pre=NULL;
node *cur=lis;
node *save;
while (cur != NULL)
{
save = cur->next;
cur->next = pre;
pre = cur;
cur = save;
}
return pre;
}
node *reverse3(list lis) //方法3,对应代码
{
node *head = new node();
while (lis)
{
node *temp = lis->next;
lis->next = head->next;
head->next = lis;
lis = temp;
}
node *res = head->next; //清除辅助head节点,避免内存泄漏
delete head;
return res;
}
void print(list lis)
{
while (lis)
{
cout << lis->data << " ";
lis = lis->next;
}
cout << endl;
}
int main()
{
vector<int> data = { 1,2,4,4,5,6};
list lis = change(data);
print(lis);
lis = reverse2(lis);
print(lis);
lis = reverse3(lis);
print(lis);
system("pause");
return 0;
}