数据结构课程设计报告 合并果子问题

合集下载

数据结构课程设计 链表合并

数据结构课程设计 链表合并

数据结构课程设计链表合并数据结构课程设计 - 链表合并概述:在数据结构课程设计中,链表合并是一个常见的问题。

本文将详细介绍链表合并的概念、算法和实现方法,并提供代码示例和详细解释。

1. 链表的基本概念链表是一种常见的数据结构,用于存储和组织数据。

链表由一系列节点组成,每一个节点包含一个数据元素和一个指向下一个节点的指针。

链表的第一个节点称为头节点,最后一个节点的指针指向空。

2. 链表合并的定义链表合并是指将两个有序链表合并成一个有序链表的操作。

合并后的链表应保持有序性。

3. 链表合并的算法链表合并可以使用迭代或者递归算法来实现。

3.1 迭代算法迭代算法通过比较两个链表的节点值,挨次选择较小的节点插入到新链表中。

具体步骤如下:- 创建一个新链表和一个指向新链表尾部的指针。

- 比较两个链表的节点值,选择较小的节点插入到新链表中,并更新指针。

- 如果其中一个链表为空,将另一个链表的剩余部份直接插入到新链表中。

- 返回新链表的头节点。

3.2 递归算法递归算法通过递归地合并链表的子链表来实现链表合并。

具体步骤如下:- 如果其中一个链表为空,返回另一个链表。

- 比较两个链表的头节点值,选择较小的节点作为合并后的头节点。

- 递归调用合并函数,将较小节点的下一个节点与另一个链表合并,并将结果作为当前节点的下一个节点。

- 返回合并后的头节点。

4. 链表合并的实现方法下面是使用C++语言实现链表合并的示例代码:```cpp#include <iostream>struct ListNode {int val;ListNode* next;ListNode(int x) : val(x), next(NULL) {}};ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {if (l1 == NULL) return l2;if (l2 == NULL) return l1;ListNode* head = NULL;ListNode* tail = NULL;if (l1->val <= l2->val) {head = l1;l1 = l1->next;} else {head = l2;l2 = l2->next;}tail = head;while (l1 != NULL && l2 != NULL) { if (l1->val <= l2->val) {tail->next = l1;l1 = l1->next;} else {tail->next = l2;l2 = l2->next;}tail = tail->next;}if (l1 != NULL) {tail->next = l1;}if (l2 != NULL) {tail->next = l2;}return head;}int main() {// 创建链表1: 1 -> 2 -> 4ListNode* l1 = new ListNode(1);l1->next = new ListNode(2);l1->next->next = new ListNode(4);// 创建链表2: 1 -> 3 -> 4ListNode* l2 = new ListNode(1);l2->next = new ListNode(3);l2->next->next = new ListNode(4);// 合并链表ListNode* mergedList = mergeTwoLists(l1, l2); // 打印合并后的链表ListNode* current = mergedList;while (current != NULL) {std::cout << current->val << " ";current = current->next;}return 0;}```以上代码使用迭代算法实现了两个有序链表的合并。

数据结构 求集合并集交集实验报告

数据结构 求集合并集交集实验报告

实验报告题目:集合的并、交和差运算班级:13信息管理姓名:刘学号:20130403012 完成日期:20,11一、需求分析1[问题描述]编制一个能演示执行集合的并、交和差运算的程序。

2[基本要求](1)集合的元素限定为整数。

(2)用链式存储结构完成。

3.测试数据set1={ 1 2 3 4 5 },set2={ 3 4 5 6 7 }set1∪set2={ 1 2 3 4 5 6 7 };set1∩set2={ 3 4 5 }set1-set2={ 1 2 }二、编码实现1.存储类型typedef struct LNode{int data;struct LNode *next;}LNode,*LinkList;2.部分函数的伪码算法//构造一个集合void CreateList_L(LinkList &L){LinkList p;int n,i;printf("请输入元素个数:\n");scanf("%d",&n);L=(LinkList)malloc(sizeof(LNode));L->next=NULL;printf("请一次输入各个元素:\n");for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));scanf("%d",&p->data);p->next=L->next;L->next=p;}}//取出数据值int get_data(LinkList h){int t;t=h->data;return t;}//删除与t相同的节点LinkList del(LinkList L1,int t){LinkList p1,p2;p1=L1->next;while(t!=p1->data&&p1->next!=NULL){p2=p1,p1=p1->next;}if(t==p1->data){if(p1==L1->next)L1->next=p1->next;elsep2->next=p1->next;}return L1;}//打印集合void printf_L(LinkList &L){LinkList h;h=L->next;while(h){printf(" %d ",h->data);h=h->next;}}//集合排序void sort(LinkList &L){LinkList p=L->next,q,r;if(p){r=p->next;p->next=NULL;p=r;}while(p){r=p->next;q=L;while(q->next!=NULL&&q->next->data<p->data) q=q->next;p->next=q->next;q->next=p;p=r;}}//集合并集void combine(LinkList &L1,LinkList L2){LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1->next;while(p->next){if(p->data==p->next->data){h=p->next;p->next=h->next;free(h);}elsep=p->next;}}//集合的差void differ(LinkList L1,LinkList L2){int t;LinkList h;h=L2->next;while(h){t=get_data(h);L1=del(L1,t);h=h->next;}}//交集void intersectLink(LinkList L1,LinkList L2) {LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1;while(p->next->next){h=p->next->next;if(p->next->data!=h->data){p->next=h;h=h->next;}elsep=p->next;}p->next=NULL;}三、调试分析1,说实话,自己根本不会做,参考网上的资料都做不出来;2,自己做的程序,没有任何错误,但就是不能运行;3,对链表的认识不够深入,不知道如何构造链表,以及实现各种操作;四、测试结果set1={ 1 2 3 4 5 },set2={ 3 4 5 6 7 }set1∪set2={ 1 2 3 4 5 6 7 };set1∩set2={ 3 4 5 }set1-set2={ 1 2 }五.附录#include<stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode,*LinkList;//构建集合函数void CreateList_L(LinkList &L){LinkList p;int n,;i;printf("请输入元素个数:\n");scanf("%d",&n);L=(LinkList)malloc(sizeof(LNode));L->next=NULL;printf("请一次输入各个元素:\n");for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));scanf("%d",&p->data);p->next=L->next;L->next=p;}}//获取数据函数int get_data(LinkList h){int t;t=h->data;return t;}//删除函数LinkList del(LinkList L1,int t){LinkList p1,p2;p1=L1->next;while(t!=p1->data&&p1->next!=NULL){p2=p1,p1=p1->next;}if(t==p1->data){if(p1==L1->next)L1->next=p1->next;elsep2->next=p1->next;}return L1;}//打印函数void printf_L(LinkList &L){LinkList h;h=L->next;while(h){printf(" %d ",h->data);h=h->next;}}//排序void sort(LinkList &L){LinkList p=L->next,q,r;if(p){r=p->next;p->next=NULL;p=r;}while(p){r=p->next;q=L;while(q->next!=NULL&&q->next->data<p->data) q=q->next;p->next=q->next;q->next=p;p=r;}}//并集void combine(LinkList &L1,LinkList L2)LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1->next;while(p->next){if(p->data==p->next->data){h=p->next;p->next=h->next;free(h);}elsep=p->next;}}//求差void differ(LinkList L1,LinkList L2) {int t;LinkList h;h=L2->next;while(h){t=get_data(h);L1=del(L1,t);h=h->next;}}//交集void intersect(LinkList L1,LinkList L2) {LinkList p,h;p=L1;while(p->next){p=p->next;}p->next=L2->next;sort(L1);p=L1;while(p->next->next){h=p->next->next;if(p->next->data!=h->data){p->next=h;h=h->next;}elsep=p->next;}p->next=NULL;}//主函数int main(){LinkList L1,L2;int t;printf("求集合交集请按1\n求集合并集请按2\n请集合之差请按3\n");scanf("%d",&t);while(t!=0){switch(t){case 1:CreateList_L(L1);CreateList_L(L2);intersect(L1,L2);sort(L1);printf_L(L1);break;case 2:CreateList_L(L1);CreateList_L(L2);combine(L1,L2);sort(L1);printf_L(L1);break;case 3:CreateList_L(L1);CreateList_L(L2);differ(L1,L2);sort(L1);printf_L(L1);break;default :printf("error\n");}scanf("%d",&t);}return 0;}11。

