已知两个以单链表形式存储的线性表,每个表均按照元素值递增此讯进行排列。请回答以下问题:
(1)编写算法,将这两个单链表合并为一个按元素值递减次序排列的单链表(要求:不额外增加任何存储空间,利用原来两个单链表的结点存放合并后的单链表)
(2)分析你所给出算法的时间复杂度
解题思路:jt将两个有序表合并为一个有序表,则使用归并排序,因为要得到元素值递减次序排列的单链表i哦,所以将元素值较小的元素头插入链表。
归并排序算法时间复杂度为O(nlogn)
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct Node
{
int data;
Node *next;
}Node,*List;
List head1=(List)malloc(sizeof(Node));
List head2=(List)malloc(sizeof(Node));
void build()
{
List ppre,p,q,qpre;
ppre=head1;
qpre=head2;
const int m=6;
const int n=5;
int a[m]={1,2,4,5,6,12};
int b[n]={2,3,7,8,11};
for(int i=0;i<m;i++)//尾插建立head1链表
{
List p=(List)malloc(sizeof(Node));
p->data=a[i];
ppre->next=p;
ppre=p;
}
ppre->next=NULL; //尾结点置空
for(int j=0;j<n;j++)//尾插建立head2链表
{
List q=(List)malloc(sizeof(Node));
q->data=b[j];
qpre->next=q;
qpre=q;
}
qpre->next=NULL;//尾结点置空
}
void merge(List head1,List head2)//与普通归并排序不同的是不允许使用额外的空间
{
List p,q;
p=head1->next;//p是第一个链表的指针
q=head2->next;//q是第二个链表的指针
head1->next=NULL;//将head1作为答案头
while(p!=NULL&&q!=NULL)
{
if(q->data < p->data)//将较小的元素头插,即可得到由大到小的序列
{
List cur=q;
q=q->next;
cur->next=head1->next;//对当前结点头插
head1->next=cur;
}
else
{
List cur=p;//临时存储p
p=p->next;
if(p->data==q->data)//如果值相等,则跳过q的值,保证值不重复
{
q=q->next;
}
cur->next=head1->next;
head1->next=cur;
}
}
if(p!=NULL)//若p未到链表尾,将p剩余元素头插接入链表
{
while(p!=NULL)
{
List cur=p;
p=p->next;
cur->next=head1->next;
head1->next=cur;
}
}
if(q!=NULL)//若q未到链表尾,将q剩余元素头插接入链表
{
while(q!=NULL)
{
List cur=q;
q=q->next;
cur->next=head1->next;
head1->next=cur;
}
}
}
void print (List head)
{
List p=head->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
}
int main()
{
build();
print(head1);
print(head2);
printf("\n");
merge(head1,head2);
print(head1);
return 0;
}