版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
链表的反转
1、迭代(C)
迭代好理解,是从链表头开始反转,直到链表的尾,这个方法要注意不能丢失后面的结点。
//结点
typedef struct Node{
int num;
struct Node *next;
}node;
//注意这里没有返回值,是因为这个链表带有头节点,反转的是头节点后面的部分
void exchange(node *pHead){
node *p=pHead;
node *m,*i,*j,*k;
k=m=p->next;
i=m->next;
while(i){
j=i->next;
i->next=m;
m=i;
i=j;
}
k->next=NULL;
p->next=m;
}
没有头节点的链表,可以加上以头结点,处理完成之后再去掉,这样可以简化操作步骤。
//结点
typedef struct Node{
int num;
struct Node *next;
}node;
//由于没有头节点,所以要有返回值
node* exchange(node *pHead){
//添加头节点
node* a=(node*)malloc(sizeof(noide));
a->next=pHead;
a=pHead;
//开始反转,与上面的步骤相同
node *p=pHead;
node *m,*i,*j,*k;
k=m=p->next;
i=m->next;
while(i){
j=i->next;
i->next=m;
m=i;
i=j;
}
k->next=NULL;
//p->next=m;直接将m返回,就是新的头指针,
free(a);
return m;
}
2、递归(Java)
反转不好操作的原因是会丢失上一个节点的地址,其实可以将每一个结点,压入一栈,之后再出栈,这样就不会出现找不到前驱结点的问题,可以从链表尾层层回退到链表头;
class Solution206 {
public ListNode NHead;//保存尾结点,就是之后的新头节点
//传入链表头
public ListNode reverseList(ListNode head) {
//链表为空直接返回
if(head==null){
return head;
}
//链表不空,开始递归
reverse(head);//开始递归
head.next=null;//头变成了尾巴,所以最后的结点的next置空
return NHead;
}
void reverse(ListNode tmp){
//将每个结点,从头到尾要入栈中,利用递归的调用处理方法
if(tmp.next!=null){
reverse(tmp.next);
tmp.next.next=tmp;//让前一个指向自己
}else
{
NHead=tmp;//找到尾结点并保存
return;
}
}
}