合并两个链表课程设计

合并两个链表课程设计

合并两个链表课程设计一、课程目标知识目标:1. 学生能理解链表的概念,掌握链表的基本操作,如插入、删除节点。

2. 学生能理解合并两个链表的过程,掌握合并算法的实现。

3. 学生能理解递归思想,并运用递归方法解决合并链表问题。

技能目标:1. 学生能运用所学知识,独立编写合并两个链表的程序。

2. 学生能够通过调试程序,找出并修正链表操作中的错误。

3. 学生能运用所学算法,解决实际问题,提高编程能力。

情感态度价值观目标:1. 学生培养对数据结构与算法的兴趣,认识到编程解决问题的价值。

2. 学生培养合作精神,学会在团队中分享、讨论和解决问题。

3. 学生培养良好的编程习惯,注重代码规范,提高代码质量。

分析课程性质、学生特点和教学要求:本课程为计算机科学或信息技术相关课程的章节,适用于高年级学生。

学生在学习本章节前,已具备基本的编程能力和数据结构知识。

课程旨在巩固学生的链表知识,提高编程技能,培养解决实际问题的能力。

课程目标具体、可衡量,旨在使学生能够独立完成合并两个链表的任务,并通过教学设计和评估,确保学生达到预期学习成果。

二、教学内容1. 链表基础知识回顾:包括链表的定义、节点结构、链表的分类(单向链表、双向链表等)。

2. 链表基本操作:插入、删除节点的方法及实现,重点讲解递归在链表操作中的应用。

3. 合并两个链表的概念:介绍合并链表的意义,分析合并过程中需注意的问题。

4. 合并算法讲解:详细讲解两种合并链表的方法(非递归和递归方法),并分析其优缺点。

5. 编程实践:指导学生编写合并两个链表的程序,要求学生独立完成,并注重代码规范。

6. 调试与优化:教授学生如何调试链表程序,找出并修正错误,提高程序性能。

教学内容安排和进度:1. 第一课时:回顾链表基础知识,讲解链表基本操作。

2. 第二课时:介绍合并两个链表的概念,讲解合并算法。

3. 第三课时:指导学生进行编程实践,完成合并链表的程序。

4. 第四课时:学生展示编程成果,讨论和解决编程过程中遇到的问题,进行调试与优化。

数据结构实验报告 有序表的合并(优质参考)

数据结构实验报告 有序表的合并(优质参考)

数据结构实验报告实验题目:有序表的合并姓名:张耀班级:计嵌151学号: 1513052017一、实验目的把两个有序表归并为一个有序表。

二、数据结构设计(1)存储设计:采用带头结点的单链表存储数据。

输入:数据通过键盘有序输入输出:屏幕显示两个有序表及归并后的表(2)函数设计:CreateList(int n);// 创建具有n个元素的线性链表ListDisplay();//输出表元素Combine(LinkList LA, LinkList LB);//归并单链表LA,LB(3)两个有序表合并算法描述:Step1:初始化。

1.1设置工作指针pa,pb,分别指向两个有序表LA,LB的首元结点。

1.2生成新表LC的头结点,工作指针pc指向LC。

Step2:只要pa和pb有所指,循环执行下列操作。

2.1生成一新节点,链到LC表尾,pc指向它。

2.2如果pa->data<=pb->data:pc->data=pa->data;pa后移。

2.3否则:pc->data=pb->data;pb后移。

Step3:如果pa空,把pb开始的结点依次复制到pc后。

Step4: 如果pb空,把pa开始的结点依次复制到pc后。

三、算法设计与N-S图(1)算法设计:求归并表的过程是在元素有序的情况下不断地从两表中取出元素,添加到新表中,所以元素采取表尾插入。

设两个有序表SA,SB,归并后的有序表为SC,取元素的过程是:依次扫描SA,SB中的元素,比较当前元素的值,将较小的元素赋给SC,直到一个顺序有序表扫描完毕,然后将另一个顺序有序表中余下元素复制到SC中。

(2)程序流程图开始初始化:pa = LA.Head->next; pb = LB.Head->next;pc = Head;pa和pb都不为空生成新节点,连接到LC表尾,pc指向它pa->data<=pb->datapc->data = pb->data;pb = pb->next;pc->data = pa->data;pa = pa->next;pa==N ULLPb!=NULL把pb开始的结点依次复制到pc后面pb==N ULLPa!=NULL把pa开始的结点依次复制到pc后面四、程序清单#include<iostream>using namespace std;结束#include"process.h"struct Node{int data;//数据域,存放表元素Node *next;//指针域,指向下一个结点};class LinkList{private:Node *Head;// 链表头指针public:LinkList();//构造函数,创建空链表void CreateList(int n);//创建具有n个元素的线性链表void ListDisplay();//输出表元素void Combine(LinkList, LinkList);//合并};LinkList::LinkList(){//构建函数,建一空链表Head = new Node;Head->next = NULL;}void LinkList::CreateList(int n){//尾插法(正序)创建具有n个元素的线性表Node *p, *s;//设置工作指针。

语言数据结构实验报告链表的合并-7页word资料

语言数据结构实验报告链表的合并-7页word资料

《数据结构》实验报告◎实验题目:合并两个链表:设A与B分别为两个带有头结点的有序循环链表(所谓有序是指链接点按数据域值大小链接,本题不妨设按数据域值从小到大排列),list1和list2分别为指向两个链表的头指针。

请写出将这两个链表合并为一个带头结点的有序循环链表的算法。

◎实验目的:使用顺序表的创建、插入、删除、合并等操作编写关于数据结构的程序。

◎实验内容:写出程序并上机调试、通过。

一、需求分析1、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“Please input the first list”时输入第一个链表的元素个数和元素。

当出现“Please input the second list”时输入第二个链表的元素个数和元素。

然后计算机终端输出合并后的链表。

2、输出的形式为两个链表中的元素合并成一个链表并且其中元素按照递增的顺序排列。

