北京理工大学数据结构实验报告2

《数据结构与算法统计》

实验报告

学院:

班级:

学号:

姓名:

一、实验目的

⑴熟悉VC++6.0环境,学习使用C++实现栈的存储结构;

⑵通过编程、上机调试,进一步理解栈的基本概念;

⑶锻炼动手编程,独立思考的能力。

二、实验内容

实现简单计算器的功能,请按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。要求支持运算符:+、-、*、/、%、()和=:

①从键盘输入一个完整的表达式,以回车作为表达式输入结束的标志;

②输入表达式中的数值均为大于等于零的整数,如果中间计算过程中出现小数也只取

整进行计算。

例如,输入:4+2*5= 输出:14

输入:(4+2)*(2-10)= 输出:-48

三、程序设计

1、概要设计

为实现上述功能,应使用两个栈,分别寄存操作数和运算符。为此需要栈的抽象数据结构。

⑴栈的抽象数据类型定义如下:

ADT Stack{

数据对象:

D = { ai | ai ∈ElemSet, i=1,…,n,n≥0 }

数据关系:

R1 = { | ai-1,ai ∈D, i=2, …,n }

基本操作:

InitStack1(SqStack1 &S)

操作结果:创建一个空栈S,以存储运算符

InitStack2(SqStack2 &S)

操作结果:创建一个空栈S,以存储操作数

Push1(SqStack1 &S,char e)

初始条件:栈S已存在

操作结果:插入运算符e作为新的栈顶元素

Push2(SqStack2 &S,int e)

初始条件:栈S已存在

操作结果:插入操作数e作为新的栈顶元素

Precede(char d,char c)

初始条件:d,c为运算符

操作结果:若d优先级大于c,返回>;若d优先级小于c,返回<;若d优先级等于c,返回=;

GetTop1(SqStack1 &S)

初始条件:栈S已存在且非空

操作结果:用e返回寄存运算符栈S的栈顶元素

GetTop2(SqStack2 &S)

初始条件:栈S已存在且非空

操作结果:用e返回寄存操作数栈S的栈顶元素

Pop1(SqStack1 &S,char &e)

初始条件:栈S已存在且非空

操作结果:删除寄存运算符栈S的栈顶元素

Pop2(SqStack2 &S,int &e)

初始条件:栈S已存在且非空

操作结果:删除寄存操作数栈S的栈顶元素

Operate(int a,char theta,int b)

初始条件:a,b为整数,theta为运算符

操作结果:返回a与b运算的结果

EvaluateExpression()

初始条件:输入合法的表达式

操作结果:返回表达式的值

}ADT Stack

⑵主程序流程

调用EvaluateExpression()函数计算表达式的值,输出在屏幕上。

⑶各模块的调用关系

先由主函数调用计算求值模块;

再由求值模块调用栈构造模块,表达式转换模块及表达式求值模块,计算并返回表达式的值;

最后由主函数在屏幕上输出表达式的结果。

⑷流程图

2、详细设计

⑴数据类型设计

typedef struct SqStack1

{

char * base;

char * top;

int stacksize;

}SqStack1;//定义运算符栈数据类型

typedef struct SqStack2

{

int * base;

int * top;

int stacksize;

}SqStack2; //定义操作数栈数据类型

⑵操作算法设计

int InitStack1(SqStack1 &S) //构造运算符栈

{

S.base=(char*)malloc(STACK_INIT_SIZE *sizeof(char));//申请存储空间

if(!S.base) exit(OVERFLOW);//存储空间分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

return 1;

}

int InitStack2(SqStack2 &S)//构造操作数栈

{

S.base=(int *)malloc(STACK_INIT_SIZE * sizeof(int));

//申请存储空间

if(!S.base) exit(OVERFLOW); //存储空间分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

return 1;

}

char GetTop1(SqStack1 &S)//取得运算符栈栈顶元素

{

char e;

if(S.top==S.base)//栈空

{

return 0;

}

e=*(S.top-1);

return e;

}

int GetTop2(SqStack2 &S) //取得操作数栈栈顶元素

{

char e;

if(S.top==S.base) //栈空

{

return 0;

}

e=*(S.top-1);

return e;

}

int Push1(SqStack1 &S,char e)

//插入元素e作为运算符栈栈顶元素

{

if(S.top-S.base>=S.stacksize)//栈满,追加存储空间

{

S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));

if(!S.base)exit(OVERFLOW); //分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

return 1;

}

int Push2(SqStack2 &S,int e)

//插入元素e作为操作数栈栈顶元素

{

if(S.top-S.base>=S.stacksize) //栈满,追加存储空间

{

S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));

if(!S.base)exit(OVERFLOW);//分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

return 1;

}

int Pop1(SqStack1 &S,char &e)

//删除运算符栈栈顶元素,并用e返回

{

if(S.top==S.base)//栈空

{

return 0;

}

--S.top;

e=*S.top;

return 1;

}

int Pop2(SqStack2 &S,int &e)

//删除运算符栈栈顶元素,并用e返回

{

if(S.top==S.base) //栈空

{

return 0;

}

--S.top;

e=*S.top;

return 1;

}

char Precede(char d,char c)//判断d与c的优先级{

switch(c)

{

case'+':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'-':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'*':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '>';break;

case'/':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'/':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'^':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '<';break;

case'/':return '<';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'(':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '<';break;

case'/':return '<';break;

case'^':return '<';break;

case'(':return '<';break;

case'=':return '<';break;

}

case')':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case')':return '>';break;

}

case'=':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case')':return '>';break;

case'=':return '=';break;

}

}

}

int Operate(int a,char theta,int b)//运算函数

{

switch(theta)

{

case'+':return (a+b);

case'-':return (a-b);

case'*':return (a*b);

case'/':return (a/b);

case'^':return (pow(a,b));

}

}

