这种问题很经典,链表的求是否有环,以及链表数目为奇数或偶数返回中间节点,都可以不同步速率移动指针达到效果。非常棒
就地反转链表以前实习的时候遇到过一次,上次完全没准备什么东西,搞半天没有出结果。今天我来秒杀它
#include "stdio.h"
typedef struct Node{
int key;
struct Node *next;
}Lnode;
void buildLink(Lnode **head,int value)
{
Lnode *q=NULL;
Lnode *p = (Lnode *)malloc(sizeof(Lnode));
p->next = NULL;
p->key = value;
if(*head == NULL)
{
*head = p;
}
else
{
q= *head;
while(q->next != NULL)
{
q=q->next;
}
q->next =p;
}
}
Lnode *reverseLink(Lnode *head)
{
Lnode *p=NULL,*q=NULL,*r=NULL;
if(head==NULL ||head->next == NULL)
{
return head;
}
p=head;
q=p->next;
r=q->next;
if(r == NULL)
{
q->next=p;
p->next=NULL;
return q;
}
else
{
p->next=NULL;
while(r!=NULL)
{
q->next=p;
p=q;
q=r;
r=r->next;
}
q->next =p;
}
return q;
}
void freeList(Lnode *head)
{
Lnode *p;
while(head!=NULL)
{
p=head;
head = head->next;
free(p);
p=NULL;
}
}
int main()
{
Lnode *head=NULL;
Lnode *reverseHead = NULL;
int totalNum =10;
int index =0;
int value;
printf("total linknode num is: ");
scanf("%d",&totalNum);
for(;index<totalNum;index++)
{
scanf("%d",&value);
buildLink(&head,value);
}
reverseHead = reverseLink(head);
head = reverseHead;
while(reverseHead != NULL)
{
printf("%d ",reverseHead->key);
reverseHead = reverseHead->next;
}
freeList(head);
return 0;
}
实现过程中使用三个指针p,q,r
当然需要考虑边界条件,只有一个节点或没有节点,或2个节点 需要特殊处理。
一般三个节点 只要p,q,r个指针就够了,r用来记录当前链表剩余节点的首节点,q是需要查到p之前的节点,所以q每次从r上面取节点,然后查到p之前,然后p节点移到q节点处,依次从后往前建立节点。
另外一种带头结点的 直接插入法就行,足够简单
代码实现比较简单,但是需要考虑到两个地方的问题,就是若两个链表有一个或两个为空的时候,需要特殊处理,不能直接往后遍历
考虑过这以后,就可以进行归并了。技巧方面主要就是需要先去一个节点作为第一个节点,以后只要向后遍历即可。代码如下
#include "stdio.h"
typedef struct Node{
int key;
struct Node *next;
}Lnode;
void buildLink(Lnode **head,int value)
{
Lnode *q=NULL;
Lnode *p = (Lnode *)malloc(sizeof(Lnode));
p->next = NULL;
p->key = value;
if(*head == NULL)
{
*head = p;
}
else
{
q= *head;
while(q->next != NULL)
{
q=q->next;
}
q->next =p;
}
}
void freeList(Lnode *head)
{
Lnode *p;
while(head!=NULL)
{
p=head;
head = head->next;
free(p);
p=NULL;
}
}
Lnode *mergeLink(Lnode *head1,Lnode *head2)
{
Lnode *p= NULL;
Lnode *head=NULL;
if(head1==NULL)
{
return head2;
}
if(head2==NULL)
{
return head1;
}
if(head1->key<=head2->key)
{
p=head1;
head1=head1->next;
}
else
{
p=head2;
head2=head2->next;
}
head = p;
while(head1!=NULL&&head2!=NULL)
{
if(head1->key<=head2->key)
{
p->next=head1;
head1=head1->next;
p=p->next;
}
else
{
p->next = head2;
head2=head2->next;
p=p->next;
}
}
if(head1!=NULL)
{
p->next=head1;
}
if(head2!=NULL)
{
p->next=head2;
}
return head;
}
int main()
{
Lnode *head1=NULL;
Lnode *head2= NULL;
Lnode *head = NULL;
Lnode *traverse=NULL;
int totalNum =10;
int index =0;
int value;
printf("total linknode num is: ");
scanf("%d",&totalNum);
for(index=0;index<totalNum;index++)
{
scanf("%d",&value);
buildLink(&head1,value);
}
printf("total linknode num is: ");
scanf("%d",&totalNum);
for(index=0;index<totalNum;index++)
{
scanf("%d",&value);
buildLink(&head2,value);
}
head = mergeLink(head1,head2);
traverse =head;
while(traverse != NULL)
{
printf("%d ",traverse->key);
traverse = traverse->next;
}
freeList(head);
}