第二章 线性表——课后习题解练【数据结构(c语言版 第2版)】

第二章 线性表

1.选择题

(1)(2)

答案:BA

(3)

(4)(5)(6)

答案:ADB

(7)

(8)

答案:A

(9)

(10)

答案:D

(11)

(12)(13)(14)

答案:DDA

(15)

2.算法设计题

(1)

void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {
    // 初始化指针
    pa = La->next;  // pa 指向 La 的第一个数据结点
    pb = Lb->next;  // pb 指向 Lb 的第一个数据结点
    
    // 使用 La 的头结点作为 Lc 的头结点
    Lc = pc = La;
    
    // 遍历两个链表,直到其中一个遍历完
    while (pa && pb) {
        // 如果 pa 的数据较小,将 pc 移动到新的尾结点,pa 后移指向下一个结点
        if (pa->data < pb->data) {
            pc->next = pa;
            pc = pa;         // pc 移动到新的尾结点
            pa = pa->next;   // pa 后移
        } 
        // 如果 pb 的数据较小,将 pb 结点链接到 pc 后面(新的尾结点),pb 后移指向下一个结点
        else if (pa->data > pb->data) {
            pc->next = pb;
            pc = pb;         // pc 移动到新的尾结点
            pb = pb->next;   // pb 后移
        }
        // 如果数据相等,取 La 的元素,删除 Lb 的元素
        else {
            pc->next = pa;
            pc = pa;         // pc 移动到新的尾结点
            pa = pa->next;   // pa 后移
            
            q = pb->next;    // 保存 pb 的下一个结点
            delete pb;       // 释放当前 pb 结点
            pb = q;          // pb 移动到下一个结点
        }
    }
    
    // 将剩余部分链接到结果链表尾部
    if (pa != NULL) {
        pc->next = pa;  // 如果 pa 不为空,链接 pa 剩余部分
    } else {
        pc->next = pb;  // 否则链接 pb 剩余部分
    }
    
    // 释放 Lb 的头结点
    delete Lb;
}

(2)

// 函数功能:合并两个有序链表La和Lb,结果存储在Lc中(使用头插法,结果为降序)
// 参数说明:
//   La, Lb: 待合并的两个有序链表(带头结点)
//   Lc: 合并后的结果链表
void union(LinkList& La, LinkList& Lb, LinkList& Lc) {
    // 初始化指针
    pa = La->next;  // pa指向La的第一个数据结点
    pb = Lb->next;  // pb指向Lb的第一个数据结点
    
    // 使用La的头结点作为Lc的头结点
    Lc = pc = La;
    Lc->next = NULL;  // 初始化Lc为空链表
    
    // 循环处理,直到两个链表都遍历完
    while (pa || pb) {
        // 选择较小的结点(或剩余结点)
        if (!pa) {          // 如果La已遍历完//if (!pa)等价于 if (pa == NULL)
            q = pb;         // 取Lb的当前结点
            pb = pb->next;  // pb指针后移
        }
        else if (!pb) {     // 如果Lb已遍历完
            q = pa;         // 取La的当前结点
            pa = pa->next;  // pa指针后移
        }
        // 比较两个链表的当前结点
        else if (pa->data <= pb->data) {  // La的结点值较小或相等
            q = pa;         // 取La的当前结点
            pa = pa->next;  // pa指针后移
        }
        else {              // Lb的结点值较小
            q = pb;         // 取Lb的当前结点
            pb = pb->next;  // pb指针后移
        }
        
        // 将选中的结点插入到Lc的头部(头插法)
        q->next = Lc->next;  // 新结点的next指向原Lc的第一个结点
        Lc->next = q;        // Lc的头结点指向新结点
    }
    
    // 释放Lb的头结点
    delete Lb;
}

(3)

