数据结构课程设计

数据结构课程设计

文章目录

  • 数据结构课程设计
    • 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;
}

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年12月12日
下一篇 2023年12月12日

相关推荐