3、程序执行的命令包括:(1)构造含n个元素的循环链表;(2)输入数据;(3)将输入的数据作成循环链表;(4)合并;(5)输出;(6)结束。

4、本程序能将两个链表合并成一个链表。

并且合并后的链表中的元素是原来两个链表中的元素按照递增顺序的排列。

5、输入及输出示例:例1:Please input the first list41 3 7 9Please input the second list51 2 5 6 8Output the mergelist1 2 3 5 6 7 8 9Press any key to continue例2:Please input the first list51 2 5 9 11Please input the second list31 2 8Output the mergelist1 2 5 8 9 11Press any key to continue二概要设计1.基本操作本程序中,用单向有序循环链表作为存储结构。

数据结构课程设计实现两个链表的合并讲课讲稿

数据结构课程设计实现两个链表的合并讲课讲稿

数据结构课程设计实现两个链表的合并一、需求分析:题目:实现两个链表的合并问题描述:1. 建立两个链表A和B,链表元素个数分别为m和n个。

2. 假设元素分别为(x1,x2,…xm),和(y1,y2, …yn)。

把它们合并成一个线形表C,使得:当m>=n时,C=x1,y1,x2,y2,...xn,yn, (x)当n>m时,C=y1,x1,y2,x2,…ym,xm,…,yn输出线性表C。

由题目的相关信息可以分析得到:首先我们需要建立两个链表AB,A链表的元素个数为m;B链表的元素个数为n;在将A\B链表进行合并,更具m和n的大小关系决定链表C的元素顺序;再将C经行直接插入排序得到一个新的链表D;最后输出ABCD的相关信息。

二、算法的流程图三、算法设计分析这个两个链表的交叉合并算法主要运用到的是链表的基本操作,定义节点,将链表的创建、计算链表的长度、链表A,B的交叉组合、链表内容升序排列、删除链表指定位置元素、删除指定的元素等算法写成了独立函数,通过主函数调用。

这样就大大精简了主函数的操作。

但主函数中很大篇幅用到了if、else语句,用以指定链表指定结点和指定元素的删除操作,这样就使得本来很精简变得繁琐,降低了程序的质量。

所以其有优点和缺点,但需要不断的改进,不断优化该程序。

四、源代码程序源代码:#include<stdio.h>#include<stdlib.h>typedef struct node //节点定义{int data;struct node *next;} node,*linklist;linklist creat(linklist head) //该函数用来创建链表{node *r,*s;int a;r = (linklist)malloc(sizeof(node));head = r;scanf("%d",&a);while(a != 0){s =(node*)malloc(sizeof(node));s->data=a;r->next=s;r=s;printf("please input a data:");scanf("%d",&a);}r->next=NULL;return head;}linklist length(linklist l) // 返回L中数据元素个数{int i=0;linklist p=l->next; // p指向第一个结点while(p){i++;p=p->next;}return i;}linklist mergel(linklist A,linklist B) //用于实现链表A,B的交叉组合 {int m,n;node *p,*q,*s,*t;linklist C;p=A->next;q=B->next;m=length(A);n=length(B);C=A;if(m<n){p=B->next;q=A->next;C=B;}while(p&&q){s=p->next;p->next=q;if(s){t=q->next;q->next=s;}p=s;q=t;}return C;}linklist sort(linklist L) //链表内容升序排列{linklist p,q,min;int temp;p=L;while( p=p->next ){q=min=p;while(q=q->next){if( q->data<min->data )min = q;}if( min!=p ){temp = p->data;p->data = min->data;min->data=temp;}}return L;}linklist Delete(linklist l,int index) //删除链表指定位置元素{ linklist p,t;int cx=1; //用于计数p=l;if(index<length(l)){while(p&&(cx<index)){t=p;p=p->next;cx++;}t->next=p->next;}elseprintf("input indext error");return l;}linklist Delete_element(linklist l,int data) //删除指定的元素{ linklist p;p=l;if(p->next){while(p->next->data!=data){p=p->next;}p->next=p->next->next;}elseprintf("don't faind the element");return l;}linklist display(linklist l) //打印{ linklist p;printf("new linklist :\n");p = l->next;while(p){printf("%d\n",p->data);p= p->next;}return l;}main(){linklist p,q,A,B,C,D;int indexs;int datas;char name;int cmd;printf("Creat linklist A:\n"); //创建A链表,并打印printf("please input a data:");A = creat(A);printf("Creat linklist B:\n"); //创建B链表,并打印printf("please input a data:");B = creat(B);C = mergel(A,B); //生成C链表,并打印 printf("linklist C\n");p = C->next;while(p){printf("%d\n",p->data);p=p->next;}D=C; //对C进行排序生成D sort(D);printf("linklist D:\n");q = D->next;while(q){printf("%d\n",q->data);q = q->next;}printf("\nplease input 0 or 1 \n");//用1和0判断是按位置删除还是直接删除元素scanf("%d",&cmd);if(cmd==0) //位置删除{printf("please input linklist name\n ");fflush(stdin);scanf("%c",&name);printf("\nplease input index \n");scanf("%d",&indexs);fflush(stdin);if(name=='A'){Delete(A,indexs);display(A);}else if(name=='B'){Delete(B,indexs);display(B);}else if(name=='C'){Delete(C,indexs);display(C);}else if(name=='D'){Delete(D,indexs);display(D);}elseprintf("nameError");}else if(cmd==1) //元素删除{fflush(stdin); //清除缓冲printf("please input linklist name\n ");//fflush(stdin);scanf("%c",&name);printf("\nplease input datas \n");scanf("%d",&datas);if(name=='A'){Delete_element(A,datas);display(A);}else if(name=='B'){Delete_element(B,datas);display(B);}else if(name=='C'){Delete_element(C,datas);display(C);}else if(name=='D'){Delete_element(D,datas);display(D);}elseprintf("name2error");}elseprintf("cmdError");printf("\nOver\n");getchar();return 0;}六、实验运行结果显示:设计体会及今后改进的意见;短短一周的数据结构课程设计结束了,回想着这一周自己的表现,感觉不是很满意,感到自己许多不足之处。

(完整word版)数据结构课程设计_集合的并、交和差运算(word文档良心出品)

(完整word版)数据结构课程设计_集合的并、交和差运算(word文档良心出品)

一、课程题目会合的并、交和差运算二、问题描绘功能:编制一个能演示履行会合的并、交和差运算的程序。

三、基本要求1)会合的元素限制为小写字母字符【‘ a’ ..‘ z’】2)演示程序以用户和计算机的对话方式履行。

四、测试数据(1) Set1= ”magazine ” , Set2= ’ paper ” ,Set1∪Set2= ”aegimnprz ” ,Set1∩Set2= ”ae” ,Set1-Set2=”gimnz”;(2) Set1= ” 012oper4a6tion89 ”,Set2= ”error data ” , Set1 ∪Set2= ” adeinoprt ” ,Set1 ∩Set2= ” aeort ” , Set1-Set2= ” inp ” .五、算法思想为了实现上述程序的功能,应以有序链表表示会合。

为此,需要两个抽象数据种类:有序表和会合。

1、有序表的抽象数据种类定义为:input(linklist l)初始条件: l 是以 l 为头节点的空链表。

操作结果:生成以l 为头节点的非空链表。

