合并两个有序链表
思路(非递归):
- 合并成一个新的链表
- 用两个指针指向原来两个链表,用一个指针指向合并的新链表的尾部
- 比较两个链表元素的大小
- 核心代码
p3->next=p1; p3=p1; p1=p1->next;
1.插入元素
struct data* insert(struct data* head,struct data* p0)//有序 { struct data* p1=head,*p2; if(head==NULL) { head=p0; p0->next=NULL; } else { while(p0->data>p1->data&&p1->next!=NULL) { p2=p1; p1=p1->next; } if(p0->data<=p1->data)//插在头前或中间 { if(p1==head) head=p0; else p2->next=p0; p0->next=p1; } else//插在尾后 { p1->next=p0; p0->next=NULL; } } n++; return head; }
2.创建单向有序链表
struct data* creat() { struct data* head=NULL,*p; p=(struct data*)malloc(LEN); printf("Please input data:(end with 0)\n"); scanf("%d",&p->data); while(p->data) { head=insert(head,p);//插入后要赋值给head p=(struct data*)malloc(LEN); scanf("%d",&p->data); } free(p); return head; }
3.打印链表
void print(struct data* head) { struct data* p=head; if(head==NULL) printf("List is NULL.\n"); else { printf("Now,there are datas:\n"); do { printf("%d->",p->data); p=p->next; }while(p->next!=NULL); printf("%d\n",p->data); } }
4.合并两个有序链表
struct data* merge(struct data* head1,struct data* head2,struct data* head3) { struct data* p1=head1,*p2=head2,*p3=head3; if(head1==NULL) return head2; if(head2==NULL) return head1; while(p1!=NULL&&p2!=NULL) { if(p1->data<p2->data) { p3->next=p1; p3=p1; p1=p1->next; } else { p3->next=p2; p3=p2; p2=p2->next; } } p3->next=(p1!=NULL)?p1:p2; head3=head3->next; return head3; }
完整代码
#include<stdio.h> #include<malloc.h> #define LEN sizeof(struct data) struct data{ int data; struct data* next; }; int n=0; struct data* creat(); void print(struct data* head); struct data* insert(struct data* head,struct data* p); struct data* merge(struct data* head1,struct data* head2,struct data* head3); int main() { struct data* head1,*head2,*head3; head3=(struct data*)malloc(20*LEN);//一定要给heads开辟空间 head1=creat(); printf("List1:\n"); print(head1); head2=creat(); printf("List2:\n"); print(head2); printf("After merging:\n"); head3=merge(head1,head2,head3); print(head3); return 0; } struct data* insert(struct data* head,struct data* p0)//有序 { struct data* p1=head,*p2; if(head==NULL) { head=p0; p0->next=NULL; } else { while(p0->data>p1->data&&p1->next!=NULL) { p2=p1; p1=p1->next; } if(p0->data<=p1->data)//插在头前或中间 { if(p1==head) head=p0; else p2->next=p0; p0->next=p1; } else//插在尾后 { p1->next=p0; p0->next=NULL; } } n++; return head; } struct data* creat() { struct data* head=NULL,*p; p=(struct data*)malloc(LEN); printf("Please input data:(end with 0)\n"); scanf("%d",&p->data); while(p->data) { head=insert(head,p);//插入后要赋值给head p=(struct data*)malloc(LEN); scanf("%d",&p->data); } free(p); return head; } void print(struct data* head) { struct data* p=head; if(head==NULL) printf("List is NULL.\n"); else { printf("Now,there are datas:\n"); do { printf("%d->",p->data); p=p->next; }while(p->next!=NULL); printf("%d\n",p->data); } } struct data* merge(struct data* head1,struct data* head2,struct data* head3) { struct data* p1=head1,*p2=head2,*p3=head3; if(head1==NULL) return head2; if(head2==NULL) return head1; while(p1!=NULL&&p2!=NULL) { if(p1->data<p2->data) { p3->next=p1; p3=p1; p1=p1->next; } else { p3->next=p2; p3=p2; p2=p2->next; } } p3->next=(p1!=NULL)?p1:p2; head3=head3->next; return head3; }
递归版
struct data* merge(struct data* head1,struct data* head2)//用递归 { struct data* p1=head1,*p2=head2; if(head1==NULL) return head2; if(head2==NULL) return head1; if(p1->data<p2->data) { p1->next=merge(p1->next,p2); return head1; } else { p2->next=merge(p1,p2->next); return head2; } }
写链表会碰到的问题
- 调用函数的返回值是指针,需要赋给头指针
- 动态创建链表需要开辟新空间,结束要free没用了的指针