将一个链表反转。如1->2->3->4->5->NULL,反转后变成5->4->3->2->1->NULL
struct list
{
int data;
struct list *next;
};
list* converseList(list *head)
{
list newHead = NULL; //记录反转后的头结点
list pre = NULL; //记录前驱结点
list p = head; //当前工作结点
list pNext = NULL; //当前工作结点的下一个结点
while(p)
{
pNext = p->next;
if(pNext == NULL)
newHead = p;
p->next = pre;
pre = p;
p = pNext;
}
return newHead;
}
面试过程中,如果你顺利写出上面的代码,面试官会加大难度,让你写一个该程序的变式版本。如:
该题可以改成反转该链表的前K个结点。
如原链表为1->2->3->4->5->NULL,反转前3个链表,则结果为3->2->1->4->5->NULL
list* kConverseList(list* head, int k)
{
if(head == NULL)
{
printf("list is NULL\n");
return NULL;
}
int i = 1;
list* p = head;
//找到第k+1个结点
while(i <= k && p)
{
p = p->next;
i++;
}
//如果链表长度小于k,则返回NULL
if(i < k && p == NULL)
{
printf("length of list is less than k\n");
return NULL;
}
//反转前k个链表
list* end = p;
p = head;
list* pre = end;
list* newHead = NULL;
list* pNext = NULL;
while(p != end)
{
pNext = p->next;
if(pNext == end)
{
newHead = p;
}
p->next = pre;
pre = p;
p = pNext;
}
return newHead;
}
这个题目还可以变形为(这个好像是携程网2015校园招聘的笔试题):
原链表为1->2->3->4->5->NULL,k=3,输出结果为3->2->1->5->4->NULL
list* kConverseListV2(list* head, int k)
{
if(head == NULL)
{
printf("list is NULL\n");
return NULL;
}
int i = 1;
list* p = head;
while(i <= k && p)
{
p = p->next;
i++;
}
if(i < k && p == NULL)
{
printf("length of list is less than k\n");
return NULL;
}
list* end = p; //这个用于记录第k+1个结点,因为第k个结点的next结点就是此结点
list* converseTail = converseList(p); //现将后面的结点反转,记录反转后的“头”结点
p = head;
list* pre = converseTail; //
list* newHead = NULL;
list* pNext = NULL;
while(p != end)
{
pNext = p->next;
if(pNext == end)
{
newHead = p;
}
p->next = pre;
pre = p;
p = pNext;
}
return newHead;
}
待续。。。。。。。。