output(linklist l)初始条件: l 是以 l 为头节点的非空链表。

操作结果:将以l 为头节点的链表中数据逐一输出。

2、会合的抽象数据种类定义为:heji(linklist A,linklist B,linklist C)初始条件:链表A、B、C 已存在操作结果:生成一个由 A 和 B 的并集组成的会合C。

jiaoji(linklist A,linklist B ,linklist ,C)初始条件:链表A、B、C 已存在操作结果:生成一个由 A 和 B 的交集组成的会合C。

六、模块化分本程序抱含四个模块:1)节点构造单元模块——定义有序表的节点构造;2)有序表单元模块——实现有序表的抽象数据种类;3)会合单元模块——实现会合获取抽象数据种类;4)主程序模块:Void main () {初始化;do{接授命令;办理命令;}while (“命令” != “退出”);}七、源程序#include<stdio.h>#include<string.h>#include<stdlib.h>#include<conio.h>typedef struct node{int data;struct node* next;}lnode,*linklist;lnode *init_lnode();void input(linklist l);void jiaoji(linklist A,linklist B,linklist C); void heji(linklist A,linklist B,linklist C); void output(linklist l);void main(){lnode *a,*b,*c;a=init_lnode();b=init_lnode();c=init_lnode();printf(" 求 AB 会合的交集和并集\n");printf(" 请输入 A 会合的元素 :");input(a);printf("\n 请输入 B 会合的元素 :");input(b);printf("\n 输入达成 \n");printf("\n 按随意键进入主菜单:");getch();do{char menu[]={"\n\n\n-----☆ 1.交集运算☆---------\n\n""--------- ☆ 2 和集运算☆ ---------\n\n""--------- ☆3.差集运算☆---------\n\n""--------- ☆ 0.退出☆ ---------\n\n" };printf("%s",menu);printf("\n 请在 0-3 中选择 :");scanf("%d",&sel);switch(sel){case 1:printf("AB会合的交集是:");jiaoji(A,B,C);output(C);C->next=NULL;break;case 2:printf("AB的合集是:");heji(A,B,C);output(C);C->next=NULL;break;case 3:chaji(A,B,C);break;case 0:break;}}while(sel!=0);}/* 主函数结束 */ /**********初始化函数 ***************/lnode * init_lnode(){lnode *l;l=(lnode *)malloc(sizeof(lnode));l->next=NULL;return l;}/***************录入函数 ********************/ void input(linklist l){lnode *s;int x;scanf("%d",&x);while(x!=0){s=(lnode *)malloc(sizeof(lnode));s->data=x;s->next=l->next;l->next=s;scanf("%d",&x);}}/************交集函数 *********************/ void jiaoji(linklist A,linklist B,linklist C){lnode *p,*q,*t;p=A->next;while(p!=NULL){q=B->next;while((q!=NULL)&&(q->data!=p->data))q=q->next;if((q!=NULL)&&(q->data==p->data)){t=(lnode*)malloc(sizeof(lnode));t->data=p->data;t->next=C->next;C->next=t;}p=p->next;}}/***********输出函数 *****************/void output(linklist l){lnode *s;s=l->next;while(s!=NULL){printf("%5d",s->data);s=s->next;}printf("\n");}/******** 并集函数 *************************/ void heji(linklist A,linklist B,linklist C){lnode *p,*q,*t;p=A->next;while(p!=NULL){t=(lnode*)malloc(sizeof(lnode));t->data=p->data;t->next=C->next;C->next=t;p=p->next;}q=B->next;while(q!=NULL){p=A->next;while((p!=NULL)&&(p->data!=q->data))p=p->next;if (p==NULL){t=(lnode*)malloc(sizeof (lnode));t->data=q->data;t->next=C->next;C->next=t;}q=q->next;}/*********************差集函数 ****************/ void chaji(linklist A,linklist B, linklist C){lnode *p,*q,*s,*t;p=A->next;printf("A与B的差集是:\n");while(p!=NULL){q=B->next;while((q!=NULL)&&(p->data!=q->data))q=q->next;if(q==NULL){s=(lnode*)malloc(sizeof(lnode));s->data=p->data;s->next=C->next;C->next=s;}p=p->next;}output(C);C->next=NULL;q=B->next;printf("B 与 A 的差集是 :\n");while(q!=NULL){p=A->next;while((p!=NULL)&&(p->data!=q->data)) p=p->next;if(p==NULL){t=(lnode*)malloc(sizeof(lnode));t->data=q->data;t->next=C->next;C->next=t;}q=q->next;}output(C);}} 四、测试数据及程序运转状况程序运转结果 :八、心得领会1、因为对会合的三种运算的算法斟酌不足,在链表种类及其尾指针的设置时出现错误,以致程序低效。

两线性表的合并 数据结构实验报告

