数据结构课程设计

news2024/12/26 22:11:19

数据结构课程设计

文章目录

  • 数据结构课程设计
    • 1.1问题描述
    • 1.2需求分析
    • 1.3概要设计
    • 1.4详细设计
    • 1.5调试分析
    • 1.6测试结果
    • 1.7参考文献
    • 1.8源码

1.1问题描述

编制一个能演示执行集合的交、并和差运算的程序。

要求:

  1. 集合元素用小写英文字母,执行各种操作应以对话方式执行。

  2. 算法要点:利用单链表表示集合;理解好三种运算的含义

1.2需求分析

分析

输入:输入应该具有判断是否为小写字母的功能,如果不是小写字母,应该舍去,同时打印有效输入给用户看,用来检查输入。并且应该去除用户输入的重复元素,满足集合的互异性。并且能处理好空集的问题。

结果:实现与用户的交互功能并且能输出集合的交、并和差运算的结果。对于无效输入,也要处理。

1.3概要设计

数据类型

采用的数据类型是单链表,单链表用来储存元素,方便后面的插入操作,具体实现如下所示:

	/*链表*/  
	typedef struct LNode{  
	    ElemType data;  
	    struct LNode * next;  
	}LinkNode;

流程:

主程序主要就是通过用户输入来判断执行哪些操作,首先是输入操作,既要避免无效输入(非小写字母),还要去重,最后还要将有效输入打印出来。

当输入为i(Intersection)的时候,调用Intersection()函数求交集,当输入为u(Union)的时候,调用Union()函数求并集,当输入为d(Difference)的时候,调用Difference()函数求差集,本次是将A – B输出,并且输出B – A。当输入为 q 时,程序结束。而当输入是无效输入的时候,也会提醒用户。

1.4详细设计

主函数伪代码

	int main() {  
	    定义3个链表;    
	    初始化链表;  
	    // InitList();   
	  
	    输入集合元素;   
	    //Input();  
	  
	    输出有效集合元素;   
	    //DispList();  
	  
	    while (flag)  
	    {  
	        打印功能菜单;   
	        //menu();  
	  
	        switch (选择) {  
	        case 'q':  
	            flag  <- 0;  
	            break;  
	        case 'i':  
	            求交集;   
	            //Intersection(L1, L2, L3);  
	            break;  
	        case 'u':  
	            求并集;   
	            //Union (L1, L2, L3);  
	            break;  
	        case 'd':  
	            求差集;   
	            //Difference(L1, L2, L3);  
	            break;  
	        default:  
	            处理无效输入;  
	            continue;  
	        }  
	    }  
	    结束;   
	    //return 0;  
	} 

主函数流程图:

在这里插入图片描述

交集伪代码:

	//交集  
	void Intersection(L1, L2, L3) {  
	    while (L1不为空) {  
	        while (L2不为空) {  
	            if (L1元素等于L2)  
	                break;  
	            else  
	                L2指向下一个元素;  
	        }  
	        if (找到相同元素) {  
	            插入L3 ;   
	        }  
	        L1指向下一个元素;  
	    }  
	} 

交集流程图:

在这里插入图片描述

并集伪代码:

	//并集  
	void Union (L1, L2, L3) {  
	    // 直接将L1赋给L3   
	    L3 = L1;   
	  
	    //对L2插入L3中  
	    while (L2 -> next != NULL) {  
	        if (L3没有这个元素) {   
	            将这个元素插入L3 ;   
	        }  
	        L2指向下一个元素;
	    }  
	} 

并集流程图:

在这里插入图片描述

差集伪代码:

1.	//差集  
2.	void Difference(L1, L2, L3) {  
3.	     while (L1不为空) {    
4.	            while (L2不为空) {    
5.	                if (L1元素等于L2)    
6.	                    break;    
7.	                else    
8.	                    L2指向下一个元素;    
9.	            }    
10.	            if (找到不同元素) {    
11.	                插入L3 ;     
12.	            }    
13.	        L1指向下一个元素;    
14.	        }    
15.	}

