数据结构——有序链表的合并,链表实现一元多项式相加

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;
}

注意一下对最后一项的处理就行。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值