两线性表的合并 数据结构实验报告
⒉ 在初次编好后,每次运行时发现第一次输入的数据必须要多了,导致线性表有点混乱, 最后发现是输入语句都多了一个“\n”所导致的,删除后就正常了。
3.程序采用逐个输入的方法创建 La,Lb,在元素较多时,会使得程序很庞大,不利于检查错
误等。
4. 算法的时空分析
各操作的算法时间复杂度比较合理 initlist 为 O(1)printList,delsame,change,creatlist 为 O(l.length), addList 为 O(la.length*lb.length)。
六、测试结果
在 TC2.0 中运行得到的结果如下图所示:
5
七、附录:源程序 #include<stdio.h> #include<malloc.h>
#define listinitsize 100 #define OVERFLOW -1
/*线性表的定义*/ typedef struct sqlist {
} while(i<=la.length)
{ lc.a[k]=la.a[i]; k++; i++; } while(j<=lb.length) { lc.a[k]=lb.a[j]; k++; j++;
7
} lc.length=k-1; return lc; } /*打印线性表*/ void printlist(sqlist l) { int i=1; for(i=1;i<=l.length;i++)
printf("%6d",l.a[i]); printf("\n"); } /*删除线性表中的相同的元素*/ sqlist delsame(sqlist L) { int i,j,k; if(L.length>0) {

数据结构课程设计实现两个链表的合并

数据结构课程设计实现两个链表的合并

一、需求分析:题目:实现两个链表的合并问题描述:1. 建立两个链表 A 和 B,链表元素个数分别为 m 和n 个。

2. 假设元素分别为(x1,x2,…xm),和(y1,y2, …yn)。

把它们合并成一个线形表 C,使得:当 m>=n 时,C=x1,y1,x2,y2, ...xn,yn, (x)当 n>m 时,C=y1,x1,y2,x2, …ym,xm,…,yn输出线性表 C。

由题目的相关信息可以分析得到:首先我们需要建立两个链表 AB,A 链表的元素个数为m;B 链表的元素个数为n;在将链表进行合并,更具 m 和n 的大小关系决定链表 C 的元素顺序;再将C 经行直接插入排序得到一个新的链表 D;最后输出 ABCD 的相关信息。

二、算法的流程图开始Creat A链表Creat B链表Mergel(A,B)合并成C对C排序生成D提示输入 0 或者 1错误输入Cmd error链表的名字正确 错误表的名字正确 错误删除, 打印 Nameerror 删除,打印 Nameerror打印“over ”结束三、 算法设计分析这个两个链表的交叉合并算法主要运用到的是链表的基本操作,定义 节点,将链表的创建、计算链表的长度、链表 A,B 的交叉组合、链表内容升 序罗列、删除链表指定位置元素、删除指定的元素等算法写成为了独立函数, 通过主函数调用。

这样就大大精简了主函数的操作。

但主函数中很大篇幅用 到了 if 、else 语句, 用以指定链表指定结点和指定元素的删除操作, 这样就 使得本来很精简变得繁琐,降低了程序的质量。

所以其有优点和缺点,但需 要不断的改进,不断优化该程序。

cmd=1输入将要操作的链 cmd=0输入将要操作的四、源代码程序源代码:#include<stdio.h>#include<stdlib.h>typedef struct node//节点定义{int data;struct node *next;} node,*linklist;linklist creat(linklist head) //该函数用来创建链表{node *r,*s;int a;r = (linklist)malloc(sizeof(node));head = r ;while(a != 0){s =(node*)malloc(sizeof(node));s->data=a;r->next=s;r=s ;}r->next=NULL;return head;}linklist length(linklist l) // 返回 L 中数据元素个数{int i=0;linklist p=l->next; // p 指向第一个结点while(p){i++;p=p->next;}return i;}linklist mergel(linklist A,linklist B) //用于实现链表 A,B 的交叉组合{int m,n;node *p,*q,*s,*t;linklist C;p=A->next;q=B->next;m=length(A);n=length(B);C=A;if(m<n){p=B->next;q=A->next;C=B;}while(p&&q){s=p->next;p->next=q;if(s){t=q->next;q->next=s;}p=s;q=t;}return C;}linklist sort(linklist L) //链表内容升序罗列{linklist p,q,min;int temp;p=L;while( p=p->next ){q=min=p;while(q=q->next){if( q->data<min->data )min = q;}if( min!=p ){temp = p->data;p->data = min->data;min->data=temp;}}return L;}linklist Delete(linklist l,int index) //删除链表指定位置元素{ linklist p,t;int cx=1; //用于计数p=l;if(index<length(l)){while(p&&(cx<index)){t=p;p=p->next;cx++;}t->next=p->next;}elsereturn l;}linklist Delete_element(linklist l,int data) //删除指定的元素{ linklist p;p=l;if(p->next){while(p->next->data!=data){p=p->next;}p->next=p->next->next;}elsereturn l;}linklist display(linklist l) //打印{ linklist p;p = l->next;while(p){p= p->next;}return l;}main(){linklist p,q,A,B,C,D;int indexs;int datas;char name;int cmd ;A = creat(A);B = creat(B);C = mergel(A,B);p = C->next;while(p){p=p->next;创建 A 链表,并打印创建 B 链表,并打印//生成 C 链表,并打印}//对 C 进行排序生成D D=C;sort (D) ;q = D->next;while(q){q = q->next;}//用 1 和 0 判断是按位置删除还是直接删除元素//位置删除if(cmd==0){fflush(stdin);fflush(stdin);if(name=='A'){Delete(A,indexs);display(A);}else if(name=='B'){Delete(B,indexs);display(B);}else if(name=='C'){Delete(C,indexs);display(C);}else if(name=='D'){}elseDelete(D,indexs);display(D); } else}else if(cmd==1) {fflush(stdin);//fflush(stdin);//元素删除//清除缓冲if(name=='A') {Delete_element(A,datas);display(A);}else if(name=='B') {Delete_element(B,datas);display(B);}else if(name=='C') {Delete_element(C,datas);display(C);}else if(name=='D') {Delete_element(D,datas);display(D);} elsegetchar();return 0;}六、实验运行结果显示:设计体味及今后改进的意见;短短一周的数据结构课程设计结束了,回想着这一周自己的表现,感觉不是很满意,感到自己许多不足之处。

数据结构实训报告

数据结构实训报告

《数据结构》课程设计报告题目:实现两个链表的合并班级:08计管(2)班姓名:袁文珠学号:0803011229指导教师:肖丽娜2010年6月17日目录一、课程设计的性质、目的及要求 (3)一、课程设计性质 (3)二、设计目的 (3)三、设计要求 (3)二、任务描述 (3)三、软件环境 (4)四、算法设计思想及流程图 (4)一、算法设计思想 (4)二、流程图 (5)五、源代码 (6)六、运行结果 (9)七、收获及体会 (10)一、课程设计的性质、目的及要求一、课程设计性质性质:数据结构设计是《数据结构》课程的实践环节,也是我院各专业必修的计算机技术基础课程之一。

二、设计目的目的:课程设计为学生提供了一个既动手又动脑,独立实践的机会,学生将课本上的理论知识和实际有机的结合起来,锻炼学生分析、解决较复杂问题的能力,本次课程设计,也是为了锻炼我们应用编程语言的语法规则和已经掌握的一些较为简单的算法,自己解决一个较简单的课题,初步积累编程经验。

提高学生独立编写大编程的能力。

三、设计要求计算机科学是一门研究数据表示和数据处理的科学。

数据是计算机化的信息,是计算机可以直接处理的最基本和最重要的对象。

无论是进行科学计算,数据处理,过程控制,还是对文件的存储和检索及数据库技术的应用,都是对数据进行加工处理的过程。

希望通过学习掌握程序设计的方法与编程技术,我们能学会良好的程序设计风格,为在计算机不同领域的应用打下坚实的基础。

希望通过本次的学习,我们能利用计算机解决实际题。

与此同时,希望能通过此次的实训来提高我们的思维能力,促进我们的综合应用能力和我们的专业素质。

二、任务描述实现两个链表的合并基本功能要求:1、建立两个链表A和B,链表元素的个数没别为m和n个。

2、假设元素分别为(x1,x2,···xm),和(y1,y2,···yn)。

把他们合并成一个线性表C,使得:当m>=n时,C=x1,y1,x2,y2,···xn,yn,···xm当n>m时,C=y1,x1,y2,x2,···ym,xm,···,yn输出线性表C3、用直接插入排序法对C进行升序排序,生成表D,并输出表A,B,C,D。

数据结构课程设计报告--集合的并、交和差运算

数据结构课程设计报告--集合的并、交和差运算

题目:集合的并、交和差运算【问题描述】编制一个能演示执行集合的并、交和差运算的程序。

【基本要求】(1) 集合的元素限定为小写字母字符[‘a’..’z’] 。

(2) 演示程序以用户和计算机的对话方式执行。

【测试数据】(1)Set1="magazine",Set2="paper",Set1∪Set2="aegimnprz",Setl ∩Set2="ae",Set1-Set2="gimnz"。

(2)Set1= " 012oper4a6tion89",Set2="error data",Set1∪Set2="adeinoprt",Setl ∩Set2="aeort",Set1-Set2="inp"。

【实现提示】以有序链表表示集合。

【选作内容】(1) 集合的元素判定和子集判定运算。

(2) 求集合的补集。

(3) 集合的混合运算表达式求值。

(4) 集合的元素类型推广到其他类型,甚至任意类型。

一、实验内容实验题目:编制一个演示集合的并、交和差运算的程序。

需求分析:1、本演示程序中,集合的元素限定为小写字母字符[“a”…”z”]。

集合输入的形式为一个以“回车符“为结束标志的字符串,串中字符顺序不限。

2、演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息“之后,由用户在键盘上输入演示程序中规定的运算命令;相应的输入数据和运算结果显示在其后。

3、程序执行的命令包括:1)构造集合1;2)构造在集合2;3)求并集;4)求交集;5)求差集;6)返回;7)结束。

