中南大学数据结构实验报告.docx

上传人:b****7 文档编号:9832327 上传时间:2023-02-06 格式:DOCX 页数:40 大小:159.09KB
下载 相关 举报
中南大学数据结构实验报告.docx_第1页
第1页 / 共40页
中南大学数据结构实验报告.docx_第2页
第2页 / 共40页
中南大学数据结构实验报告.docx_第3页
第3页 / 共40页
中南大学数据结构实验报告.docx_第4页
第4页 / 共40页
中南大学数据结构实验报告.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

中南大学数据结构实验报告.docx

《中南大学数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《中南大学数据结构实验报告.docx(40页珍藏版)》请在冰豆网上搜索。

中南大学数据结构实验报告.docx

中南大学数据结构实验报告

 

中南大学

数据结构实验报告

 

实验题目:

(1)单链表的实现

(2)栈和队列

(3)二叉树的遍历(4)查找与排序

学生姓名:

代巍

学生学号:

**********

*******

所在学院:

信息科学与工程学院

专业班级:

信息安全1201班

 

指导教师评定:

签名:

 

实验一单链表的实现

一、实验目的

了解线性表的逻辑结构和各种存储表示方法,以及定义在逻辑结构上的各种

基本运算及其在某种存储结构上如何实现这些基本运算。

在熟悉上述内容的基础上,能够针对具体应用问题的要求和性质,选择合适的存储结构设计出相应的有效算法,解决与线性表相关的实际问题

二、实验内容

用C/C++语言编写程序,完成以下功能:

     

(1)运行时输入数据,创建一个单链表    

(2)可在单链表的任意位置插入新结点    

(3)可删除单链表的任意一个结点 

(4)在单链表中查找结点     

(5)输出单链表

三、程序设计的基本思想,原理和算法描述:

 

(包括程序的结构,数据结构,输入/输出设计,符号名说明等) 

用一组地址任意的存储单元存放线性表中的数据元素。

  以元素(数据元素的映象) + 指针(指示后继元素存储位置) = 结点(表示数据元素 或 数据元素的映象)  

以“结点的序列”表示线性表称作线性链表(单链表)

单链表是指数据接点是单向排列的。

一个单链表结点,其结构类型分为两部分:

 

 

(1)、数据域:

用来存储本身数据。

 

 

(2)、链域或称为指针域:

用来存储下一个结点地址或者说指向其直接后继的指针。

 

1、单链表的查找 

对单链表进行查找的思路为:

对单链表的结点依次扫描,检测其数据域是否是我们所要查好的值,若是返回该结点的指针,否则返回NULL。

 

2、单链表的插入 

因为在单链表的链域中包含了后继结点的存储地址,所以当我们实现的时候,只要知道该单链表的头指针,即可依次对每个结点的数据域进行检测。

  

假设在一个单链表中存在2个连续结点p、q(其中p为q的直接前驱),若我们需要在p、q之间插入一个新结点s,那么我们必须先为s分配空间并赋值,然后使p的链域存储s的地址,s的链域存储q的地址即可。

(p->link=s;s->link=q),这样就完成了插入操作。

 

3、单链表的删除 

删除运算思想方法删除运算是将表的第i个结点删去。

具体步骤:

找到 i-1 的存储位置p令p-next指向 i 的直接后继结点释放结点 i 的空间,将其归还给"存储池"。

四、源程序及注释

#include

#include

#include

#include

#include

#defineElemTypeint

//链表类型

typedefstructLNode

{

ElemTypedata;

structLNode*next;

}LNode,*LinkList;

intEmptyList(LinkList&L)

{if(L->next==NULL){

return0;

}

else{return1;}

}

//手动建立一个带头结点的线性链表L

voidSCreateList_L(LinkList&L)

{LinkListl,p;

inti;

ElemTyped;

l=(LinkList)malloc(sizeof(LNode));

L=(LinkList)malloc(sizeof(LNode));//生成头结点

l=L;

L->next=NULL;

cout<<"请依次输入结点值,以0为结束:

"<

for(i=1;i=1;){

cin>>d;

if(d!

=0)

{

p=(LinkList)malloc(sizeof(LNode));//生成新结点

p->data=d;

p->next=l->next;l->next=p;l=l->next;

}

elsebreak;

}

if(EmptyList(L))cout<<"生成链表成功!

";

elsecout<<"链表为空,未生成!

";

cin.get();

cin.get();

}//SCreate_L

