中南大学数据结构实验报告Word下载.docx
《中南大学数据结构实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《中南大学数据结构实验报告Word下载.docx(34页珍藏版)》请在冰豆网上搜索。
对单链表的结点依次扫描,检测其数据域是否是我们所要查好的值,若是返回该结点的指针,否则返回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
的直接后继结点释放结点
的空间,将其归还给"
存储池"
。
四、源程序及注释
#include<
iostream.h>
stdlib.h>
malloc.h>
conio.h>
time.h>
#defineElemTypeint
//链表类型
typedefstructLNode
{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
intEmptyList(LinkList&
L)
{if(L->
next==NULL){
return0;
}
else{return1;
}
//手动建立一个带头结点的线性链表L
voidSCreateList_L(LinkList&
{LinkListl,p;
inti;
ElemTyped;
l=(LinkList)malloc(sizeof(LNode));
L=(LinkList)malloc(sizeof(LNode));
//生成头结点
l=L;
L->
next=NULL;
cout<
<
"
请依次输入结点值,以0为结束:
endl;
for(i=1;
i=1;
){
cin>
>
d;
if(d!
=0)
p=(LinkList)malloc(sizeof(LNode));
//生成新结点
p->
data=d;
next=l->
next;
l->
next=p;
l=l->
elsebreak;
if(EmptyList(L))cout<
生成链表成功!
!
;
elsecout<
链表为空,未生成!
cin.get();
}//SCreate_L
//自动建立一个带头结点的线性链表L
voidZCreateList_L(LinkList&
L,intn)
srand((unsigned)time(NULL));
for(inti=n;
i>
0;
--i){
//生成新结点
data=(rand()%100+1);
}//ZCreate_L
//建立一个带头结点的线性链表
LinkListCreateList_L()
{charc;
intn;
LinkListL;
*********建立线性链表*********"
1.手动建立"
2.自动建立"
******************************"
c;
if(c=='
1'
){SCreateList_L(L);
elseif(c=='
2'
){cout<
请输入链表结点的个数:
n;
ZCreateList_L(L,n);
else{cout<
输入错误,请重新输入:
returnL;
//计算线性链表L中结点的个数
intLengthList(LinkList&
LinkListp=L->
inti=0;
while(p)
++i;
p=p->
returni;
}//LengthList
//在线性链表L中第i个结点之前插入新的数据元素e
voidListInsert_L(LinkList&
{inti;
ElemTypee;
第i个结点之前插入新的结点,请输入i:
i;
while(i<
=0||i>
LengthList(L))
位置错误,重新输入插入位置:
;
LinkListp,s;
p=L;
intj=0;
while(p&
&
j<
i-1){p=p->
++j;
if(!
p||j>
i-1){cout<
输入错误!
else{
新结点的数据为:
e;
s=(LinkList)malloc(sizeof(LNode));
s->
data=e;
next=p->
next=s;
插入成功!
}//ListInsert_L
//删除线性链表L中的第i个结点
voidListDelete_L(LinkList&
请输入要删除第i个结点的i值:
位置错误,重新输入删除位置:
LinkListp,q;
intj=0;
q=(LinkList)malloc(sizeof(LNode));
while(p->
next&
i-1){
}//寻找第i个结点
(p->
next)||j>
删除位置不合理"
else{
q=p->
next=q->
e=q->
data;
删除成功!
endl<
删除的结点值为:
free(q);
//删除并释放结点
}//ListDelete_L
//输出线性链表L中的所有数据元素
voidPrintList(LinkList&
所有数据如下所示:
data<
"
}//PrintList
voidSearchList(LinkList&
L)//查找某一结点,显示其位置
ElemTypen;
请输入要找的数据:
if(L==NULL){cout<
链表为空!
data!
=n&
p->
next!
=NULL){p=p->
i=i+1;
if(p->
data==n){cout<
找到了对应的结点,在链表的第"
i+1<
位上!
链表上找不到相应的的结点!
!
voidDestroyList(LinkList&
L)//退出系统前,内部做结尾工作
{
while(L)
LinkListp;
L=L->
free(p);
L=NULL;
线性链表L已销毁!
}//DestroyList
intmenu_select()//选择函数
char*m[7]={"
1.建立线性链表"
2.某一结点前插入一个结点"
3.删除一个结点"
4.计算结点个数并输出"
5.查找并显示某一结点位置"
6.输出所有节点"
0.退出系统"
};
charc1;
do{
system("
cls"
);
/*清屏*/
\n\n=========链表的基本操作=========\n\n"
for(i=0;
i<
7;
i++)
m[i]<
\n==================================\n"
请选择(1-6,0):
c1;
}while(c1<
'
0'
||c1>
6'
return(c1-'
voidmain()
LinkListL=NULL;
for(;
)
switch(menu_select())
case1:
L=CreateList_L();
pause"
break;
case2:
if(L!
=NULL)ListInsert_L(L);
链表为空,请先建链表!
case3:
=NULL)ListDelete_L(L);
case4:
=NULL){inti=LengthList(L);
结点的个数为:
case5:
=NULL)SearchList(L);
case6:
=NULL)PrintList(L);
case0:
=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清空栈与队列。
在数据的输入与数据的输出时提供必要的提示信息。
四、源程序及其注释
stdio.h>
#include"
stack.h"
#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)
top++;
//要求是先挖坑,再种萝卜
data[S->
top]=x;
出栈
要从该栈出来
从栈中出来的数
DataTypeSeqStackPop(SeqStack*S)
DataTypetemp;
if(SeqStackEmpty(*S))
printf("
sorry!
为空栈!
//exit
(1);
temp=S->
top];
//出栈是当前出栈,要求先挖萝卜再填坑
\n%d\n"
temp);
取栈顶元素
要操作的栈
DataTypeSeqStackGetTop(SeqStackS)
if(SeqStackEmpty(S))
temp=S.data[S.top];
}
//作用输出顺序栈中的元素
voidSeqStackPrint(SeqStackS)
SeqStackp;
p=S;
输出栈中的所有元素:
SeqStackEmpty(p))
temp=p.data[p.top];
p.top--;
\n%d\n"
//当这里位置数据类型怎么办
voidmain(void)
intnum;
intinput;
p=SeqStackInit();
//这里调用入栈函数,把10,20,30进栈
SeqStackPush(&
p,10);
p,20);
p,30);
while
(1)
\n\t实验二\n\n"
\n1.入栈"
\n2.栈顶元素弹出"
\n3.取栈顶元素"
\n4.输出顺序栈中的元素"
\n5.清空栈\n"
\t请输入要实现的功能\n"
scanf("
%d"
&
num);
switch(num)
{
case1:
printf("
\n请输入要入栈的数:
\t\t\n"
scanf("
&
input);
SeqStackPush(&
p,input);
break;
case2:
SeqStackPop(&
p);
case3:
SeqStackGetTop(p);
case4:
SeqStackPrint(p);
case5:
ClearStack(&
}
实验三二叉树的建立和遍历
1、学会实现二叉树结点结构和对二叉树的基本操作。
2、掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。
1、数据结构的定义
二叉树是另一种树型结构,它的特点是每个结点至多只有两棵子树,并且二叉树有左右之分,其次序不能任意颠倒。
二叉树的存储结构分为顺序存储和链式存储结构,本次我们主要应用二叉树的二叉链表的方式存储方式,实验中首先必须对二叉树的数据结构进行定义,即定义一个二叉链表,其中其数据成员包括节点的数据、左子树的指针、右子树的指针。
2、二叉树的建立
在实验开始前我们要建立一个以先序形式的二叉树,先序的二叉树就是先访问根结点,然后访问左子树,最后访问右子树的遍历。
3、二叉树的遍历
二叉树的遍历分为先序、中序、后序,需先取遍历的节点的数据存入队列中,然后输出。
4、程序中要的函数的介绍
(1)二叉树的类型定义
(2)定义链式队列类型
(3)初始化链式队列的函数
(4)主函数
#include<
typedefstructBiTNode
{chardata;
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
voidCreatBiTree(BiTree&
T)
{//前序法创建二叉树
charch;
if((ch=getchar())=='
\n'
)
T=NULL;
T=(BiTNode*)malloc(sizeof(BiTNode));
if(!
exit
(1);
T->
data=ch;
CreatBiTree(T->
lchild);
rchild);
voidPreTravel(BiTree&
{//前序遍历
if(T)
{
%c"
T->
data);
PreTravel(T->
voidMidTravel(BiTree&
{//中序遍历
MidTravel(T->
voidPostTravel(BiTr