逆转单向链表
逆转单向链表是一个很基础很常见的问题,可惜在我最近面试的几个面试者中还是发现有的人写不好这个程序或者写的有问题.请看下面的实现,这也是大多数人聪明的人会想到的实现方法
typedef struct Node{
int data;
struct Node *next;
}node;
int data;
struct Node *next;
}node;
elementT *reverse(Node *p,Node *head)
{
if((!p)|| !(p->next))
{
head->next = p;
return p;
}
else
{
struct Node *temp = reverse(p->next,head);
temp->next = p;
p->next = NULL;
return p;
}
}
{
if((!p)|| !(p->next))
{
head->next = p;
return p;
}
else
{
struct Node *temp = reverse(p->next,head);
temp->next = p;
p->next = NULL;
return p;
}
}
传递两个指针,将head指向逆转后的头结点.但请注意我用粗体标注出来的那一行,很多人都会忘记掉这一行,那么忘记这一行的后果是什么呢? 答案很简单会形成一个死循环.所以使用递归时一定要注意.
所以我认为对于这个题目,如果对递归或链表不熟悉的话,我不是推荐用上面的方法,还是用传统的方法来的可靠
void reverse(Node **head)
{
if((!*head)|| !((*head)->next))
return;
struct Node *pre,*cur,*nex;
pre = NULL;
cur = (*head)->next;
while(cur)
{
nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
(*head)->next = pre;
return;
}
{
if((!*head)|| !((*head)->next))
return;
struct Node *pre,*cur,*nex;
pre = NULL;
cur = (*head)->next;
while(cur)
{
nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
(*head)->next = pre;
return;
}
比较容易想到,也不容易出错,但这里也要注意函数定义部分void reverse(Node **head),因为要改变头指针,所以要把一个指针传递给头指针.
下面我再提供一个递归实现,这种实现和我上面提供的递归实现还是有一些区别的,首选它不返回指针,其次把一个指针传递给了头指针.请大家好好体味一下.
void RecursiveReverse(Node **head)
{
struct Node *first;
struct Node *rest;
if(!(*head))
return;
first = *head;
rest = first->next;
if(!rest)
return;
RecursiveReverse(&rest);
first->next->next = first;
first->next = NULL;
*head = rest;
}
{
struct Node *first;
struct Node *rest;
if(!(*head))
return;
first = *head;
rest = first->next;
if(!rest)
return;
RecursiveReverse(&rest);
first->next->next = first;
first->next = NULL;
*head = rest;
}