差集流程图:
在这里插入图片描述

1.5调试分析

调试过程中也是遇到一些问题的,首先就是单个功能测试正常,然后多次测试就失败了,然后一直在找具体原因,最后还是在删除L3链表的时候出了问题,因为自己的疏忽,不小心把L3链表全删了,导致第二次执行的时候,是找不到L3链表的,导致程序异常终止,后来经过修改,也是解决了这个问题。

以及对于输入,一开始觉得太复杂,就没有做去重操作,后来发现这样对于后面的操作带来了极大的不便,就将其修改为了去重。

对于算法复杂度,输入,交集,并集都是O(nm)的复杂度,目前没有什么好的优化方法,不过如果是改用高级语言,就可以用集合去解,也比较方便,而且如果用Python的话,这些操作都是自带的。

总结的话,还是要细心一点吧,特别是代码量一大,或者是函数调用比较多的时候,就容易犯错误,这个时候也不好修改,而且你也不知道到底是哪个环节出的问题。

1.6测试结果

测试输入:

1.	// 1、两个都正常并且有无效输入  
2.	qwerte12DRrtyu  
3.	sdfdFY0egr7tgrt  
4.	// 2、其中一个为空集  
5.	(空集)  
6.	rwqfwerrw  
7.	// 3、两个都为空集  
8.	(空集)  
9.	(空集) 

测试结果:

1、两个都正常并且有无效输入

在这里插入图片描述

2、其中一个为空集

在这里插入图片描述

3、两个都为空集

在这里插入图片描述

1.7参考文献

[1]李春葆主编;尹为民,蒋晶珏,喻丹丹,蒋林编著.数据结构教程 第5版[M].北京:清华大学出版社,2017

[2]史蒂芬·普拉达.C Primer Plus 第6版 中文版[M].北京:人民邮电出版社,2019

[3]史蒂芬·普拉达.C++ Primer Plus中文版[M].北京:人民邮电出版社,2019

1.8源码

#include<stdio.h>
#include<stdlib.h>

typedef char ElemType; /* ElemType类型根据实际情况而定 */

/*链表*/
typedef struct LNode{
	ElemType data;
	struct LNode * next;
}LinkNode;

//链表的初始化
void InitList(LinkNode* &L) {
    L = (LinkNode *)malloc(sizeof(LinkNode));
    L->next = NULL;
}

//去重输入操作
void Input(LinkNode* &L) {
    LinkNode* s, * p;    
    ElemType n;
    scanf("%c", &n);
    while (n != '\n') {
    	p = L ;
    	while (p && (p->data != n)) {//集合中不含有相同的元素
            p = p ->next;
        }
        if (p == NULL && n >= 97 && n <= 122) {
            s = (LinkNode*)malloc(sizeof(LinkNode));
            s->data = n;
            s->next = L->next;
            L->next = s;
        }
        scanf("%c", &n);
    }
}

不去重输入操作
//void Input(LinkNode* &L) {
//    LinkNode* s;    
//    ElemType n;
//    scanf("%c", &n);
//    while (n != '\n') {
//        if (n >= 97 && n <= 122) {
//            s = (LinkNode*)malloc(sizeof(LinkNode));
//            s->data = n;
//            s->next = L->next;
//            L->next = s;
//        }
//        scanf("%c", &n);
//    }
//}

//输出操作
void DispList(LinkNode * L)
{
	LinkNode * p = L -> next;
	if (!p) {    
        printf("空集\n");
        return;
    }
	while(p != NULL){
		printf("%c ", p -> data);
		p = p -> next;
	}
	printf("\n");
}
//链表的清空
void ClearList(LinkNode * &L) {
    LinkNode * pre = L, * p = L -> next;
    while (p != NULL) {
        pre = p;
        p = pre -> next; 
		free(pre);  
    }
    L -> next = NULL;
}