//自动建立一个带头结点的线性链表L

voidZCreateList_L(LinkList&L,intn)

{LinkListl,p;

l=(LinkList)malloc(sizeof(LNode));

L=(LinkList)malloc(sizeof(LNode));//生成头结点

l=L;

L->next=NULL;

srand((unsigned)time(NULL));

for(inti=n;i>0;--i){

p=(LinkList)malloc(sizeof(LNode));//生成新结点

p->data=(rand()%100+1);

p->next=l->next;l->next=p;l=l->next;

}

cout<<"生成链表成功!

";

cin.get();

cin.get();

}//ZCreate_L

//建立一个带头结点的线性链表

LinkListCreateList_L()

{charc;

intn;

LinkListL;

cout<<"*********建立线性链表*********"<

cout<<"1.手动建立"<

cout<<"2.自动建立"<

cout<<"******************************"<

cin>>c;

if(c=='1'){SCreateList_L(L);}

elseif(c=='2'){cout<<"请输入链表结点的个数:

";cin>>n;ZCreateList_L(L,n);}

else{cout<<"输入错误,请重新输入:

"<

returnL;

cin.get();

cin.get();

}

//计算线性链表L中结点的个数

intLengthList(LinkList&L)

{

LinkListp=L->next;

inti=0;

while(p)

{

++i;

p=p->next;

}

returni;

cin.get();

cin.get();

}//LengthList

//在线性链表L中第i个结点之前插入新的数据元素e

voidListInsert_L(LinkList&L)

{inti;ElemTypee;

cout<<"第i个结点之前插入新的结点,请输入i:

";

cin>>i;

while(i<=0||i>LengthList(L))

{

cout<<"位置错误,重新输入插入位置:

";

cin>>i;

}

LinkListp,s;

p=L;intj=0;

while(p&&jnext;++j;}

if(!

p||j>i-1){cout<<"输入错误!

";

cin.get();

cin.get();

}

else{

cout<<"新结点的数据为:

";

cin>>e;

s=(LinkList)malloc(sizeof(LNode));

s->data=e;s->next=p->next;

p->next=s;

cout<<"插入成功!

";

}

cin.get();

cin.get();

}//ListInsert_L

//删除线性链表L中的第i个结点

voidListDelete_L(LinkList&L)

{

inti;

ElemTypee;

cout<<"请输入要删除第i个结点的i值:

";

cin>>i;

while(i<=0||i>LengthList(L))

{

cout<<"位置错误,重新输入删除位置:

";

cin>>i;

}

LinkListp,q;

p=L;intj=0;

q=(LinkList)malloc(sizeof(LNode));

while(p->next&&j

p=p->next;

++j;

}//寻找第i个结点

if(!

(p->next)||j>i-1){cout<<"删除位置不合理";

cin.get();

cin.get();

}

else{

q=p->next;

p->next=q->next;

e=q->data;

cout<<"删除成功!

"<

"<

free(q);//删除并释放结点

}

cin.get();

cin.get();

}//ListDelete_L

 

//输出线性链表L中的所有数据元素

voidPrintList(LinkList&L)

{

LinkListp=L->next;

cout<<"所有数据如下所示:

"<

while(p)

{

cout<data<<"";

p=p->next;

}

cin.get();

cin.get();

}//PrintList

voidSearchList(LinkList&L)//查找某一结点,显示其位置

{

inti=0;

ElemTypen;

cout<<"请输入要找的数据:

";

cin>>n;

if(L==NULL){cout<<"链表为空!

";}

LinkListp=L->next;

while(p->data!

=n&&p->next!

=NULL){p=p->next;i=i+1;}

if(p->data==n){cout<<"找到了对应的结点,在链表的第"<

";}

elsecout<<"链表上找不到相应的的结点!

!

";

cin.get();

cin.get();

}

voidDestroyList(LinkList&L)//退出系统前,内部做结尾工作

{

while(L)

{

LinkListp;

p=L;

L=L->next;

free(p);

}

L=NULL;

cout<<"线性链表L已销毁!

!

"<

}//DestroyList

intmenu_select()//选择函数

{

char*m[7]={"1.建立线性链表",

"2.某一结点前插入一个结点",

"3.删除一个结点",

"4.计算结点个数并输出",

"5.查找并显示某一结点位置",

"6.输出所有节点",

"0.退出系统"};

inti;

charc1;

do{

system("cls");/*清屏*/

cout<<"\n\n=========链表的基本操作=========\n\n";

for(i=0;i<7;i++)

cout<

cout<<"\n==================================\n";

cout<<"请选择(1-6,0):

";

cin>>c1;

}while(c1<'0'||c1>'6');

return(c1-'0');

}

voidmain()

{

LinkListL=NULL;

for(;;)

{

switch(menu_select())

{

case1:

L=CreateList_L();

system("pause");

break;

case2:

if(L!

=NULL)ListInsert_L(L);

else{

cout<<"链表为空,请先建链表!

";

cin.get();

cin.get();

break;

}

system("pause");

break;

case3:

if(L!

=NULL)ListDelete_L(L);

else{

cout<<"链表为空,请先建链表!

";

cin.get();

cin.get();

break;

}

system("pause");

break;

case4:

if(L!

=NULL){inti=LengthList(L);cout<<"结点的个数为:

"<

cin.get();

cin.get();}

else{

cout<<"链表为空,请先建链表!

";

cin.get();

cin.get();

break;

}

system("pause");

break;

case5:

if(L!

=NULL)SearchList(L);

else{

cout<<"链表为空,请先建链表!

";

cin.get();

cin.get();

break;

}

system("pause");

break;

case6:

if(L!

=NULL)PrintList(L);

else{

cout<<"链表为空,请先建链表!

";

cin.get();

cin.get();

break;

}

system("pause");

break;

case0:

if(L!

=NULL)DestroyList(L);

exit(0);

}

}

}

五、实验结果

 

实验二栈和队列

一、实验目的

了解栈和队列的特性。

掌握栈的顺序表示和实现。

掌握栈的链式表示和实现。

掌握队列的顺序表示和实现。

掌握队列的链式表示和实现。

掌握栈和队列在实际问题中的应用。

二、实验内容

编写一个程序实现顺序栈的各种基本运算,并在此基础上设计一个主程序完成如下功能:

初始化顺序栈,插入元素,删除栈顶元素,取栈顶元素,遍历顺序栈,置空顺序栈。

三、程序设计的基本思想,原理和算法描述

栈的修改时按照先进后出的原则进行的,试验中用到构造空栈,及入栈出栈操作。

队列是一种先进先出的线性表,只允许在表的一端插入,而在另一端删除元素,试验中构造队并且入队出队。

立顺序栈SeqStack,存放测试数据;建立队列SeqQueue存放出栈数据;

建立InitStack、StackEmpty、StackFull、Pop、Push、GetTop函数用作顺序栈的基本操作;建立InitQueue、QEmpty、Qfull、InQueue、OutQueue、ReadFront函数用作队列的基本操作;

建立主函数依次按序对子函数进行操作:

InitStack初始化栈→Push压入数据→InitQueue初始化队列→Pop弹出数据→InQueue存入队列→OutQueue出队列→Push压入栈→Pop弹出数据→free清空栈与队列。

在数据的输入与数据的输出时提供必要的提示信息。

四、源程序及其注释

#include

#include"stack.h"

#include

#defineMAXSIZE100

 

//作用:

对栈进行初始化

//参数:

//返回值:

SeqStack

SeqStackSeqStackInit()

{

SeqStackS;

S.top=-1;

returnS;

}

 

//作用:

对栈进行判断是否为空

//参数:

传入要判断的栈

//返回值:

返回TRUE为空,返回FLASE为非空

intSeqStackEmpty(SeqStackS)

{

if(S.top<0)

{

returnTRUE;

}

else

{

returnFLASE;

}

}

 

//作用:

把S置为空栈

//参数:

传入要操作的栈

//返回值:

voidClearStack(SeqStack*S)

{

while(!

SeqStackEmpty(*S))

{

S->top--;

}

printf("\n清空!

\n");

}

 

//作用:

把元素x压入栈,使其成为新的栈顶元素

//参数:

传入栈和要输入的数字

//返回值:

voidSeqStackPush(SeqStack*S,DataTypex)

{

S->top++;//要求是先挖坑,再种萝卜

S->data[S->top]=x;

}

//作用:

出栈

//参数:

要从该栈出来

//返回值:

从栈中出来的数

DataTypeSeqStackPop(SeqStack*S)

{

DataTypetemp;

if(SeqStackEmpty(*S))

{

printf("sorry!

为空栈!

");

//exit

(1);

}

else

{

temp=S->data[S->top];//出栈是当前出栈,要求先挖萝卜再填坑

S->top--;

printf("\n%d\n",temp);

}

}

//作用:

取栈顶元素

//参数:

要操作的栈

//返回值:

从栈中出来的数

DataTypeSeqStackGetTop(SeqStackS)

{

DataTypetemp;

if(SeqStackEmpty(S))

{

printf("sorry!

为空栈!

");

//exit

(1);

}

else

{

temp=S.data[S.top];//出栈是当前出栈,要求先挖萝卜再填坑

printf("\n%d\n",temp);

}

}

//作用输出顺序栈中的元素

//参数:

要操作的栈

//返回值:

从栈中出来的数

voidSeqStackPrint(SeqStackS)

{

DataTypetemp;

SeqStackp;

p=S;

printf("输出栈中的所有元素:

");

while(!

SeqStackEmpty(p))

{

temp=p.data[p.top];//出栈是当前出栈,要求先挖萝卜再填坑

p.top--;

printf("\n%d\n",temp);//当这里位置数据类型怎么办

}

}

voidmain(void)

{

intnum;

intinput;

SeqStackp;

p=SeqStackInit();

//这里调用入栈函数,把10,20,30进栈

SeqStackPush(&p,10);

SeqStackPush(&p,20);

SeqStackPush(&p,30);

while

(1)

{

printf("\n\t实验二\n\n");

printf("\n1.入栈");

printf("\n2.栈顶元素弹出");

printf("\n3.取栈顶元素");

printf("\n4.输出顺序栈中的元素");

printf("\n5.清空栈\n");

printf("\t请输入要实现的功能\n");

scanf("%d",&num);

switch(num)

{

case1:

printf("\n请输入要入栈的数:

\t\t\n");

scanf("%d",&input);

SeqStackPush(&p,input);

break;

case2:

SeqStackPop(&p);

break;

case3:

SeqStackGetTop(p);

break;

case4:

SeqStackPrint(p);

break;

case5:

ClearStack(&p);

break;

}

}

}

五、实验结果

 

实验三二叉树的建立和遍历

一、实验目的

1、学会实现二叉树结点结构和对二叉树的基本操作。

2、掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。

二、实验内容

编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。

三、程序设计的基本思想,原理和算法描述

1、数据结构的定义 

二叉树是另一种树型结构,它的特点是每个结点至多只有两棵子树,并且二叉树有左右之分,其次序不能任意颠倒。

二叉树的存储结构分为顺序存储和链式存储结构,本次我们主要应用二叉树的二叉链表的方式存储方式,实验中首先必须对二叉树的数据结构进行定义,即定义一个二叉链表,其中其数据成员包括节点的数据、左子树的指针、右子树的指针。

 

2、二叉树的建立 

在实验开始前我们要建立一个以先序形式的二叉树,先序的二叉树就是先访问根结点,然后访问左子树,最后访问右子树的遍历。

 

3、二叉树的遍历 

二叉树的遍历分为先序、中序、后序,需先取遍历的节点的数据存入队列中,然后输出。

4、程序中要的函数的介绍 

(1)二叉树的类型定义 

(2)定义链式队列类型 

(3)初始化链式队列的函数 (4)主函数

 

四、源程序及注释

#include

#include

typedefstructBiTNode

{chardata;

structBiTNode*lchild,*rchild;

}BiTNode,*BiTree;

voidCreatBiTree(BiTree&T)

{//前序法创建二叉树

charch;

if((ch=getchar())=='\n')

T=NULL;

else

{

T=(BiTNode*)malloc(sizeof(BiTNode));

if(!

T)

exit

(1);

T->data=ch;

CreatBiTree(T->lchild);

CreatBiTree(T->rchild);

}

}

 

voidPreTravel(BiTree&T)

{//前序遍历

if(T)

{

printf("%c",T->data);

PreTravel(T->lchild);

PreTravel(T->rchild);

}

}

 

voidMidTravel(BiTree&T)

{//中序遍历

if(T)

{

MidTravel(T->lchild);

printf("%c",T->data);

MidTravel(T->rchild);

}

}

 

voidPostTravel(BiTree&T

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 自然景观

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1