int EvaluateExpression()//主要运算函数

{

char c,d,theta,x;

int num,a,b;

SqStack1 OPTR;

SqStack2 OPND;

InitStack1(OPTR);//构造运算符栈

InitStack2(OPND);//构造操作数栈

Push1(OPTR,'=');

c=getchar();

while(c!='='||GetTop1(OPTR)!='=')

{

num=0;

if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='^'&&c!='('&&c!=')'&&c!='=')//不是运算符进入操作数栈

{

while(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='^'&&c!='('&&c!=')'&&c!='=')//将输入的操作数的字符型转换为整型

{

num*=10;

num+=(c-48);

c=getchar();

}

Push2(OPND,num);

}

else//是运算符

{

d=GetTop1(OPTR);

switch(Precede(d,c))//运算符优先级比较

{

case'<':Push1(OPTR,c);c=getchar();break;

//栈顶运算符优先级低,新输入的运算符进栈

case'=':Pop1(OPTR,x);c=getchar();break;

//去括号

case'>':Pop1(OPTR,theta);Pop2(OPND,b);Pop2(OPND,a);Push2(OPND,Operate(a,theta,b)); break;

//运算,并将运算结果放入操作数栈

}

}

}

return GetTop2(OPND);//返回操作数栈栈顶元素

}

⑶主函数设计

void main()

{

int result;

result=EvaluateExpression();//进行计算

printf("%d\n",result);//输出结果

}

四、程序调试分析

⑴开始进行编程时,只设计了一个栈的类型,无法将运算符和操作数分开存储,在老师讲解下,问题得以解决。同时将处理栈的函数,如Pop,Push等都针对运算对象进行了重新设置,一个处理运算符,一个处理操作数。

⑵开始时未意识到输入的操作数为char型,应转换为int型,以后进行编程时应注意操作对象的类型。

五、程序运行结果

输入合法的表达式,以=<回车>结尾,在屏幕上输出表达式的值。

测试1:

14+6*3/2=

23

测试2:

15-2/2+4^2=

30

六、程序清单

#include

#include

#include

#define STACK_INIT_SIZE 100

#define STACKINCREMENT 10

typedef struct SqStack1

{

char * base;

char * top;

int stacksize;

}SqStack1;//定义运算符栈数据类型

typedef struct SqStack2

{

int * base;

int * top;

int stacksize;

}SqStack2; //定义操作数栈数据类型

int InitStack1(SqStack1 &S);

int InitStack2(SqStack2 &S);

int Push1(SqStack1 &S,char e);

int Push2(SqStack2 &S,int e);

char Precede(char d,char c);

char GetTop1(SqStack1 &S);

int GetTop2(SqStack2 &S);

int Pop1(SqStack1 &S,char &e);

int Pop2(SqStack2 &S,int &e);

int Operate(int a,char theta,int b);

int EvaluateExpression();

void main()

{

int result;

result=EvaluateExpression();//进行计算

printf("%d\n",result);//输出结果

}

int EvaluateExpression()//主要运算函数

{

char c,d,theta,x;

int num,a,b;

SqStack1 OPTR;

SqStack2 OPND;

InitStack1(OPTR);//构造运算符栈

InitStack2(OPND);//构造操作数栈

Push1(OPTR,'=');

c=getchar();

while(c!='='||GetTop1(OPTR)!='=')

{

num=0;

if(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='^'&&c!='('&&c!=')'&&c!='=')//不是运算符进入操作数栈

{

while(c!='+'&&c!='-'&&c!='*'&&c!='/'&&c!='^'&&c!='('&&c!=')'&&c!='=')//将输入的操作数的字符型转换为整型

{

num*=10;

num+=(c-48);

c=getchar();

}

Push2(OPND,num);

}

else//是运算符

{

d=GetTop1(OPTR);

switch(Precede(d,c))//运算符优先级比较

{

case'<':Push1(OPTR,c);c=getchar();break;

//栈顶运算符优先级低,新输入的运算符进栈

case'=':Pop1(OPTR,x);c=getchar();break;

//去括号

case'>':Pop1(OPTR,theta);Pop2(OPND,b);Pop2(OPND,a);Push2(OPND,Operate(a,theta,b)); break;

//运算,并将运算结果放入操作数栈

}

}

}

return GetTop2(OPND);//返回操作数栈栈顶元素

}

int InitStack1(SqStack1 &S) //构造运算符栈

{

S.base=(char*)malloc(STACK_INIT_SIZE *sizeof(char));//申请存储空间

if(!S.base) exit(OVERFLOW);//存储空间分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

return 1;

}

int InitStack2(SqStack2 &S)//构造操作数栈

{

S.base=(int *)malloc(STACK_INIT_SIZE * sizeof(int));

//申请存储空间

if(!S.base) exit(OVERFLOW); //存储空间分配失败

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

return 1;

}

char GetTop1(SqStack1 &S)//取得运算符栈栈顶元素

{

char e;

if(S.top==S.base)//栈空

{

return 0;

}

e=*(S.top-1);

return e;

}

int GetTop2(SqStack2 &S) //取得操作数栈栈顶元素

{

char e;

if(S.top==S.base) //栈空

{

return 0;

}

e=*(S.top-1);

return e;

}

int Push1(SqStack1 &S,char e)

//插入元素e作为运算符栈栈顶元素

{

if(S.top-S.base>=S.stacksize)//栈满,追加存储空间

{

S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));

if(!S.base)exit(OVERFLOW); //分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

}

int Push2(SqStack2 &S,int e)

//插入元素e作为操作数栈栈顶元素

{

if(S.top-S.base>=S.stacksize) //栈满,追加存储空间

{

S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(int));

if(!S.base)exit(OVERFLOW);//分配失败

S.top=S.base+S.stacksize;

S.stacksize+=STACKINCREMENT;

}

*S.top++=e;