//集合的并
void Union (LinkNode *&L1, LinkNode *&L2, LinkNode *&L3) {
    LinkNode *p, *q, *s;
    // 如果输入去重
	L3 = L1; 
//    //如果未去重,对!1插入L3中
//    p = L1 -> next;
//    while (p) {
//        q = L3->next;
//        while (q && (q->data != p->data)) {//C3号中不含有与1号相同的元素
//            q = q->next;
//        }
//        if (q == NULL) {
//            s = (LinkNode*)malloc(sizeof(LinkNode));
//            s->data = p->data;
//            s->next = L3->next;
//            L3->next = s;
//        }
//        p = p->next;
//    }
    //对L2插入L3中
    p = L2 -> next;
    while (p) {
        q = L3->next;
        while (q && (q->data != p->data)) {//L3中不含有与L2相同的元素
            q = q->next;
        }
        if (q == NULL) {// //当q遍历完一次都没有找到的话,即q的最后为空时就可以将L2的元素插入L3中
            s = (LinkNode*)malloc(sizeof(LinkNode));
            s->data = p->data;
            s->next = L3->next;
            L3->next = s;
        }
        p = p->next;
    }
}


//交集
void Intersection(LinkNode *&L1, LinkNode *&L2, LinkNode *&L3) {
    LinkNode *p, *q, *r, *s;
    p = L1->next;//遍历L1
    while (p) {
        q = L2->next;//遍历L2
        while (q) {
            if (p->data == q->data)
                break;//找到相同的就返回
            else
                q = q->next;
        }
        if (q) {
                r = (LinkNode*)malloc(sizeof(LinkNode));
                r->data = p->data;
                r->next = L3->next;
                L3->next = r;
        }
        p = p->next;
    }
}


//差集
void Difference(LinkNode *&L1, LinkNode *&L2, LinkNode *&L3) {
    LinkNode *p, *q, *r;
    p = L1->next;//遍历L1
    while (p) {
        q = L2->next;
        while (q) {
            if (q->data == p->data)
                break;
            else
                q = q->next;
        }
        if (q == NULL) {//说明L2遍历完了,并且有不一样的
            r = (LinkNode*)malloc(sizeof(LinkNode));
            r->data = p->data;
            r->next = L3->next;
            L3->next = r;
        }
        p = p->next;
    }
}


void menu(){
	printf("                           功能菜单                          \n");
    printf("-------------------------------------------------------------\n");
    printf("| q---退出程序 | i---交集运算 | u---并集运算 | d---差集运算 |\n");
    printf("-------------------------------------------------------------\n");
}