// 函数功能:求两个有序链表La和Lb的交集,结果存储在Lc中
// 参数说明:
//   La, Lb: 输入的两个有序链表(带头结点)
//   Lc: 输出的结果链表
void Mix(LinkList& La, LinkList& Lb, LinkList& Lc) {
    // 初始化工作指针
    pa = La->next;  // pa指向La的第一个数据结点
    pb = Lb->next;  // pb指向Lb的第一个数据结点

    // 使用La的头结点作为Lc的头结点
    Lc = pc = La;

    // 遍历两个链表,直到其中一个遍历完
    while (pa && pb) {
        if (pa->data == pb->data) {
            // 情况1:当前结点值相等,将pa结点加入结果链表
            pc->next = pa;   // 将pa链接到结果链表
            pc = pa;         // pc移动到新的尾结点
            pa = pa->next;   // pa后移

            // 释放pb的当前结点(因为值相等,只需保留一个)
            q = pb;
            pb = pb->next;
            delete q;
        }
        else if (pa->data < pb->data) {
            // 情况2:pa结点值较小,直接释放pa结点
            q = pa;
            pa = pa->next;
            delete q;
        }
        else {
            // 情况3:pb结点值较小,直接释放pb结点
            q = pb;
            pb = pb->next;
            delete q;
        }
    }

    // 释放La的剩余结点(如果有)
    while (pa) {
        q = pa;
        pa = pa->next;
        delete q;
    }

    // 释放Lb的剩余结点(如果有)
    while (pb) {
        q = pb;
        pb = pb->next;
        delete q;
    }

    // 设置结果链表的尾结点
    pc->next = NULL;

    // 释放Lb的头结点(可选)
    delete Lb;
}

(4)

// 函数功能:求两个递增有序单链表的差集 A - B,结果存储在链表 A 中
// 参数说明:
//   A, B: 两个带头结点的递增有序单链表,分别存储一个集合
//   n: 结果集合元素个数的引用,调用时传入一个整型变量
void Difference(LinkedList A, LinkedList B, int &n) {
    // 初始化工作指针
    p = A->next;        // p 指向链表 A 的第一个数据结点
    q = B->next;        // q 指向链表 B 的第一个数据结点  
    head = A;           // head 指向 p 的前驱结点(即 A 的头结点)
    
    n = 0;              // 初始化计数器(引用可以直接赋值)

    // 同步遍历两个链表,直到其中一个遍历完
    while (p != NULL && q != NULL) {
        if (p->data < q->data) {
            // 情况1:A 的当前结点值小于 B 的当前结点值
            // 该结点属于差集,保留并继续处理
            head = p;           // head 指针后移,保持指向 p 的前驱
            p = p->next;        // p 指针后移
            n++;                // 差集元素个数加1(直接使用 n,不需要解引用)
        }
        else if (p->data > q->data) {
            // 情况2:A 的当前结点值大于 B 的当前结点值
            // B 需要继续向后查找可能相等的结点
            q = q->next;        // q 指针后移
        }
        else {
            // 情况3:A 和 B 的当前结点值相等
            // 该结点不属于差集,需要从 A 中删除
            head->next = p->next;    // 将前驱结点的 next 指向 p 的后继结点
            
            // 删除当前结点 p
            u = p;              // 保存要删除的结点
            p = p->next;        // p 指针后移
            delete u;           // 释放被删除结点的内存
        }
    }
    
    // 循环结束后,如果 A 还有剩余结点,它们都属于差集
    while (p != NULL) {
        n++;                    // 差集元素个数加1
        p = p->next;           // 继续遍历 A 的剩余结点
    }
}

(6)

// 函数功能:在单链表中查找最大值
// 参数说明:L是带头结点的单链表
// 返回值:链表中最大的元素值,若链表为空则返回NULL
int Max(LinkList L) {
    // 检查链表是否为空(只有头结点)
    if (L->next == NULL) {
        return NULL;
    }

    // 初始化指针
    LNode *pmax = L->next;    // 假设第一个结点为最大值
    LNode *p = L->next->next; // 从第二个结点开始遍历

    // 遍历链表查找最大值
    while (p != NULL) {
        // 如果当前结点值大于已知最大值
        if (p->data > pmax->data) {
            pmax = p;  // 更新最大值指针
        }
        p = p->next;   // 移动到下一个结点
    }

    // 返回最大值结点的数据
    return pmax->data;
}

(7)

