1.有序链表的合并
void Connect(LinkList a, LinkList b, LinkList& c)
{
LNode* pa, * pb, * pc;//三个结点指针
pa = a->next;//pa指向a链表的首元结点
pb = b->next;//pb指向b链表的首元结点
c = a;//c链表刚开始为只有a链表头结点的空表
pc = c;//pc指向头结点
while (pa && pb)
{
if (pa->data <= pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa ? pa : pb;
delete b;
}
注:合并的两条链表必须都是有序的
(1)初始化
LNode* pa, * pb, * pc;//三个结点指针
pa = a->next;//pa指向a链表的首元结点
pb = b->next;//pb指向b链表的首元结点
c = a;//c链表刚开始为只有a链表头结点的空表
pc = c;//pc指向头结点
pa与pb刚开始都是指向各自链表首元结点的结点指针。c链表初始化为只有a链表头结点的空表。pc指向该头结点。
(2)对两个链表进行有序遍历
while (pa && pb)
{
if (pa->data <= pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
直到a链表或者b链表有一方遍历完毕,while循环终止。每次都比较一下指针对应的数据域大小,选择较小的一方进行操作——结点接到pc指向的结点后面,更新pc指针,更新操作的指针。
(3)对没有遍历完的链表进行处理
pc->next = pa ? pa : pb;
运用三目运算符——pa?pa:pb是一个运算式,意思是:如果pa不为空那么返回pa,否则返回pb,这里让pc->next正好接上了没有遍历完的链表。
(4)删除b链表的头结点
delete b;
新链表已经用了a链表的头结点,b的头结点就没有用了,需要删除。
示例:
int main() {
LinkList L1, L2, L3;
int n, m;
cout << "输入第一条链表的长度和第二条链表的长度:";
cin >> n >> m;
CreateList_R(L1, n);
CreateList_R(L2, m);
Connect(L1, L2, L3);
LNode* p = L3->next;
cout << "合并后的有序链表为:";
while (p)
{
printf("%d ", p->data);
p = p->next;
}
return 0;
}
2.一元多项式相加
还是要用到有序表的合并。
(1)结点的定义
typedef struct LNode {
int zhishu;
int xishu;
struct LNode* next;
}LNode, *LinkList;//LinkList为指向结构体LNode的指针类型
结点类型变成两个数据域,一个指数,一个系数。
(2)一元多项式生成(尾插法)
void CreateList_R(LinkList& L, int n) {
LNode* p, * r;
L = new LNode;
L->next = NULL;
r = L;
for (int i = 0; i < n; i++)
{
p = new LNode;
cout << "请输入一组系数和指数:";
cin >> p->xishu >> p->zhishu;
r->next = p;
r = p;
}
cout << "链表生成完毕!"<< endl;
r->next = NULL;//双向循环链表改这个
}
整体相同,只不过一次要输入两个数据,分别代表系数和指数。
(3)有序表的合并(一元多项式版)
void Connect(LinkList a, LinkList b, LinkList& c)
{
LNode* pa, * pb, * pc;
pa = a->next;
pb = b->next;
c = a;
pc = c;
while (pa && pb)
{
if (pa->zhishu == pb->zhishu)
{
pc->next = pa;
pc = pa;
pc->xishu = pa->xishu + pb->xishu;
pa = pa->next;
pb = pb->next;
}
else if (pa->zhishu < pb->zhishu)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa ? pa : pb;
delete b;
}
初始化与单链表的合并相同。然后在while循环种有三种情况:指数相等,pa指数小于pb,pa指数大于pb。
1.指数相等:把pa指向的结点加入c链表,修改pc指向的结点,然后修改它的系数值为两者相加。同时移动pa与pb。
2.pa指数小于pb:把pa指向的结点加入c链表,修改pc指向的结点,移动pa。
3.pa指数大于pb:把pb指向的结点加入c链表,修改pc指向的结点,移动pb。
while循环结束后的步骤也与有序表合并相同。
示例: y1=1+x^2+x^3 y2=1+x^4+5x^6+x^7
int main() {
LinkList L1, L2, L3;
int n, m;
cout << "输入第一条链表的长度和第二条链表的长度:";
cin >> n >> m;
CreateList_R(L1, n);
CreateList_R(L2, m);
Connect(L1, L2, L3);
LNode* p = L3->next;
cout << "合并后的有序链表为:";
while (p)
{
if (p->next == NULL)//最后一项不用加'+',特殊处理
{
printf("%dx^%d", p->xishu, p->zhishu);
return 0;
}
printf("%dx^%d + ", p->xishu,p->zhishu);
p = p->next;
}
return 0;
}
注意一下对最后一项的处理就行。