李冬梅老师习题集第2章线性表--算法设计2,3,4,5

2将两个非递减的有序链表合并为一个非递增的有序链表。要求链表扔使用原来两个链表的存储空间,不另外占用其他存储空间。表中允许有重复数据。

算法思想:

从原来两个链表中依次再去节点,通过更改节点的指针域来重新建立元素之间的线性关系,得到一个新链表。关键点有2个:(1)保证新表与原表顺序相反,需要利用头插法建立单链表,而不能用尾插法(2)当一个表到达尾节点为NULL时,另一个非空表的剩余元素依次摘取,依次链接在LC的表头节点之后,而不能全部直接连接在LC表的最后(因为采用的是头插法)

假设待合并的链表LA,LB,合并后的新表LC(lc是头指针,lc=la,lc使用la链表的头结点)。pa是链表la的工作指针,pb是链表lb的工作指针,初始化为相应链表的首元节点。。从首元节点开始进行比较,当2个链表la和lb均未到达尾节点时,依次摘取其中较小者重新连接在lc表的头结点之后,如果当2个链表中的元素相等,只摘取la表中的元素,保留lb表中的元素。当一个表到达尾节点,且尾节点为NULL时,将非空表依次摘取,连接在LC表的头结点之后。。。最后释放lb的头结点

// 单链表逆序打印.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

// 单链表.cpp : Defines the entry point for the console application.
//



// 带头结点单链表.cpp : Defines the entry point for the console application.


#define readup ios::sync_with_stdio(0)

using namespace std;

typedef struct LNode
{
    int data;
    struct LNode* next;
}LNode, * LinkList;

void ReversePrint(LinkList firstNode)
{
    if (firstNode == NULL)return;

    ReversePrint(firstNode->next);
    cout << firstNode->data << ' ';
}
void print(LinkList first)
{
    if (first == NULL)return;
    cout << first->data << "  ";
    print(first->next);
}
void mergelist(LinkList& la, LinkList& lb, LinkList& lc)//算法设计题2
{
    LinkList pa = la->next;
    LinkList pb = lb->next;
    LinkList pc;
    lc = pc = la;
    LinkList q;
    lc->next = NULL;//一定不要忘记
    while (pa || pb)
    {
        if (pa == NULL)//la表为null,用q指向pb,pb指针后移
        {
            q = pb;
            pb = pb->next;
        }
        else if (pb == NULL)//lb表为空,用q指向pa,pa工作指针后移
        {
            q = pa;
            pa = pa->next;
        }
        else if (pa->data <= pb->data)//取较小者la中元素,q指向pa,pa指针后移
        {
            q = pa; pa = pa->next;
        }
        else
        {
            q = pb; pb = pb->next;//取较小者lb中元素,q指向pb,pb指针后移
        }
        q->next = lc->next; lc->next = q;//头插法
    }
    delete lb;//释放lb的头结点
}
void mergelist01(LinkList& la, LinkList& lb, LinkList& lc)//算法设计题2
{
    LinkList pa = la->next;
    LinkList pb = lb->next;
    LinkList pc = lc = la;
    lc->next = NULL;
    LinkList q = NULL;
    while (pa && pb)
    {
        if (pa->data <= pb->data)
        {
            q = pa; pa = pa->next;
        }else
        {
            q = pb; pb = pb->next;
        }
        q->next = lc->next; lc->next = q;
    }
    while (pa)
    {
        q = pa; pa = pa->next;
        q->next = lc->next; lc->next = q;
    }
    while (pb)
    {
        q = pb; pb = pb->next;
        q->next = lc->next; lc->next = q;
    }
    delete lb;
}
int main()
{
    int n;
    cin >> n;
    LinkList head = (LinkList)malloc(sizeof(LNode));
    head->next = NULL;
    LinkList tmp = NULL;
    LinkList cur = head;
    for (int i = 1; i <= n; i++)
    {
        tmp = (LinkList)malloc(sizeof(LNode));
        cin >> tmp->data;
        tmp->next = NULL;
        cur->next = tmp;
        cur = tmp;
    }
    print(head->next);
    int m; cin >> m;
    LinkList lb = (LinkList)malloc(sizeof(LNode));
    lb->next = NULL;
    LinkList rear = lb;
    for (int i = 1; i <= m; i++)
    {
        tmp = (LinkList)malloc(sizeof(LNode));
        cin >> tmp->data; tmp->next = NULL;
        rear->next = tmp; rear = tmp;
    }
    print(lb->next); cout << endl;
    LinkList lc;
    mergelist01(head,lb,lc);
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值