int main() {
    LinkNode *L1, *L2, *L3;
    L1 = (LinkNode*)malloc(sizeof(LinkNode));
    L2 = (LinkNode*)malloc(sizeof(LinkNode));
    L3 = (LinkNode*)malloc(sizeof(LinkNode));
    InitList(L1);
    InitList(L2);
    InitList(L3);
    printf("请输入小写字母哦!\n");
    printf("请输入SetA: ");
    Input(L1);
    printf("SetA的有效输入为: ");
    DispList(L1);
    printf("请输入SetB: ");
    Input(L2);
    printf("SetB的有效输入为: ");
    DispList(L2);
    char i;
    int flag = 1;
    while (flag)
    {
    	menu();
        printf("请选择:");
        scanf("%c", &i);
        getchar();
        switch (i) {
        case 'q':
            flag = 0;
            printf("感谢您的使用!");
            break;
        case 'i':
            Intersection(L1, L2, L3);
            printf("交集是:");
            DispList(L3);
            ClearList(L3);
            break;
        case 'u':
            Union (L1, L2, L3);
            printf("并集是:");
            DispList(L3);
            ClearList(L3);
            break;
        case 'd':
            Difference(L1, L2, L3);
            printf("(A-B)差集是:");
            DispList(L3);
            ClearList(L3);
            printf("(B-A)差集是:");
            Difference(L2, L1, L3);
            DispList(L3);
            ClearList(L3);
            break;
        default:
            printf("无效输入!\n");
            continue;
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iOS 系统校园无线WIFI认证上网指南

无为WiFi介绍一下IOS手机怎么连接校园网&#xff0c;本介绍为普通途径连接使用校园网&#xff0c;想了解绕过校园网请看其他贴文。1. 打开无线网络&#xff08;WLAN&#xff09;开关2. 连接校园无线WiFi网络进入“设置”->“无线局域网”->在无线WiFi信号列表中选择“SWJ…

【从零开始学习深度学习】40. 算法优化之AdaGrad算法介绍及其Pytorch实现

之前介绍的梯度下降算法中&#xff0c;目标函数自变量的每一个元素在相同时间步都使用同一个学习率来自我迭代。例如&#xff0c;假设目标函数为fff&#xff0c;自变量为一个二维向量[x1,x2]⊤[x_1, x_2]^\top[x1​,x2​]⊤&#xff0c;该向量中每一个元素在迭代时都使用相同的…

线程安全详解

线程安全 线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中&#xff0c;线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行&#xff0c;不会出现数据污染等意外情况。 多个线程访问同一个对象时&#xff0c;如…

【docker11】docker安装常用软件

docker安装常用软件 1.安装软件说明 框架图 总体步骤&#xff1a; 搜索镜像拉去镜像查看镜像启动镜像 - 服务端口映射停止容器移除容器 1.安装tomcat docker hub上查找tomcat镜像 从docker hub上拉取tomcat镜像到本地 docker images查看是否有拉取到的tomcat 使用to…

Spring Security 导致 Spring Boot 跨域失效问题

1、CORS 是什么首先我们要明确&#xff0c;CORS 是什么&#xff0c;以及规范是如何要求的。这里只是梳理一下流程。CORS 全称是 Cross-Origin Resource Sharing&#xff0c;直译过来就是跨域资源共享。要理解这个概念就需要知道域、资源和同源策略这三个概念。域&#xff0c;指…

sahrding-jdbc的雪花算法取模为0或1的问题

工作时无意间发现sahrding-jdbc使用雪花算法生成的id 在某一业务分库分表 永远在那两个库表里面,排查后这里做下分享 环境、配置、问题介绍 16库16表使用的是org.apache.shardingsphere.core.strategy.keygen下面generateKey生成id分库表算法是对16取模生成数据永远在0库0表 0…

如何有效的防护暴力破解和撞库攻击

在网络威胁领域&#xff0c;暴力破解攻击仍然是网络犯罪分子非常喜爱且有利可图的攻击方法。&#xff0c;黑客通过收集互联网已泄露的用户和密码信息&#xff0c;生成对应的字典表&#xff0c;由于许多用户重复使用相同的用户名和密码&#xff0c;攻击者可以使用撞库攻击获得对…

前缀和算法

目录1.概述2.代码实现2.1.一维前缀和2.2.二维前缀和3.应用本文参考&#xff1a; LABULADONG 的算法网站 1.概述 前缀和算法分为一维和二维&#xff0c;一维前缀和可以快速求序列中某一段的和&#xff0c;而二维前缀和可以快速求一个矩阵中某个子矩阵的和。 2.代码实现 2.1.一…

约拍小程序开发,优化约拍产业路径

随着网红、直播经济的发展&#xff0c;年轻群体对于拍摄服务的需求正在急速增长&#xff0c;与此同时该群体用户又极具个性&#xff0c;很多传统影楼拍摄价格高、拍摄风格固定化、等待时间久&#xff0c;个人摄影师宣传推广难度又大&#xff0c;导致拍摄需求被抑制&#xff0c;…

_Linux多线程-基础篇

文章目录1. 什么是线程Linux中的线程叫做轻量级进程&#xff08;LWP&#xff09;2. 线程的优点3. 线程的缺点4. 线程异常5. 线程用途6. Linux进程VS线程单进程7. 总结线程在进程内部执行是OS调度的基本单位。不同视角看待进程轻量级进程1. 什么是线程 在一个程序里的一个执行路…

【Cfeng Work】 Open API的intro和 梳理

OpenAPI 开放平台 内容管理Open API intro腾讯云OpenAPIOpenAPI请求API密钥管理云API签名过程拼接规范请求串 CanonicalRequest拼接待签名字符串计算签名拼接到Authorization中云API签名失败规范Token 和 长期密钥公共参数OpenApi设计AppId、AppSecretsign签名timestamp 时间戳…

制造服务行业需要项目管理软件吗?

伴随着时代的快速发展&#xff0c;电子制造服务行业也正在飞速发展&#xff0c;在日新月异得时代步伐下&#xff0c;科学得管理方法和现代化得管理工具相结合&#xff0c;保证企业得进步与发展。项目管理工具通过构造高效统一的项目管理平台&#xff0c;优化企业管理中存在的问…

win10 conda安装labme安装和使用

1、安装conda 在WIN10中配置conda 1.1miniconda下载 https://docs.conda.io/en/latest/miniconda.html 可以任意选择对应的版本&#xff0c;安装时选择配置路径&#xff0c;以免后期重复配置环境。 1.2.2 在环境变量中添加路径 Win R&#xff0c;打开运行&#xff0c;输入…

在ubuntu系统上用pyinstaller加密打包yolov5项目代码的详细步骤

目录0. 背景1. 创建虚拟环境2. pyinstaller打包2.1. 生成并修改spec文件2.2. 重新生成二进制文件3. 测试4. 加密打包4.1. 创建入口函数main.py4.2. 修改detect.py4.3. 加密生成main.spec文件4.4. 修改main.spec文件4.5. 生成二进制文件4.6. 测试0. 背景 最近需要在ubuntu 18.0…

Payso×OceanBase:云上拓新,开启云数据库的智能托管

日前&#xff0c;聚合支付厂商 Payso&#xff08; 独角鲨北京科技有限公司&#xff09;的平台、交易系统引入 OceanBase 原生分布式数据库&#xff0c;实现显著降本增效—— 硬件成本降低 20&#xff5e;30%&#xff0c;查询效率提升 80%&#xff0c;执行效率提升了 30%&#x…

学习IB生物,我们需要知道什么知识点?

学习IB课程的很多同学应该都听说过一个说法&#xff1a;IB生物算是理科中的文科&#xff0c;没有公式推导&#xff0c;只有大量需要记忆的内容&#xff0c;不需要用学习理科的思维去学习&#xff0c;其实这种观点是有误区的。实际上&#xff0c;学习生物这门课将会面对的是一个…

01背包问题详解

目录 1.1二维dp数组 1.2一维dp数组改进 1.3相关例题 1.3.1分割等和子集 1.3.2一和零 1.1二维dp数组 概述&#xff1a;背包的最大重量是固定的&#xff0c;物品的数量&#xff0c;重量也是固定的&#xff0c;并且物品只能放一次&#xff0c;可以选择放或者不放&#xff0c…

Redis 核心原理串讲(中),架构演进之高可用

文章目录Redis 核心原理总览&#xff08;全局篇&#xff09;前言一、持久化1、RDB2、AOF3、AOF 重写4、混合持久化5、对比二、副本1、同步模式2、部分重同步三、哨兵1、核心能力2、节点通信总结Redis 核心原理总览&#xff08;全局篇&#xff09; 正文开始之前&#xff0c;我们…

【FPGA】Verilog:基本实验步骤演示 | 功能电路创建 | 添加仿真激励 | 观察记录仿真波形

前言&#xff1a; 本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载的完整过程、Verilog语言基本运用&#xff0c;电路设计和Test Bench程序的编写、以及实验开发板的使用&#xff0c;通过观察和数据记录理解仿真和FGPA实现的差异。 目录 Ⅰ. 基础知…

考研政治 马原 易混淆知识点

马哲 1. 哲学基本问题 从何者为第一性&#xff0c;分为唯物主义和唯心主义 从是否具有同一性&#xff0c;分为可知论&#xff08;有同一性&#xff09;和不可知论&#xff08;无同一性&#xff09; 辩证法&#xff1a;联系&#xff0c;发展的观点看世界&#xff0c;认为发展的…