链表反转
链表反转可通过迭代和递归两种方法实现。
迭代实现基本思想:把链表节点两两反转,直到下一个节点为空,最后让头节点指针域为空。
下面是代码:
ListNode* reverseList(ListNode* head) {
if(!head||!head->next){
return head;//当节点为空时不用反转
}
auto a=head;
auto b=a->next;
while(b){
auto c=b->next;
b->next=a;
a=b;
b=c;
}
head->next=NULL;
return a;
}
递归实现基本思想:要反转n个节点就要反转n-1个节点,每次反转后得到的结果应该是,头节点的下一个节点的指针域指向头节点,而头节点的指针域为空。(递归相当于把事情给员工去做,不问过程,只关注结果)
下面请看代码:
ListNode reverseList(ListNode head) {
if(!head||!head->next){
return head;
}
auto taile=reverseList(head->next);
head->next->next=head;
head->next=NULL;
return taile;
}
}
下面请看链表反转升级版
题目基本思想
本题在上一题的基础上指定了反转的长度,并且两头需要调转。(此题需要给定一个虚拟头节点,这可以省去判断如果left在首节点的情况)
看代码:
ListNode* reverseBetween(ListNode* head, int left, int right) {
auto pHead=new ListNode(-1);
pHead->next=head;
auto a=pHead;
for(int i=0;i<left-1;i++){
a=a->next;
}
auto b=a->next;
auto c=b->next;
int j;
for(j=0;j<(right-left);j++){//进行内部链表反转
auto d=c->next;
c->next=b;
b=c;
c=d;
}
a->next->next=c;
a->next=b;
return pHead->next;
}