“构造集合1”和“构造集合2”时,需以字符的形式键入集合元素。

二、数据结构设计为了实现上述程序的功能,应以有序链表表示集合。

为此,需要两个抽象数据类型:有序表和集合。

数据结构课设报告_集合的并、交和差运算的程序

数据结构课设报告_集合的并、交和差运算的程序

目录1.需求分析 11.1问题描述: 11.2基本要求: 11.3测试数据: 12.概要设计 12.1.集合的数据类型定义为: 12.2.各种函数的功能: 23.详细设计 24.编码实现 45.调试分析 65.1程序运行界面如下图: 65.2遇到的问题以及解决方法: 76.课设总结 77.参考文献 81.需求分析1.1问题描述:编制一个能演示执行集合的并、交和差运算的程序。

1.2基本要求:⑴集合的元素限定为小写字母符[′a′….′z ′],集合的大小n<27。

⑵集合输入的形式为一个以"回车符"为结束标志的字符串,串中字符顺序不限,且允许出现重复字符或非法字符,程序应能自动滤去。

⑶输出的运算结果字符串中将不含重复字符或非法字符。

⑷演示程序以用户和计算机的对话方式执行。

1.3测试数据:(1)输入集合个数为2,分别为{a,b,e,d,f},{c,f,g,n},选择集合运算类型为求集合的交集。

(2)输入集合个数为3,分别为{a,b,c},{g,h,n,k},{k,z,a},选择运算类型为求集合的并集。

(3)输入集合个数为2,分别为{b,c,d},{c,d,f,},选择运算类型为集合的差(4)输入集合个数为2,分别为{a,b,x,&,1,3,4},{a,b,c,f,g,1,4},选择集合的运算类型为集合的并集。

2.概要设计2.1.集合的数据类型定义为:struct Set{int num;bool hash[30];}num为集合的元素个数hash为利用哈希表,用来储存集合的元素。

2.2.各种函数的功能:1.void InitSet(Set &Res)操作结果:初始化集合的函数,函数参数为引用类型。

2.Set DealSet(char *s)初始条件:指针s不为空操作结果:将字符串处理成集合,生成的集合为函数返回值。

3.void PriSet(Set s)操作结果:打印集合s。

国家开放大学《数据结构》课程实验报告(实验3 ——栈、队列、递归设计)参考答案

国家开放大学《数据结构》课程实验报告(实验3 ——栈、队列、递归设计)参考答案
}
/*判队空*/
int QueueEmpty(SeqQueue *sq)
{
if(sq->rear==sq->front)
return 1;
else
return 0;
}
/*循环队列入队*/
void InQueue(SeqQueue *sq,ElemType x)
{
if ((sq->rear+1)%MaxSize==sq->front) /*队满*/
InitStack(s);
printf("(2)栈为%s\n",(StackEmpty(s)?"空":"非空"));
printf("(3)输入要进栈的数据个数:");
scanf("%d",&n);
printf("依次输入进栈的%d个整数:",n);
/*数据依次进栈*/
for(i=0; i<n; i++)
{
printf("循环队列已空,不能进行出队操作!\n");
exit(1);
}
else{
x=sq->data[sq->front];
sq->front=(sq->front+1)%MaxSize;
return x;
}
}
/*取队头元素*/
ElemType GetQueue(SeqQueue *sq)
{
void InitQueue(SeqQueue *sq); /*初始化队列*/
int QueueEmpty(SeqQueue *sq); /*判队空*/

数据结构猴子吃桃课程设计

数据结构猴子吃桃课程设计

课程设计报告书课程名称:数据结构与算法题目:猴子吃桃子问题学生姓名:专业:计算机科学与技术班别:学号:指导老师:日期:2012 年12 月日目录一、问题描述 (2)二、基本要求 (2)三、工具和准备工作 (2)1.工具 (2)2.准备工作 (2)2.1分析题目 (2)四、分析与实现 (3)4.1数组实现 (3)4.2链结构实现 (4)4.3 递归结构实现 (6)五、测试与结论 (8)5.1 数组结构算法实现 (8)5.2 链式结构算法实现 (8)5.3 递归算法实现 (9)六、总结 (10)一、问题描述有一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一个,到了第10天就只余下一个桃子。

用多种方法实现求出原来这群猴子共摘了多少个桃子。

二、基本要求1)采用数组数据结构实现上述求解2)采用链式数据结构实现上述求解3)采用递归实现上述求解三、工具和准备工作1.工具一台电脑、运行平台是WindonsXP 、Visual C++6.02.准备工作2.1分析题目猴子每天吃当前桃子的一半加多一个,所以可以设它们总共所摘的桃子有m 个。

因此用数学的方法可以求出总共的桃子有多少。

即:m=2m ⎥⎥⎦⎤⎢⎢⎣⎡⎪⎭⎫ ⎝⎛-n 211+2∑⎪⎪⎭⎫ ⎝⎛-+⎥⎥⎦⎤⎢⎢⎣⎡⎪⎭⎫ ⎝⎛---11212211n n n +1(n=1,2,3,…,9),其中,猴子在前9天里每天所吃的桃子数为:m ⎥⎥⎦⎤⎢⎢⎣⎡⎪⎭⎫ ⎝⎛-n 211+2⎥⎥⎦⎤⎢⎢⎣⎡⎪⎭⎫ ⎝⎛-n 211,在前9天里每天所剩下的桃子数为:m ⎥⎥⎦⎤⎢⎢⎣⎡⎪⎭⎫ ⎝⎛-n 211+∑⎪⎪⎭⎫ ⎝⎛--1212n n (n=1,2,3,…,9)。

其实也可以这样想:设猴子总摘了m 个桃子。

它们第一天吃了⎪⎭⎫ ⎝⎛+12m 个,第二天吃了⎪⎭⎫ ⎝⎛+214m 个,第三天吃了⎪⎭⎫ ⎝⎛+418m 个,…,第九天吃了⎪⎭⎫ ⎝⎛+-1212n n m 个,所以这不难看出第一天吃的桃子是第二天的2倍。

数据结构课程设计-两个链表合并-星

数据结构课程设计-两个链表合并-星

数据结构课程设计-两个链表合并-星两个链表的合并1.课程设计目的实现对两个的链表的交叉合并,输出线形表C用直接插入排序法对C进行升序排序,生成链表D,并输出链表D。

掌握对线性表的链式表示和实现,实现插入的操作。

了解链表交叉合并的方法和直接插入排序法的思想,并深刻掌握算法的格式和应用。

提高对数据结构的理解和应用,增强个人动手实践能力和逻辑分析能力。

2.设计方案论证2.1设计思路本课程设计将对链表的交叉合并和直接插入排序的实现。

首先将两个链表进行交叉合并,合并的要求如下:建立两个链表A和B,链表元素个数分别为m和n个。