// 函数功能:逆置带头结点的单链表
// 参数说明:L - 带头结点的单链表(引用传递)
void inverse(LinkList &L) {
    // 初始化指针
    LNode *p = L->next;  // p指向链表第一个结点
    L->next = NULL;       // 将头结点的next置空,准备重建链表

    // 遍历原链表,逐个结点逆置
    while (p != NULL) {
        LNode *q = p->next;  // q临时保存p的后继结点
        
        // 将当前结点p插入到新链表的头部(头结点之后)
        p->next = L->next;   // 将p的next指向原头结点的后继
        L->next = p;         // 头结点指向新的首元结点

        p = q;  // p移动到原链表的下一个结点
    }
}

(8)

void delete(LinkList &L, int mink, int maxk) {
    if (L == NULL || L->next == NULL) return; // 空链表直接返回

    LNode *pre = L;       // pre始终指向当前结点的前驱
    LNode *p = L->next;   // p从首元结点开始遍历

    while (p != NULL) {
        if (p->data > mink && p->data < maxk) {
            // 找到需要删除的结点
            pre->next = p->next; // 跳过当前结点
            LNode *temp = p;     // 临时保存要删除的结点
            p = p->next;         // p指针后移
            free(temp);          // 释放内存
        } else {
            // 不需要删除的结点
            pre = p;
            p = p->next;
        }
    }
}
内容概要:本文介绍了基于Matlab代码实现的【EI复现】考虑网络动态重构的分布式电源选址定容优化方法,重点研究在电力系统中结合网络动态重构技术进行分布式电源(如光伏、风电等)的最佳位置选择与容量配置的双层优化模型。该方法综合考虑配电网结构变化与电源布局之间的相互影响,通过优化算法实现系统损耗最小、电压稳定性提升及可再生能源消纳能力增强等多重目标。文中提供了完整的Matlab仿真代码与案例验证,便于复现实验结果并拓展应用于微网、储能配置与配电系统重构等相关领域。; 适合人群:电力系统、电气工程及其自动化等相关专业的研究生、科研人员及从事新能源规划与电网优化工作的工程师;具备一定Matlab编程基础和优化理论背景者更佳。; 使用场景及目标:①用于科研论文复现,特别是EI/SCI级别关于分布式能源优化配置的研究;②支【EI复现】考虑网络动态重构的分布式电源选址定容优化方法(Matlab代码实现)撑毕业设计、课题项目中的电源选址定容建模与仿真;③辅助实际电网规划中对分布式发电接入方案的评估与决策; 阅读建议:建议结合提供的网盘资源下载完整代码与工具包(如YALMIP),按照文档目录顺序逐步学,注重模型构建思路与代码实现细节的对应关系,并尝试在不同测试系统上调试与扩展功能。
本系统采用SpringBoot与Vue技术架构,实现了完整的影院票务管理解决方案,包含后台数据库及全套可执行代码。该系统在高等院校计算机专业毕业设计评审中获得优异评价,特别适用于正在进行毕业课题研究的学生群体,以及需要提升项目实践能力的开发者。同时也可作为课程结业作业或学期综合训项目使用。 系统提供完整的技术文档和经过全面测试的源代码,所有功能模块均通过多轮调试验证,保证系统稳定性和可执行性。该解决方案可直接应用于毕业设计答辩环节,其技术架构符合现代企业级开发规范,采用前后端分离模式,后端基于SpringBoot框架实现业务逻辑和数据处理,前端通过Vue.js构建用户交互界面。 系统核心功能涵盖影院管理、影片排期、座位预定、票务销售、用户管理等模块,实现了从影片上架到票务核销的完整业务流程。数据库设计遵循第三范式原则,确保数据一致性和完整性。代码结构采用分层架构设计,包含控制器层、服务层、数据访问层等标准组件,便于后续功能扩展和维护。 该项目不仅提供了可直接部署运行的完整程序,还包含详细的技术实现文档,帮助开发者深入理解系统架构设计理念和具体实现细节。对于计算机专业学生而言,通过研究该项目可以掌握企业级应用开发的全流程,包括需求分析、技术选型、系统设计和测试部署等关键环节。 资源来源于网络分享,仅用于学交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脑子不好真君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值