return 1;

}

int Pop1(SqStack1 &S,char &e)

//删除运算符栈栈顶元素,并用e返回

{

if(S.top==S.base)//栈空

{

return 0;

}

--S.top;

e=*S.top;

return 1;

}

int Pop2(SqStack2 &S,int &e)

//删除运算符栈栈顶元素,并用e返回

{

if(S.top==S.base) //栈空

{

return 0;

}

--S.top;

e=*S.top;

return 1;

}

char Precede(char d,char c)//判断d与c的优先级

{

switch(c)

{

case'+':switch(d)

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'-':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'*':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'/':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'^':switch(d)

case'+':return '<';break;

case'-':return '<';break;

case'*':return '<';break;

case'/':return '<';break;

case'^':return '>';break;

case'(':return '<';break;

case')':return '>';break;

case'=':return '<';break;

}

case'(':switch(d)

{

case'+':return '<';break;

case'-':return '<';break;

case'*':return '<';break;

case'/':return '<';break;

case'^':return '<';break;

case'(':return '<';break;

case'=':return '<';break;

}

case')':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case'(':return '=';break;

case')':return '>';break;

}

case'=':switch(d)

{

case'+':return '>';break;

case'-':return '>';break;

case'*':return '>';break;

case'/':return '>';break;

case'^':return '>';break;

case')':return '>';break;

case'=':return '=';break;

}

}

}

int Operate(int a,char theta,int b)//运算函数{

switch(theta)

{

case'+':return (a+b); case'-':return (a-b); case'*':return (a*b); case'/':return (a/b); case'^':return (pow(a,b)); }

}

数据结构与算法实验报告2:插入排序及归并排序(递增策略)

数据结构与算法实验报告2:插入排序及 归并排序(递增策略) 1. 实验介绍 本实验旨在探索插入排序和归并排序这两种排序算法的实现过程和性能表现。插入排序是一种简单的排序算法,它通过不断将元素插入已排序的序列中来完成排序。归并排序是一种分治法排序算法,它将待排序的序列拆分成小的子序列,然后逐步合并这些子序列来完成排序。 2. 插入排序 插入排序的思想是将数组分为已排序和未排序两部分,最初已排序部分只包含一个元素,然后逐个将未排序部分的元素插入到已排序部分的适当位置,以此达到排序的目的。插入排序使用两个循环来实现,外循环遍历未排序部分的元素,内循环将元素插入已排序部分的合适位置。 3. 归并排序 归并排序是一种分治法排序算法,它将待排序的序列拆分成小的子序列,然后逐步合并这些子序列来完成排序。归并排序使用递

归的方式将序列拆分成单个元素,然后不断合并这些单个元素来创建有序的序列。 4. 实验结果 通过实验测试,插入排序和归并排序的性能如下所示: - 插入排序: - 时间复杂度:平均情况下为 O(n^2),最好情况下为 O(n),最坏情况下为 O(n^2) - 空间复杂度:O(1) - 稳定性:稳定排序 - 归并排序: - 时间复杂度:平均情况下为 O(nlogn),最好情况下为 O(nlogn),最坏情况下为 O(nlogn) - 空间复杂度:O(n) - 稳定性:稳定排序 5. 结论 插入排序和归并排序都是常见的排序算法,它们各有优势和适用场景。插入排序适用于小规模的数据集,且对部分已排序的情况

有更好的性能。归并排序适用于大规模的数据集,其时间复杂度始终稳定,且不受输入数据的影响。根据实际需求选择合适的算法可以提高代码的效率和性能。

北理工数据结构实验报告

《数据结构与算法统计》 实验报告 ——实验四 学院: 班级: 学号: 姓名:

一、实验目的 1、熟悉VC 环境,学会使用C 语言利用顺序表解决实际问题。 2、通过上机、编程调试,加强对线性表的理解和运用的能力。 3、锻炼动手编程,独立思考的能力。 二、实验内容 从键盘输入10个数,编程实现分别用插入排序、交换排序、选择排序算法进行排序,输出排序后的序列。 三、程序设计 1、概要设计 为了实现排序的功能,需要将输入的数字放入线性表中,进行进一步的排序操作。 (1)抽象数据类型: ADT SqList{ 数据对象:D={|,1,2,,,0}i i a a ElemSet i n n ∈=≥ 数据关系:R1=11{,|,,1,2, ,}i i i i a a a a D i n --<>∈= 基本操作: Input(Sqlist & L) 操作结果:构造一个线性表L 。 output(SqList L) 初始条件:线性表L 已存在。 操作结果:按顺序在屏幕上输出L 的数据元素。 BiInsertionsort (Sqlist L) 初始条件:线性表L 已存在。 操作结果:对L 的数据元素进行折半插入排序。 QuickSort (Sqlist L) 初始条件:线性表L 已存在。 操作结果:对L 的数据元素进行交换排序。 SelectSort(SqList &L) 初始条件:线性表L 已存在。 操作结果:对L 的数据元素进行选择排序。 }ADT SqList ⑵ 宏定义 #define KeyType int #define MAXSIZE 10 #define ok 1 #define error 0 ⑶主程序流程 由主程序首先调用Input(L)函数创建顺序表, 先调用BiInsertionsort (L)函数进行折半插入排序,调用output(L)函数显示排序结

北理工数据结构实验 排序

本科实验报告实验名称:排序

