设 A 为递减有序(元素值为整型)的单链表,B为递增有序(元素值为整型)的单链表,编写函数将 A 和 B 合并成一个递减有序的单链表,相同元素值只保留一个结点。
最为朴素的思想就是每次都遍历到B的最末尾,将该节点值与A的第一个节点的值作比较,取值较大的节点连到新链表中,但这样做的时间复杂度很高。
较快的方法是将链表B逆置,然后反复比较A,B链表的第一个节点的值,取值较大的节点连到新链表中,并跳指针,这样做只对A做了一次遍历,对B做了两次遍历,较前一种方法时间较快。
目录
声明
#include<iostream>
#include<fstream>
using namespace std;
typedef struct node
{
int data;
node* next;
}node;
逆置
逆置我在之前详细写过,可以看这个单链表基础操作_青耕_的博客-CSDN博客
void reverse(node* &head)
{
node* p = head->next;
node* nextp = p->next;
node* prep = NULL;
while (p != NULL)
{
p->next = prep;
prep = p;
p = nextp;
if (p == NULL)
break;
nextp = p->next;
}
head->next = prep;
}
合并
具体的思路如上,直接上代码
node* merge(node* head1, node* head2)
{
node* head = new node;
node* p = head;
node* nextp = NULL;
node* p1 = head1->next;
node* p2 = head2->next;
while (p1 != NULL || p2 != NULL)//反复寻找节点加入,直至A,B所有节点都被加入或删除(相同的留一个)
{
if (p1== NULL)
{
p->next = p2;
p = p->next;
//cout << p->data << ' ';
p2 = p2->next;
continue;
}
if (p2== NULL)
{
p->next = p1;
p = p->next;
//cout << p->data << ' ';
p1 = p1->next;
continue;
}
if (p1->data == p2->data)//相同的留一个
{
p->next = p1;
p = p->next;
p1 = p1->next;
node* temp = p2->next;
free(p2);
p2 = temp;
continue;
}
if (p1->data > p2->data)
{
p->next = p1;
p1 = p1->next;
}
else
{
p->next = p2;
p2 = p2->next;
}
p = p->next;
//cout << p->data << ' ';
}
p->next = NULL;
return head;
}
源代码
#include<iostream>
#include<fstream>
using namespace std;
typedef struct node
{
int data;
node* next;
}node;
void creat(char* s, node* &head)
{
int num;
fstream file(s, ios::in);
file >> num;
head = new node;
node* p = new node;
node* prep = head;
prep->next = p;
for (int i = 0; i < num; i++)
{
file >> p->data;
prep = p;
p = new node;
prep->next = p;
}
free(p);
prep->next = NULL;
file.close();
}
void reverse(node* &head)
{
node* p = head->next;
node* nextp = p->next;
node* prep = NULL;
while (p != NULL)
{
p->next = prep;
prep = p;
p = nextp;
if (p == NULL)
break;
nextp = p->next;
}
head->next = prep;
}
node* merge(node* head1, node* head2)
{
node* head = new node;
node* p = head;
node* nextp = NULL;
node* p1 = head1->next;
node* p2 = head2->next;
while (p1 != NULL || p2 != NULL)//反复寻找节点加入,直至A,B所有节点都被加入或删除(相同的留一个)
{
if (p1 == NULL)
{
p->next = p2;
p = p->next;
//cout << p->data << ' ';
p2 = p2->next;
continue;
}
if (p2 == NULL)
{
p->next = p1;
p = p->next;
//cout << p->data << ' ';
p1 = p1->next;
continue;
}
if (p1->data == p2->data)//相同的留一个
{
p->next = p1;
p = p->next;
p1 = p1->next;
node* temp = p2->next;
free(p2);
p2 = temp;
continue;
}
if (p1->data > p2->data)
{
p->next = p1;
p1 = p1->next;
}
else
{
p->next = p2;
p2 = p2->next;
}
p = p->next;
//cout << p->data << ' ';
}
p->next = NULL;
return head;
}
void print(node* head)
{
node* p = head->next;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
int main()
{
node* head1;//头结点指针,有专属头节点
node* head2;//头结点指针,有专属头节点
char name1[] = "text1.txt";
char name2[] = "text2.txt";
creat(name1, head1);
print(head1);
creat(name2, head2);
print(head2);
reverse(head2);
print(head2);
node* head = merge(head1, head2);
print(head);
}