奇偶链表
题目描述:给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
示例 1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
示例 2:
输入: 2->1->3->5->6->4->7->NULL
输出: 2->3->6->7->1->5->4->NULL 说明:
- 应当保持奇数节点和偶数节点的相对顺序。
- 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。
题解思路:采用双指针p,q,分别指向奇数链表和偶数链表的第一个元素,同步遍历链表,将奇数点元素加入到odd链表中,偶数点元素加入到even链表中,当奇数点走到头时,将其最后一个结点的next指向even偶数指针即可。
- 注意点:如果链表个数是奇数,则q一定会走到空,而p则走到最后一个结点,此时只要将
p->next=even
即可;如果个数是偶数,则p,q同时走到空,所以一定要在声明一个指针,保存p的前一个不为空的结点
struct ListNode* oddEvenList(struct ListNode* head){
struct ListNode* odd,*even,*p,*q,*res,*temp;
res=head;
if(head&&head->next)
{
p=head;
q=head->next;
odd=p;
even=q;
while(p&&q)
{
if(p->next)
{
p->next=p->next->next;
}
if(q->next)
{
q->next=q->next->next;
}
temp=p;
p=p->next;
q=q->next;
if(p&&!p->next)
{
p->next=even;
}
if(!p)
{
p=temp;
p->next=even;
}
}
res=odd;
}
return res;
}
第二种方法就是遍历完第一遍,将奇数点结点加入到odd链表,偶数点结点加入到even链表,然后再遍历odd链表,将其最后一个结点的next指向even。
struct ListNode* oddEvenList(struct ListNode* head){
struct ListNode* odd,*even,*p,*q,*res;
res=head;
if(head&&head->next)
{
p=head;
q=head->next;
odd=p;
even=q;
while(p&&q)
{
if(p->next)
{
p->next=p->next->next;
}
if(q->next)
{
q->next=q->next->next;
}
p=p->next;
q=q->next;
}
p=odd;
while(p->next)
{
p=p->next;
}
p->next=even;
res=odd;
}
return res;
}