一、实验目的 2、通过编程、上机调试,进一步理解排序的方法。 3、具体尝试插入排序、快速排序、选择排序的操作步骤。 4、锻炼动手编程,独立思考的能力。 二、实验题目 排序 输入10个数,从插入排序、快速排序、选择排序三类算法中各选一种编程实现 三、实验基础知识 插入排序、快速排序、选择排序三类算法的基本思想 四、实验设计方法 1、概要设计 (1)、插入排序(此次使用直接插入排序) void InsertionSort ( SqList &L ) { // 对顺序表L 作直接插入排序。 for ( i=2; i<=L.length; ++i ) if (L.r[i].key < L.r[i-1].key) {

L.r[0] = L.r[i]; // 复制为监视哨 for ( j=i-1; L.r[0].key < L.r[j].key; -- j ) L.r[j+1] = L.r[j]; // 记录后移 L.r[j+1] = L.r[0]; // 插入到正确位置 } } // InsertSort (2)、快速排序(此次用的是起泡排序) V oid Bubblesort(elem R[],int n) { I=n; While(i>1){ lastExchangeIndex = 1; for(j=1;j

数据结构课程设计实验2 打印树形结构

数据结构课程设计实验报告 实验二 树和图部分 选题为:6.4.6—打印树形结构 1、 需求分析 (1) 创建二叉树。按照用户需要的二叉树,构建二叉树 (2) 将创建的二叉树以凹入表形式打印出来。 (3) 对二叉树以中序遍历方式遍历 (4) 通过结点的深度标志位控制打印时结点的横向位置 2、 概要设计 为了实现以上功能,可以从以下3个方面着手设计。 (1) 主界面设计 为了实现二叉树相关操作功能的管理,设计一个含有多个菜单项的主控菜单子程序以链接系统的各项子功能,方便用户使用本程序。本系统主控菜单运行界面如下所示。 (2) 存储结构设计 本程序采用二叉链式存储类型(BITNode )存储二叉树的节点信息。二叉树的链表中的结点包含四个域:数据域(data )、左孩子指针域(lchild )、有孩子指针域(rchild )和结点深度标志域(depth )。 (3) 系统功能设计 本程序设计了3个功能子菜单,其描述如下: ① 二叉树的初始化。由函数CreatTree ()实现。该功能按照自上而下从左往右的顺序输入二叉树结点,构造二叉树。 ② 打印树形结构。由函数RDL ()实现。该函数实现二叉树的中序遍历,并同时格式化输出结点的数据信息。 ③ 退出操作。由exit (0)函数实现。 3、 模块设计 ① 模块设计 本程序包含两个模块:主程序模块和二叉树操作模块。其调用关系如下图所示: ② 系统子程序及功能设计 本系统共设置3个子程序,各程序的函数名及功能说明如下:

a. BiTree CreatTree() //建立二叉树,并返回根指针 b. void RDL(BiTree T) //使用RDL的中序遍历方式遍历二叉树,并输出打印结果 c. void main() //主函数。调用二叉树操作模块 ③函数主要调用关系图 本系统3个子程序之间的主要调用关系如图所示。 4、详细设计 (1)数据类型定义 typedef struct BiTNode{//定义二叉树结点 char data; struct BiTNode *lchild;//左孩子指针 struct BiTNode *rchild;//有孩子指针 int depth;//结点深度,用于打印控制横向的位置 }BiTNode,*BiTree; (2)系统主要子程序详细设计 ①建立二叉树模块 BiTree CreatTree(){//建立二叉树,并返回根指针 int front,rear; front=1; rear=0; char ch;//由于接收输入的字符 char c; BiTree T,s; T=NULL;//初始置空二叉树 printf("创建二叉树,请输入结点信息:(空结点请输入:#,结束请输入:@)\n"); c=getchar();//用于消除菜单键的回车 ch=getchar();//接收第一个字符 while(ch!='@') { s=NULL;//s为新结点 if(ch!='#')//为非空结点 { s=(BiTree)malloc(sizeof(BiTree)); s->data=ch; s->lchild=NULL;//左右孩子置空 s->rchild=NULL;

数据结构上机实验报告

数据结构上机实验报告 数据结构上机实验报告 1、实验目的 本次实验旨在通过实践,加深对数据结构中各种基本数据结构 和算法的理解,并掌握其应用方法,提高编程实践能力。 2、实验内容 2.1 实验环境 2.1.1 硬件环境: - 计算机配置:操作系统,处理器,内存 - 其他硬件设备:无 2.1.2 软件环境: - 开发工具:版本 - 编程语言:版本 - 其他相关软件:无 2.2 实验任务 2.2.1 任务一、线性表的基本操作实现 - 需要实现线性表的初始化、插入、删除、查找等基本操作。

- 使用自定义的数据结构实现线性表,例如顺序表或链表。 2.2.2 任务二、栈和队列的基本操作实现 - 需要实现栈和队列的初始化、压栈、弹栈、入队、出队等基本操作。 - 使用自定义的数据结构实现栈和队列。 2.2.3 任务三、树和图的基本操作实现 - 需要实现树和图的初始化、遍历、添加节点、删除节点等基本操作。 - 使用自定义的数据结构实现树和图。 2.3 实验步骤 2.3.1 任务一实现步骤: 1、按照实验要求,设计并实现线性表的初始化函数。 2、根据实验要求,编写线性表的插入函数,可以在指定位置插入元素。 3、编写线性表的删除函数,可以删除指定位置的元素。 4、实现线性表的查找函数,可以根据元素值查找对应位置。 2.3.2 任务二实现步骤:

1、设计并实现栈的初始化函数。 2、编写栈的压栈函数,将元素添加到栈顶。 3、实现栈的弹栈函数,将栈顶元素弹出。 4、设计并实现队列的初始化函数。 5、编写队列的入队函数,将元素添加到队尾。 6、实现队列的出队函数,将队首元素出队。 2.3.3 任务三实现步骤: 1、设计并实现树的初始化函数。 2、编写树的遍历函数,可以按照先序、中序、后序等方式遍历树的节点。 3、实现树的添加节点函数,可以在指定节点下添加子节点。 4、编写树的删除节点函数,可以删除指定节点及其子节点。 5、设计并实现图的初始化函数。 6、编写图的遍历函数,可以按照广度优先或深度优先方式遍历图的节点。 7、实现图的添加节点函数,可以添加新的节点。 8、编写图的删除节点函数,可以删除指定节点及其相关边。

北理工数据结构作业2

北理工数据结构作业2 一、问题描述 根据北理工数据结构作业2,要求如下: 设计一个程序,实现以下功能: 1、创建一个链表,可以存储整数类型的数据; 2、在链表的头部插入一个新的节点; 3、在链表的尾部插入一个新的节点; 4、在链表的指定位置插入一个新的节点; 5、删除链表的指定位置的节点; 6、修改链表的指定位置的节点的值; 7、查找链表中指定值的节点,并返回该节点的位置; 8、遍历链表,并输出链表中的所有节点的值; 9、清空链表的所有节点; 10、销毁链表,释放链表的内存。 二、解决方案 1、链表的数据结构定义

struct Node { int value; struct Node next; }; ``` 2、创建链表 ```c struct Node createList(); ``` - 功能:创建一个空链表,并返回链表的头节点指针。 - 输入:无 - 输出:链表的头节点指针 3、头部插入节点 ```c struct Node insertNodeAtHead(int value, struct Node head);

- 功能:在链表的头部插入一个新的节点,并返回链表的头节点指针。 - 输入:待插入节点的值,链表的头节点指针 - 输出:链表的头节点指针 4、尾部插入节点 ```c void insertNodeAtTl(int value, struct Node head); ``` - 功能:在链表的尾部插入一个新的节点。 - 输入:待插入节点的值,链表的头节点指针 - 输出:无 5、指定位置插入节点 ```c void insertNodeAtIndex(int value, int index, struct Node head); ```

北京理工大学数据结构与算法设计实验二

《数据结构与算法设计》 实验报告 ——实验二 学院:自动化学院 班级:06111001 学号:1120100001 姓名:宝竞宇

一、实验目的 掌握栈的建立,输入,删除,出栈等基本操作。应用栈解 决实际问题。 二、实验内容 实现简单计算器的功能,请按照四则运算加、减、乘、除、幂(^)和括号的优先关系和惯例,编写计算器程序。要求支持运算符:+、-、*、/、%、()和=: ①从键盘输入一个完整的表达式,以回车作为表达式输入结 束的标志; ②输入表达式中的数值均为大于等于零的整数,如果中间计 算过程中出现小数也只取整进行计算。 例如,输入:4+2*5= 输出:14 输入:(4+2)*(2-10)= 输出:-48 三、程序设计 1、概要设计 抽象数据类型定义:两个栈结构,分别用来储存数据和计算 符号 宏定义:函数“成功”,“失败的返回值” 在主程序程序中先依次输入各表达式,存入相应各栈,然后,调用“判断函数”来判断计算符的优先次序,然后再利用计算函数来计算,表达式值。其中还有,取栈顶元素函数,存

入栈函数。 2、详细设计 数据类型实现:struct t { char dat[200]; int top; }prt; 入栈函数:存入数组,栈顶指针上移 void pushd(long int a) { prd.dat[prd.top++]=a; } 出栈:取出对应值,栈顶指针下移 long int popd( ) { return prd.dat[--prd.top]; } 比较优先级:建立数组,比较返回大于小于号。 计算函数:以字符型输入,运算符号,用switch来分支计算判断,返回计算数值 long int operation ( long int x, long int y, char a) { s witch(a) { case '+': return x+y; case '-': return x-y; case '*': return x*y;

数据结构实验报告

数据结构实验报告 数据结构实验报告 一、实验目的 本次实验的目的是实践和掌握数据结构的基本概念和操作,同时提高编程能力,培养解决问题的能力。 二、实验环境 1、硬件环境:(列出实验所用计算机硬件环境) 2、软件环境:(列出实验所用计算机软件环境) 三、实验内容 本次实验主要涉及以下几个方面的内容: 1、数据结构的基本概念与分类 1.1 数据结构的定义和基本概念 1.2 数据结构的分类和特点 2、线性表与链表 2.1 线性表的定义和基本操作 2.2 链表的定义和基本操作 2.3 线性表与链表的比较

3、栈与队列 3.1 栈的定义和基本操作 3.2 队列的定义和基本操作 3.3 栈与队列的应用场景 4、树与二叉树 4.1 树的定义和基本操作 4.2 二叉树的定义和基本操作 4.3 树与二叉树的比较 5、图 5.1 图的定义和基本概念 5.2 图的表示和基本操作 5.3 图的遍历算法 四、实验步骤 1、第一步:(描述实验的第一个步骤) 2、第二步:(描述实验的第二个步骤) 3、第三步:(描述实验的第三个步骤) 4、:::

五、实验结果与分析 在实验过程中,我们得到了以下结果: (描述实验结果,如某个操作的运行时间、空间占用等) 根据实验结果的分析,我们可以得出以下结论: (分析实验结果,指出哪些操作较高效,哪些操作需要改进等) 六、实验总结与心得 通过本次实验,我对数据结构的基本概念和操作有了更深入的 理解,同时也提高了编程能力。在实验过程中,我遇到了一些问题,但通过查阅资料和与同学的讨论,最终得以解决。总的来说,本次 实验对我的学习和成长起到了积极的促进作用。 七、附件 1、(列出本文档所涉及的附件名称和说明) 八、法律名词及注释 1、法律名词1:注释1 2、法律名词2:注释2 3、:::

数据结构 图实验报告

数据结构图实验报告 数据结构图实验报告 引言: 数据结构是计算机科学中非常重要的一个概念,它用于存储和组织数据,使得 数据的操作更加高效和方便。图是一种常见的数据结构,它由节点和边组成, 用于表示各种实际问题中的关系和连接。本实验旨在通过实际操作,深入理解 图的基本概念和常见操作。 实验目的: 1. 理解图的基本概念和特性; 2. 掌握图的存储结构和基本操作; 3. 实现图的遍历算法; 4. 分析图的应用场景。 实验过程: 1. 图的存储结构: 在本次实验中,我们选择邻接矩阵来存储图。邻接矩阵是一个二维数组,其 中行和列分别表示图中的节点,数组元素表示节点之间的边的关系。具体而言,如果节点i和节点j之间存在边,则邻接矩阵中的第i行第j列元素为1;否则 为0。 2. 图的基本操作: 在实验中,我们实现了以下几个图的基本操作: - 添加节点:通过向邻接矩阵中添加一行一列,并设置对应的边的关系,来添

加一个节点; - 添加边:通过修改邻接矩阵中对应元素的值,来添加一条边; - 删除节点:通过删除邻接矩阵中对应行和列,并更新其他节点的索引,来删除一个节点; - 删除边:通过修改邻接矩阵中对应元素的值,来删除一条边; - 查找节点:通过遍历邻接矩阵,找到对应节点的索引; - 查找边:通过遍历邻接矩阵,找到对应边的关系。 3. 图的遍历算法: 在实验中,我们实现了深度优先搜索(DFS)和广度优先搜索(BFS)两种图的遍历算法。DFS通过递归的方式,先访问当前节点,再依次访问相邻节点,直到所有节点都被访问。BFS则通过队列的方式,先访问当前节点,再依次访问当前节点的相邻节点,直到所有节点都被访问。 实验结果: 通过实验,我们成功实现了图的存储结构和基本操作,并且正确实现了DFS和BFS两种遍历算法。我们对不同规模的图进行了测试,并分析了算法的时间复杂度。实验结果表明,邻接矩阵的存储结构在添加和删除节点时的时间复杂度较高,而在查找节点和边时的时间复杂度较低。DFS和BFS的时间复杂度都为O(V+E),其中V表示节点数,E表示边数。根据实验结果,我们可以根据具体应用场景选择合适的图的存储结构和遍历算法。 实验总结: 通过本次实验,我们加深了对图的理解,掌握了图的存储结构和基本操作,并

数据结构课程实验报告

数据结构课程实验报告 一、实验目的 本次数据结构课程实验的主要目的是通过实践掌握常见数据结构的基 本操作,包括线性结构、树形结构和图形结构。同时,也要求学生能 够熟练运用C++语言编写程序,并且能够正确地使用各种算法和数据结构解决具体问题。 二、实验内容 本次实验涉及到以下几个方面: 1. 线性表:设计一个线性表类,并且实现线性表中元素的插入、删除、查找等基本操作。 2. 栈和队列:设计一个栈类和队列类,并且分别利用这两种数据结构 解决具体问题。 3. 二叉树:设计一个二叉树类,并且实现二叉树的遍历(前序遍历、 中序遍历和后序遍历)。

4. 图论:设计一个图类,并且利用图论算法解决具体问题(如最短路径问题)。 三、实验过程 1. 线性表 首先,我们需要设计一个线性表类。在这个类中,我们需要定义一些成员变量(如线性表大小、元素类型等),并且定义一些成员函数(如插入元素函数、删除元素函数等)。在编写代码时,我们需要注意一些细节问题,如边界条件、异常处理等。 2. 栈和队列 接下来,我们需要设计一个栈类和队列类。在这两个类中,我们需要定义一些成员变量(如栈顶指针、队头指针等),并且定义一些成员函数(如入栈函数、出栈函数、入队函数、出队函数等)。在编写代码时,我们需要注意一些细节问题,如空间不足的情况、空栈或空队列的情况等。 3. 二叉树 然后,我们需要设计一个二叉树类,并且实现二叉树的遍历。在这个

类中,我们需要定义一个节点结构体,并且定义一些成员变量(如根 节点指针、节点数量等),并且定义一些成员函数(如插入节点函数、删除节点函数、遍历函数等)。在编写代码时,我们需要注意一些细 节问题,如递归调用的情况、空节点的情况等。 4. 图论 最后,我们需要设计一个图类,并且利用图论算法解决具体问题。在 这个类中,我们需要定义一个邻接矩阵或邻接表来表示图形结构,并 且定义一些成员变量(如顶点数量、边的数量等),并且定义一些成 员函数(如添加边函数、删除边函数、最短路径算法等)。在编写代 码时,我们需要注意一些细节问题,如图不连通的情况、负权边的情 况等。 四、实验结果 通过本次实验,我掌握了常见数据结构的基本操作,并且能够熟练运 用C++语言编写程序。同时,我也学会了如何使用各种算法和数据结构解决具体问题。通过这次实验,我对数据结构有了更深入的理解, 并且提高了自己的编程能力。 五、实验总结

北京理工大学 数据结构 实验报告 实验二 简易计算器

实验二简易计算器 姓名:任子龙学号:1120140167 班级:05111451 一.需求分析 1.程序要求可对一实数算术表达式进行简单的数学运算,可以识别带+、-、*、/、%、^(乘方)等等运算符及括号的中缀表达式,从键盘上输入一算术表达式(一般为中缀表达式),计算出表达式的值。 2.按照四则运算规则,求表达式的值。一般规则如下:1)先括号内,再括号外。2)先乘方,再乘除,后加减。b.同级运算从左到右顺序执行。 3.有良好的提示信息,引导用户在键盘上输入规定的运算指令;如表达式有误,也应给出相应的提示信息。 4.建立两个工作栈,分别保存运算符,操作数或运算结果。 二.概要设计 1.抽象数据类型的定义 为实现上述功能,建立两个工作栈;算符为字符型变量,算数为单精度浮点型变量,则需要定义两种数据类型分别存储。typedef struct StackChar{ char c; struct StackChar*next; }SC; typedef struct StackFloat{ float f;

}SF; 2.本程序包含两个模块 (1)主程序模块 主函数只包含了输入输出部分。流程为:首先输入算式,然后调用算符优先算法函数EvaluateExpression(s)进行计算,结果输出;然后循环下去,直到输入OUT指令,退出程序; (2)链栈单元模块——实现栈的链式存储的抽象数据类型。 各函数之间的调用关系: 三.详细设计 1.结点类型 typedef struct StackChar{ char c; struct StackChar*next; }SC;

数据结构的实验报告

数据结构的实验报告 数据结构的实验报告 一、引言 数据结构是计算机科学中非常重要的一个领域,它研究的是数据的组织、存储 和管理方式,以及数据之间的关系和操作。在本次实验中,我们将探索不同类 型的数据结构,包括数组、链表和树,并比较它们在不同场景下的性能和适用性。 二、实验目的 本次实验的目的是通过编写代码和运行实验,深入理解不同数据结构的特点和 使用场景,以及它们在不同操作下的效率和性能。通过实验,我们希望能够掌 握以下内容: 1. 理解不同数据结构的基本概念和特点; 2. 掌握不同数据结构的基本操作,如插入、删除和查找; 3. 比较不同数据结构在不同操作下的性能差异; 4. 分析和评估不同数据结构的适用场景。 三、实验过程 1. 数组 数组是一种线性数据结构,它将一组相同类型的元素存储在连续的内存空间中。在本次实验中,我们使用数组来存储学生的成绩,并实现以下操作:插入、删 除和查找。 通过实验发现,数组在插入和删除操作时效率较低,因为需要移动其他元素来 保持连续性。但在查找操作时,由于元素的连续存储,可以通过下标直接访问,

效率较高。 2. 链表 链表是一种非连续的数据结构,它通过指针将一组元素链接在一起。在本次实 验中,我们使用链表来存储学生的信息,并实现以下操作:插入、删除和查找。通过实验发现,链表在插入和删除操作时效率较高,因为只需要修改指针的指 向即可,无需移动其他元素。但在查找操作时,需要遍历链表来找到目标元素,效率较低。 3. 树 树是一种非线性的数据结构,它由一组节点和边组成。在本次实验中,我们使 用二叉搜索树来存储学生的信息,并实现以下操作:插入、删除和查找。 通过实验发现,二叉搜索树在插入和删除操作时效率较高,因为它通过比较节 点的值来确定插入位置或删除节点。在查找操作时,由于树的结构,可以通过 比较节点的值来快速定位目标元素,效率较高。 四、实验结果 通过对不同数据结构的实验,我们得到了以下结果: 1. 数组适用于对元素的访问频繁、插入和删除操作较少的场景; 2. 链表适用于插入和删除操作频繁、对元素的访问较少的场景; 3. 树适用于对元素的访问和插入、删除操作均较频繁的场景。 五、实验总结 通过本次实验,我们深入了解了不同数据结构的特点和使用场景。我们发现不 同数据结构在不同操作下的性能和适用性有所差异。在实际应用中,我们需要 根据具体场景的需求来选择合适的数据结构,以提高程序的效率和性能。

数据结构与算法实验报告

数据结构与算法实验报告 数据结构与算法实验报告 一、实验目的 本实验旨在通过实践的方式,加深对数据结构与算法的理解与 应用,并能够独立设计和实现常见的数据结构和算法。 二、实验要求 1·设计并实现以下数据结构与算法:(按需列出具体数据结构 与算法) 2·进行性能测试,分析并总结测试结果。 3·撰写实验报告,完整记录实验过程与结果,并进行适当的分 析与总结。 三、实验环境 (列出实验所需环境,包括操作系统、编程语言及开发环境等) 四、实验过程与方法 4·1 数据结构设计与实现 (首先介绍每个数据结构的功能与特点,然后给出设计思路和 实现方法,包括数据结构的定义、操作方法和算法等)

4·2 算法设计与实现 (首先介绍每个算法的功能与特点,然后给出设计思路和实现方法,包括算法的定义、输入输出格式、算法流程图等) 五、实验结果与分析 5·1 数据结构性能测试结果 (列出数据结构的测试用例及其输入输出,记录测试结果,包括运行时间、空间占用等方面的数据,并进行适当的分析与总结)5·2 算法性能测试结果 (列出算法的测试用例及其输入输出,记录测试结果,包括运行时间、空间占用等方面的数据,并进行适当的分析与总结) 六、实验总结 6·1 实验成果 (总结实验所达到的目标,列出已实现的数据结构和算法) 6·2 实验心得 (记录实验过程中的收获和体会,包括困难与解决方法、感悟和改进方向等) 附件: 1·实验源码

(附上实验所使用的源代码文件,以供参考) 2·实验数据 (附上实验所用的测试数据文件或数据表格等) 法律名词及注释: (列出文档中涉及的法律名词及其注释,以确保读者对相关法律法规的理解)

数据结构实验报告 (2)

数据结构实验报告 实验报告 数据结构实验报告应包含以下几个部分: 1. 实验目的:简要介绍实验的目的和意义。 2. 原理介绍:详细介绍本次实验所涉及的数据结构原理,包括数据结构的定义、特性以及相关算法或操作。 3. 实验内容:详细描述本次实验的具体内容,包括实验要求和实验步骤。

4. 实验结果:展示实验的结果,以适当的方式呈现实验数 据和实验输出。可以包括图表、表格、代码等。 5. 分析讨论:分析实验结果,讨论实验结果与预期结果的 差异,并给出相应的解释。 6. 实验总结:对本次实验的总结和评价,包括实验的收获、不足之处以及改进的建议。 以下是一个简单的数据结构实验报告的范例: 实验目的: 本次实验的目的是熟悉链表数据结构的概念和基本操作, 包括链表的插入、删除和查找等。

原理介绍: 链表是一种常用的数据结构,它由一组节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。链表中的节点可以通过指针相互连接,从而形成一串有序的数据。链表不同于数组,它的插入和删除操作十分高效,但查找效率较低。 实验内容: 本次实验要求实现一个链表,并在链表中实现插入、删除和查找操作。首先,定义一个节点结构,并实现节点的插入和删除操作;其次,实现查找操作,并根据查找结果返回节点位置或者相关信息。 实验结果: 经过实验,我们得到了以下结果:在链表中插入节点的时间复杂度为O(1),删除节点的时间复杂度为O(1),查找节点的时间复杂度为O(n)。

分析讨论: 从结果可以看出,链表的插入和删除操作的效率较高,但查找操作的效率较低。这是因为链表中的节点没有连续的存储空间,所以需要遍历整个链表才能找到目标节点。如果需要频繁进行查找操作,可以考虑使用其他数据结构,如二叉搜索树或哈希表。 实验总结: 通过本次实验,我们深入了解了链表数据结构的原理和基本操作,并实现了一个简单的链表。在以后的学习和实践中,我们可以根据实际需求选择合适的数据结构,以提高程序的效率和性能。此外,本次实验也让我们更加熟悉了编程的过程和技巧。希望以后能够继续学习和应用数据结构知识,提升自己的编程能力。 以上是一个简单的数据结构实验报告的范例,具体内容和结构可以根据实际情况进行调整。实验报告应清晰、简洁地表达实验过程和结果,以便他人能够理解和复现实验。

数据结构实验二——算术表达式求值实验报告

数据结构实验二——算术表达式求值实验报 告 算术表达式求值实验报告 一、引言 算术表达式求值是计算机科学中一个重要的基础问题,它涉及到了数据结构和算法的应用。本实验旨在通过实现一个算术表达式求值的程序,加深对数据结构中栈的理解和应用,并掌握算术表达式的求值过程。 二、实验目的 1. 理解算术表达式的基本概念和求值过程; 2. 掌握栈的基本操作和应用; 3. 实现一个能够正确求解算术表达式的程序; 4. 进一步熟悉编程语言的使用。 三、实验内容 1. 设计并实现一个栈的数据结构; 2. 实现算术表达式求值的算法; 3. 编写测试用例,验证程序的正确性; 4. 进行性能测试,分析算法的时间复杂度。 四、实验方法与步骤 1. 设计栈的数据结构

在本实验中,我们选择使用数组来实现栈的数据结构。栈的基本操作包括入 栈(push)、出栈(pop)、判断栈空(isEmpty)和获取栈顶元素(top)等。 2. 算术表达式求值算法 算术表达式求值的一种常用算法是通过后缀表达式进行求值。具体步骤如下: - 将中缀表达式转换为后缀表达式; - 通过栈来求解后缀表达式; - 返回最终的计算结果。 3. 编写测试用例 编写一系列测试用例,包括不同类型的算术表达式,以验证程序的正确性。 例如: - 简单的四则运算表达式:2 + 3 * 4 - 5; - 包含括号的表达式:(2 + 3) * (4 - 5); - 包含多位数的表达式:12 + 34 * 56; - 包含浮点数的表达式:3.14 + 2.71828。 4. 性能测试和时间复杂度分析 针对不同规模的输入数据,进行性能测试,记录程序的运行时间。同时,分 析算法的时间复杂度,验证算法的效率。 五、实验结果与分析 我们设计并实现了一个栈的数据结构,并成功地完成了算术表达式求值的程序。通过对一系列测试用例的验证,我们发现程序能够正确地求解各种类型的算术表达式,并返回正确的计算结果。

数据结构实验报告

数据结构实验报告 实验一数据结构实验报告 一、实验目的 本实验的目的是通过实践,对数据结构的基本概念和基本操作进行理 解与掌握。通过实验,加深对线性表及其实现方式的认识,并能够编程实 现线性表相应的各种操作。 二、实验内容 1.线性表的顺序存储结构的实现 在本实验中,我们采用顺序存储结构实现线性表。通过编写程序,实 现线性表的初始化、插入、删除、查找等基本操作。具体实现流程如下: a)初始化线性表:申请一定大小的内存空间,用于存储线性表的数据 元素。 b)插入操作:在线性表的任意位置插入一个新元素。若插入位置无效,返回错误提示。 c)删除操作:在线性表中删除指定位置的元素。若删除位置无效,返 回错误提示。 d)查找操作:查找线性表中指定元素的位置。若找到,返回元素所在 位置的序号;若找不到,返回错误提示。 2.线性表的链式存储结构的实现 在本实验中,我们采用链式存储结构实现线性表。通过编写程序,实 现链表的初始化、插入、删除、查找等基本操作。具体实现流程如下:

a)初始化线性表:创建一个头节点,并初始化链表为空。 b)插入操作:在链表的任意位置插入一个新节点。若插入位置无效,返回错误提示。 c)删除操作:删除链表中指定位置的节点。若删除位置无效,返回错误提示。 d)查找操作:查找链表中指定元素的位置。若找到,返回元素所在位置的序号;若找不到,返回错误提示。 三、实验过程与结果分析 1.线性表的顺序存储结构实现 a)实现过程: 首先,定义一个结构体,用于存储线性表的相关信息,包括线性表的总长度、当前长度和数据元素的数组。 然后,编写初始化函数,通过动态分配内存空间,为线性表的数据元素数组分配一定大小的内存空间。 接着,实现插入操作。在插入操作中,判断插入位置是否有效,若无效,则返回错误提示;若有效,则将插入位置以后的所有元素向后移动一位,空出插入位置,将新元素插入到指定位置上。 同样地,实现删除操作。判断删除位置是否有效,若无效,则返回错误提示;若有效,则将删除位置以后的所有元素向前移动一位,覆盖掉删除位置上的元素。

相关文档
最新文档