这种问题很经典,链表的求是否有环,以及链表数目为奇数或偶数返回中间节点,都可以不同步速率移动指针达到效果。非常棒
就地反转链表以前实习的时候遇到过一次,上次完全没准备什么东西,搞半天没有出结果。今天我来秒杀它
#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); }