1、假设有两个按元素值递增次序排列的线性表,均以单链表形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
输入: 1 2 5 6 8
3 4 7 9 10
输出: 10 9 8 7 6 5 4 3 2 1
思路:利用尾插法,依次比较表头数据的大小,小的插入目标链表,而利用尾插法,即可倒置链表。
#include <iostream> #include<stdio.h> #include<malloc.h> #include<string.h> typedef struct node { int data; struct node *next; } List; List *CreateList() //创建链表,注意带头结点和不带头结点的区别 { List *head,*cnew,*tail; head = (List*)malloc(sizeof(List)); head->next = NULL; int num; while(1) { scanf("%d",&num); if(num==0)break; cnew = (List*)malloc(sizeof(List)); cnew->data = num; cnew->next = NULL; if(head->next==NULL) head->next = cnew; else tail->next = cnew; tail = cnew; } return head; } void showList(List *head) { List *p; p = head->next; while(p!=NULL) { printf("%d\t",p->data); p = p->next; } } List *List_merge(List *La,List *Lb) { List *p,*q,*r; p = La->next; La->next = NULL; q = Lb->next; while(p!=NULL&&q!=NULL) { if(p->data<q->data) //尾插法,结果与插入顺序相反 { r = p->next; p->next = La->next; La->next = p; p = r; } else { r = q->next; q->next = La->next; La->next = q; q = r; } } while(p!=NULL) { r = p->next; p->next = La->next; La->next = p; p = r; } while(q!= NULL) { r = q->next; q->next = La->next; La->next = q; q = r; } return La; } int main() { List *head1,*head2; head1 = CreateList(); head2 = CreateList(); head1 = List_merge(head1,head2); showList(head1); }
2.带头结点且头指针为ha和hb的两线性表A和B 分别表示两个集合。两表中的元素皆为递增有序。请写一算法求A和B的并集AUB。要求该并集中的元素仍保持递增有序。且要利用A和B的原有结点空间。
输入: 1 2 5 6 8
2 5 7 9
输出: 1 2 5 6 7 8 9
测试数据
输入:7 9 10 11
8 9 10 11
输出:7 8 9 10 11
思路同上,只不过在插入目标链表的时候不采用“尾插法”,而使用“头插法”,这样插入顺序与链表顺序一致
#include <iostream> #include<stdio.h> #include<malloc.h> using namespace std; typedef struct node{ int data; struct node *next; }List; List * CreateList() { List *head,*tail,*cnew; int num; head = (List*)malloc(sizeof(List)); head->next = NULL; while(1) { scanf("%d",&num); if(num==0)break; cnew = (List*)malloc(sizeof(List)); cnew->data = num; cnew->next = NULL; //此句至关重要,不可忽略 if(head->next==NULL){ head->next = cnew; } else tail->next = cnew; tail = cnew; } return head; } List showList(List *head) { List *p; p = head->next; while(p!=NULL) { printf("%d\t",p->data); p = p->next; } } List *merge_List(List *head1,List *head2) { List *La,*Lb,*r,*tail; La = head1->next; Lb = head2->next; head1->next = NULL; tail = head1; while(La!=NULL&&Lb!=NULL) { if(La->data<Lb->data) { r = La->next; tail->next = La; tail = tail->next; La = r; } else if(La->data>Lb->data){ r = Lb->next; tail->next = Lb; tail = tail->next; Lb = r; } else if(La->data=Lb->data) //要考虑到两个节点相等的情况,当相等时,不插入,工作指针移动到下个节点 { r = La->next; La = r; } } while(La!=NULL) { r = La->next; tail->next = La; tail = tail->next; La = r; } while(Lb!=NULL) { r = Lb->next; tail->next = Lb; tail = tail->next; Lb = r; } return head1; } int main() { List *head1,*head2; head1 = CreateList(); head2 = CreateList(); head1 = merge_List(head1,head2); showList(head1); }
3、知L1、L2分别为两循环单链表的头结点指针,m,n分别为L1、L2表中数据结点个数。要求设计一算法,用最快速度将两表合并成一个带头结点的循环单链表。
思路:移动L1链表的指针到链表尾,然后将其指向L2的首元节点,而后移动L2链表的指针到链表尾,将其指导L1的头指针即可
#include <iostream> #include<stdio.h> #include<malloc.h> using namespace std; typedef struct node{ int data; struct node *next; }List; List * CreateList() { List *head,*tail,*cnew; int num; head = (List*)malloc(sizeof(List)); head->next = NULL; while(1) { scanf("%d",&num); if(num==0)break; cnew = (List*)malloc(sizeof(List)); cnew->data = num; cnew->next = NULL; if(head->next==NULL) { head->next = cnew; } else { tail->next = cnew; } tail = cnew; } tail->next = head; return head; } List showList(List *head) { List *p; p = head->next; while(p!=head) { printf("%d\t",p->data); p = p->next; } } List *merge_List(List *head1,List *head2) { List *La,*Lb,*r,*tail1,*tail2; La = head1->next; tail1 = La; Lb = head2->next; tail2 = Lb; while(tail1->next!=head1) { tail1 = tail1->next; } tail1->next = Lb; while(tail2->next!=head2) { tail2 = tail2->next; } tail2->next = head1; return head1; } int main() { List *head1,*head2; head1 = CreateList(); head2 = CreateList(); head1 = merge_List(head1,head2); showList(head1); }