假设元素分别为(x1,x2,…xm),和(y1,y2, …yn)。

把它们合并成一个线形表C,使得:当m>=n时,C=x1,y1,x2,y2,...xn,yn, (x)当n>m时,C=y1,x1,y2,x2,…ym,xm,…,yn输出线形表C。

对合并的链表C进行直接插入排序,输出链表D。

此次课程设计实验的数据位①A表(30,41,15,12,56,80)B表(23,56,78,23,12,33,79,90,55)②A表(30,41,15,12,56,80,23,12,34)B表(23,56,78,23,12)2.1.1链表链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

通常我们把链表画成用箭头相连接的结点沈阳大学的序列,节点之间的箭头表示指针。

在c语言中,链表用结构指针来描述。

相比于线性表顺序结构,链表比较方便插入和删除操作。

(1)线性表的单链表存储结构ypedef struct Node{ElemType data;struct Node *next;} Node;typedef struct Node *Linklist;(2)实现两个链表的简单合并算法如下:Void Mergelist_L(Linklist &La,Linklist &Lb,Linklist &Lc){//已知单线性链表La和Lb的元素按值非递减排列。

如何进行科学的实验结果合并和综合分析

如何进行科学的实验结果合并和综合分析

如何进行科学的实验结果合并和综合分析科学实验的结果合并和综合分析是科学研究中非常重要的环节,它可以帮助研究者更全面、准确地了解实验结果,提取有用的信息,得出科学结论。

本文将介绍如何进行科学的实验结果合并和综合分析。

一、实验结果合并的基本原则在进行实验结果合并时,有几个基本的原则需要遵循:1. 数据的统一性:确保所有实验数据都是以相同的标准进行测量或观测得到的,如测量单位、测量方法等应一致。

2. 数据的可比性:确保实验数据之间具有可比性,即数据应来自于相同的实验条件下进行的观察或测量。

3. 数据的可信度:应使用高质量的实验数据,排除人为误差或其他干扰因素的影响。

二、实验结果合并的步骤进行实验结果的合并可以按照以下步骤进行:1. 数据清洗:检查和清理实验数据,排除异常值或明显错误的数据。

2. 数据标准化:对不同实验数据进行单位转换或标准化处理,确保数据具有可比性。

3. 数据整合:将多组实验数据合并到一个数据集中,构建一个统一的数据表格或数据库。

4. 数据平均值计算:计算各组实验数据的平均值,以反映整体趋势。

5. 数据变异性分析:计算各组实验数据的标准差或方差,评估数据变异性,判断实验结果的稳定性。

6. 数据图形化展示:使用图表或图形的方式将实验数据进行可视化展示,有助于研究者更直观地观察数据分布和趋势。

三、实验结果综合分析的方法在进行实验结果的综合分析时,可以采用以下几种方法:1. 均值差异分析:通过统计学方法,比较各组实验数据的均值差异是否显著,判断实验处理之间的差异是否具有统计学意义。

2. 相关性分析:计算各组实验数据之间的相关系数,判断实验因素之间是否存在相关性。

3. 趋势分析:观察实验数据的变化趋势,分析实验处理对结果的影响程度。

4. 回归分析:根据实验数据建立回归模型,预测未知条件下的实验结果。

5. 综合评价:综合考虑实验数据的各个方面,给出对实验结果的整体评价。

四、综合分析结果的表达方式在表达综合分析结果时,要注意以下几点:1. 准确度:描述实验结果时要准确无误,避免主观臆断或不科学的推论。

猴子吃桃 数据结构课程设计报告 中南大学

猴子吃桃 数据结构课程设计报告 中南大学

用C语言解决猴子吃桃子问题学生姓名:贾勤指导老师:湛新霞摘要本课程设计主要解决猴子吃桃子的问题。

一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一个,到了第10天就只余下一个桃子。

用多种方法实现求出原来这群猴子共摘了多少个桃子。

在课程设计中,系统开发平台为Windows 2000,程序设计设计语言采用Visual C++,数据库采用MS SQL 2000,程序运行平台为Windows 98/2000/XP。

在整个程序中分别采用数组数据结构、链数据结构、递归等结构形式实现此问题的求解。

程序通过调试运行,初步实现了设计目标。

关键词程序设计;C++;数组;链;递归;猴子吃桃1 引言在日常生活中经常遇到一些与数据计算有关的问题,许多与猴子吃桃问题类似的问题要求用计算机程序语言来解决,用这个程序算法可以解决一些类似问题,以便利于生活实际。

1.1课程设计背景猴子吃桃问题涉及一个比较有趣的数组,把猴子吃桃的天数倒过来看的话,以天数作为数组的下标i,剩下桃子的个数a[i]的递推公式为a[i]=(a[i-1]+1)*2。

a[i]实际代表了倒数第i天剩下的桃子数。

所以可以求得此数组的通项公式为a[i]=3*pow(2,(i-1))-2 (i>=2)1.2 课程设计目的在这个程序中我们主要是用C语言解决猴子吃桃问题,一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一个,到了第10天就只余下一个桃子。

用多种方法实现求出原来这群猴子共摘了多少个桃子。

生活中或学术上有很多类似的问题,这个问题看似简单,却可能使很多重大问题的重要组成部分或者是核心。

解决此问题的目的是以便在生活中解决根本性问题,是生活变得更加便利。

1.3 课程设计内容这个程序的内容是以C语言为程序语言载体分别用数组数据结构、链数据结构、递归等结构形式实现此问题的求解。

2需求分析这个课程设计分为三个部分,即分别用三种不同的方法解决猴子吃桃子问题。

实现两个链表合并(数据结构课程方案c语言版)

实现两个链表合并(数据结构课程方案c语言版)

课程设计报告课程设计题目:实现两个链表的合并学生姓名黎微微专业计算机信息管理班级1141301指导教师吴志强2018年 01月 08 日一、课程设计目的:课程设计为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析解决实际问题的能力。

提高学生适应实际,实践编程的能力。

二、课程设计题目:实现两个链表的合并要求:1)输入2个单链表2)输出2个单链表合并后形成的结果。

三、模块划分:<1)数据模块参考使用课本上的具有头结点的链表抽象数据类型linklist,该抽象数据类型中包含一个elemtype类型的数据和一个指针,在开始用时,elemtype定义为整型变量,指针用来指向下一个元素。

对应的使用链表抽象数据类型linklist基本操作的函数有:初始化操作函数void ini(linklist *s>。

<2)创建链表模块void create(linklist *s>其功能是创建链表录入数据。

<3)输出数据模块void display(linklist *s>其功能为是输出s链表中的各项元素,从而验证操作是否成功<4)排序模块void sort(linklist *s>此函数功能是s链表使用冒泡法对链表进行排序<5)合并链表模块void add(linklist *s1,linklist *s2>其功能是按照题目要求实现两个链表的合并,将s2链表插入到s1链表中。

<6)主函数模块void main(>,函数中调用了各个模块的函数,从而实现了题目合并排序的要求四、流程图:S1为五、算法设计分析这个两个链表的交叉合并算法主要运用到的是链表的基本操作,定义节点,将链表的创建、链表的插入、链表内容升序排列,通过主函数调用。

这样就大大精简了主函数的操作。

但主函数中很大篇幅用到了if、else语句,用以指定链表指定结点,这样就使得本来很精简变得繁琐,降低了程序的质量。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

合肥学院
计算机科学与技术系
课程设计报告
2011 ~2012 学年第二学期
课程数据结构与算法
课程设计名称合并果子问题
学生姓名杜双双
学号1004013037
专业班级计算机科学与技术10级3班
指导教师李红陈艳平王竹婷
2012 年2 月
课程设计报告
一、问题分析和任务定义
此程序需要完成如下要求:在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。

多多决定把所有的果子合成一堆。

每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。

可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。

多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。

因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。

假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。

例如有3种果子,数目依次为1,2,9。

可以先将1、2堆合并,新堆数目为3,耗费体力为3。

接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。

所以多多总共耗费体力3+12=15。

可以证明15为最小的体力耗费值。

实现本程序需要解决以下几个问题:
1、要使每次合并的体力消耗最小应该选择数目最小的两堆果子,那么如何选择出两堆最小的呢?
2、选择出了两堆果子如何进行合并?
3、如何计算最小的体力耗费值?
本问题的关键和难点在于数据结构的选择,找出最优的方法,在此选择哈夫曼树数据结构。

示例:三种果子,果子数目分别为1,2,3
哈夫曼树
最小体力消耗值:3+6=9
二、数据结构的选择和概要设计
上面采用哈夫曼树,则其存储就是哈夫曼树的存储结构。

采用数组顺序存储结点信息。

每一个结点包括四个域:存放该结点的weight 域、分别存放其左右孩子结点在数组中下标的lchild 域和rchild 域,以及记录该结点的父结点信息的parent 域。

只需用一个主函数就能解决问题。

三、详细设计和编码
数据结构:
typedef struct {
int weight;
int parent,lchild,rchild;
}hufmtree;
若给定n种果子的数目,则可定义数组tree[]存储哈夫曼树上的结点:
详细设计算法如下:
(1)初始化数组tree[];读入给定的n种果子每种果子数,分别放入数组的前n个分量的weight域中,并将数组中所有分量的lchild域、rchild域和parent域置0.
for(i=0;i<n;i++)//初始化数组
{
tree[i].parent=0;
tree[i].lchild=0;
tree[i].rchild=0;
tree[i].weight=0;
}
(2)从数组的前n个分量中选择果子数目最小和次小的两个结点(假设下标分别为p1和p2)合并,产生新结点,将新结点的信息存放在第n+1个分量中;新结点的数目为两个结点数目值之和,左右孩子域中的值分别修改为p1和p2;同时,改变下标为p1和p2结点的parent域中的值,使其等于n+1。

for(i=n;i<m;i++)//进行合并
{
p1=p2=0;
s1=s2=ma;
for(j=0;j<=i-1;j++)//选出两个果子数目最小的根结点
{
if(tree[j].parent==0)
if(tree[j].weight<s1)//查找最小
{s2=s1;
s1=tree[j].weight;
p2=p1;
p1=j;
}
else if(tree[j].weight<s2)//查找次小
{
s2=tree[j].weight;
p2=j;
}
tree[p1].parent=tree[p2].parent=i;
tree[i].weight=tree[p1].weight+tree[p2].weight;
tree[i].lchild=p1;
tree[i].rchild=p2;
}
}
(3)重复(2),每次均从parent域的值为0的所有结点中选择数目最小和次小的两个结点合并,产生的新结点顺次存放在weight域值为0的分量中,同时修改该分量的左右孩子域值和
被合并的两个结点的parent域值,知道数组的第2n-1个分量的weight域、lchild域和rchild 域中的值被修改为止。

(4)将每次合并后产生的新结点的weight域中的值进行求和
sum=sum+tree[i].weight;
四、上机调试过程
1、语法错误及修改:由于本程序只使用了哈夫曼树的构造,所以程序可以相对来说得到简化,语句很少。

出现的问题主要是变量的定义,括号的配对。

这些问题均根据编译器的警告提示,对应将其解决。

2、逻辑问题修改和调整:本程序虽然只用到了哈夫曼树的构造,但在构造哈夫曼树的过程中也有不少是值得关注的。

寻找最小和次小结点,将它们合并,也是说易不易的。

其中主要运用了for循环语句,根据指定条件的判断,找结点,合并结点,并将产生的新结点求和。

3、时间,空间性能分析:本算法的空间复杂度很低,只需要一个一维数组存放结果即可。

因此空间复杂度为O(n)。

选取两个最小值需要逐个比较,所以时间复杂度为O(n^2)。

4、经验和体会:初拿到本课题,开始想到的是堆栈,后分析觉得用哈夫曼树,在考虑问题时要全面,不要总在字面意思上看,思考建立模型,解决问题的能力得以提高。

五、测试结果及其分析
在运行环境中运行程序显示:
根据显示说明按要求输入数据:3
键盘输入3,按enter,显示如下:
根据要求输入三个数字:
程序根据输入的数据计算出最小体力耗费值
重新运行输入其他数据情况:
输入不正确情况:将数据输入改为字符输入程序运行后如下
六、用户使用说明
程序名为果子合并问题.c,运行环境为vc++。

程序执行后显示
输入果子的种类(1到10000之间):
在键盘按要求输入数字之后如3,按enter键显示:
输入果子的种类(1到10000之间):3
依次输入每种果子的数目(1到20000之间):
在键盘按要求输入数字(如1,2,3),按enter键显示结果:
依次输入每种果子的数目(1到20000之间):1 2 9
最小体力消耗值:15
七、参考文献
[1] 王昆仑,李红.数据结构与算法. 北京:中国铁道出版社,2006年5月。

八、附录
#include "stdio.h"
#define max 10000
#define ma 20000
typedef struct
{
int weight;
int parent,lchild,rchild;
}hufmtree;
hufmtree tree[2*max-1];
main()
{
int i,m,f,n,j;
int sum=0,p1,p2,s1,s2;
printf("输入果子的种类:");
scanf("%d",&n);
m=2*n-1;
for(i=0;i<n;i++)//初始化数组
{
tree[i].parent=0;
tree[i].lchild=0;
tree[i].rchild=0;
tree[i].weight=0;
}
printf("依次输入每种果子的数目:");
for(i=0;i<n;i++)//读入果子的数目
{
scanf("%d",&f);
tree[i].weight=f;//依次赋值每种果子的数目
}
for(i=n;i<m;i++)//进行合并
{
p1=p2=0;
s1=s2=ma;
for(j=0;j<=i-1;j++)//选出两个果子数目最小的根结点 {
if(tree[j].parent==0)
if(tree[j].weight<s1)//查找最小
{s2=s1;
s1=tree[j].weight;
p2=p1;
p1=j;
}
else if(tree[j].weight<s2)//查找次小
{
s2=tree[j].weight;
p2=j;
}
tree[p1].parent=tree[p2].parent=i;
tree[i].weight=tree[p1].weight+tree[p2].weight; tree[i].lchild=p1;
tree[i].rchild=p2;
}
sum=sum+tree[i].weight;
}
printf("最小体力耗费值:");
printf("%d\n",sum);
}。

相关文档
最新文档