数据结构试验报告.docx
《数据结构试验报告.docx》由会员分享,可在线阅读,更多相关《数据结构试验报告.docx(75页珍藏版)》请在冰豆网上搜索。
![数据结构试验报告.docx](https://file1.bdocx.com/fileroot1/2022-11/28/d2cb566b-7134-49c6-8de1-87bf6f293950/d2cb566b-7134-49c6-8de1-87bf6f2939501.gif)
数据结构试验报告
数据结构实验
学院:
信息工程学院
班级:
计算机科学与技术091
学生姓名:
学生学号:
时间:
2010-3至2010-6
计算机系数据结构实验报告
姓名:
学号:
专业班级:
计算机科学与技术091
线性表及其应用
一、实验目的
帮助学生掌握线性表的基本操作在顺序和链表这两种存储结构上的实现,尤以链表的操作和应用作为重点。
二、问题描述
1.构造一个空的线性表L。
2.在线性表L的第i个元素之前插入新的元素e;
3.在线性表L中删除第i个元素,并用e返回其值。
三、实验要求
1、分别利用顺序和链表存储结构实现线性表的存储,并设计出在不同的存储结构中线性表的基本操作算法。
2、在实验过程中,对相同的操作在不同的存储结构下的时间复杂度和空间复杂度进行分析。
四、实验环境
PC微机
DOS操作系统或Windows操作系统
TurboC程序集成环境或VisualC++程序集成环境
五、实验算法分析
顺序存储算法描述:
插入:
顺序表的插入操作是指在线性表的第i-1个数据元素和第i个数据元素之间插入一个新的数据元素,使长度为n的线性表变成长度为n+1的线性表,数据元素ai-1和ai之间的逻辑关系发生了变化。
因此,除非i=n+1,否则必须移动元素才能反映这个逻辑上的变化。
一般情况下,在第i(1≤i≤n)个元素之前插入一个元素时,需将第n至第i(共n-i+1)个元素向后移动一个位置。
删除:
顺序表的删除操作是使长度为n的线性表变成长度为n—1的线性表,数据元素ai-1、ai和ai+1之间的逻辑关系发生了变化。
一般情况下,删除第i(1≤i≤n)个元素时需将第i+1至第n(共n-1)个元素向前移动一个位置。
链式存储的算法描述:
插入:
链表的插入操作是将值为x的新结点插入到表的第i个结点的位置上,即插入到ai-1与ai之间。
具体步骤:
(1)找到ai-1存储位置p
(2)生成一个数据域为x的新结点*s
(3)令结点*p的指针域指向新结点
(4)新结点的指针域指向结点ai。
删除:
链表的删除操作是将表的第i个结点删去。
具体步骤:
(1)找到ai-1的存储位置p(因为在单链表中结点ai的存储地址是在其直接前趋结点ai-1的指针域next中。
(2)令p->next指向ai的直接后继结点(即把ai从链上摘下)
(3)释放结点ai的空间。
六、实验步骤
1、问题描述;
1)分别利用顺序和链表存储结构实现线性表的存储,并设计出在不同的存储结构中线性表的基本操作算法。
2)在实验过程中,对相同的操作在不同的存储结构下的时间复杂度和空间复杂度进行分析。
2、设计两种存储结构与核心算法描述;
线性表的顺序和链表存储结构为:
。
顺序表:
structsqlist
{elemtypea[maxsize];
intlen;
};
非循环单链表为:
structNode
{
charData;
structNode*Next;
};
classList
{
private:
Node*Head;
public:
}
2、具体用所选择的语言实现算法为:
顺序表:
#include
usingnamespacestd;
#defineelemtypechar
constintmaxsize=100;
structsqlist
{elemtypea[maxsize];
intlen;
};
sqlistsetnull(sqlistl)
{l.len=0;
returnl;
};
sqlistinsert(sqlistl,elemtypex,inti)
{intj;
if(l.len>maxsize-1)
cout<<"输入溢出"<elseif(i<1||i>l.len+1)
cout<<"输入错误,超出范围"<else
{for(j=l.len;j>=i;j--)
l.a[j+1]=l.a[j];
l.a[i]=x;
l.len++;
}
returnl;
}
sqlistdeletesq(sqlistl,inti,char&e)
{intj;
if(i<1||i>l.len)
cout<<"\t输入错误,超出范围"<else
{e=l.a[i];
for(j=i+1;j<=l.len;j++)
l.a[j-1]=l.a[j];
l.len--;
}
returnl;
}
voidoutput(sqlistl)
{intj;
cout<<"L=:
(";
for(j=1;j<=l.len;j++)
cout<cout<}
intchoose(sqlistl)
{inta;
cout<<"是否返回继续操作?
<是[1],否[0]>。
";
cin>>a;
returna;
}
sqlistinputsq(sqlistl)
{intn;
cout<<"请输入表中元素的个数:
";
cin>>n;
for(intj=1;j<=n;j++)
{
cout<<"输入表中第"<";
cin>>l.a[j];
}
l.len=n;
returnl;
}
intmain()
{
sqlistl;elemtypex,y,e;intsel,j;
while
(1)
{
system("cls");
cout<cout<<"======================顺序表的基本操作菜单============================"<cout<<"\t1、在顺序表L的第i个元素之前插入新的元素e。
"<cout<<"\t2、在顺序表L中删除第i个元素,并用e返回其值。
"<cout<<"\t3、退出操作。
"<cout<<"----------------------------------------------------------------------"<cout<<"请输入选择要执行的编号(1-3):
";
cin>>sel;
switch(sel)
{
case1:
cout<<"================插入操作================="<l=inputsq(l);
cout<<"你输入的顺序表为:
";
output(l);
cout<<"请输入要插入的数据:
";
cin>>x;
cout<<"请输入要插入的位置:
";
cin>>j;
l=insert(l,x,j);
cout<<"插入后得到的顺序表为:
";
output(l);
l=setnull(l);
break;
case2:
cout<<"================删除操作================="<l=inputsq(l);
cout<<"你输入的顺序表为:
";
output(l);
cout<<"请输入要删除的数据位置:
";
cin>>j;
l=deletesq(l,j,e);
cout<<"删除后得到的顺序表为:
";
output(l);
cout<<"删除的数据为:
";
cout<cout<l=setnull(l);
break;
case3:
return0;
};
y=choose(l);
if(y==0)
exit(0);
else
fflush(stdin);
}
}
链表为:
#include
usingnamespacestd;
structNode
{
charData;
structNode*Next;
};
classList
{
private:
Node*Head;
public:
List();
~List();
voidAddList();
voidInsertData();
voidDeleteData();
voidShowList();
voidfanshow();
};
List:
:
List()
{
List:
:
Head=NULL;
}
List:
:
~List()
{
Node*r=NULL,*p=NULL;
for(p=List:
:
Head;p!
=NULL;p=p->Next)
{
r=p;
p=p->Next;
deleter;
r=NULL;
}
List:
:
Head=NULL;
}
voidList:
:
AddList()
{
intn=0;
Node*p=NULL,*q=NULL;
cout<<"";
cout<<"请输入链表长度:
";
cin>>n;
if(n>=1)
{
p=newNode;
cout<<"输入第1个元素:
";
cin>>p->Data;
List:
:
Head=p;
for(inti=1;i{
q=p;
p=newNode;
cout<<"输入第"<
";
cin>>p->Data;
q->Next=p;
}
p->Next=NULL;
}
}
voidList:
:
InsertData()
{
inti,j=1;chare;
Node*p=List:
:
Head;
Node*s;
cout<<"请输入要插入的元素:
";
cin>>e;
cout<<"请输入要插入的位置:
";
cin>>i;
while(p&&j{
++j;
p=p->Next;
}
if(j>i)
return;
s=newNode;
s->Data=e;
if(i==1)
{
s->Next=Head;
Head=s;
}
else
{
s->Next=p->Next;
p->Next=s;
}
return;
}
voidList:
:
ShowList()
{
cout<<"此时链表内容输出为:
L=(";
for(Node*p=List:
:
Head;p!
=NULL;p=p->Next)
cout<Data;cout<<")";
cout<}
voidList:
:
DeleteData()
{
chare;
inti;
Node*p=List:
:
Head,*delp=NULL,*q;
cout<<"请输入要删除的元素的位置:
";
cin>>i;
if(List:
:
Head==NULL)
cout<<"输入超出范围。
"<return;
intj=1;
while(p&&j
{q=p;
++j;
p=p->Next;
}
e=p->Data;
if(i!
=1)
{
q->Next=p->Next;
free(p);
}
else
{e=Head->Data;
Head=Head->Next;
cout<<"你所删除的数据为:
"<return;
}
cout<<"你所删除的数据为:
"<return;
}
intmain()
{
inty,sel;
ListL;
cout<L.~List();
while
(1)
{
system("cls");
cout<cout<<"=======================链表的基本操作(菜单)========================"<cout<<"\t1、在链表L的第i个元素之前插入新的元素e."<cout<<"\t2、在链表L中删除第i个元素,并用e返回其值."<cout<<"\t3、退出程序."<cout<<"==================================================================="<cout<<"选择要执行的编号(1-3):
";
cin>>sel;
switch(sel)
{
case1:
cout<<"================插入操作================="<L.AddList();
cout<L.ShowList();
cout<L.InsertData();
cout<L.ShowList();
break;
case2:
cout<<"================删除操作================="<L.AddList();
L.ShowList();
L.DeleteData();
L.ShowList();
break;
case3:
return0;
break;
cout<}
cout<<"是否返回继续操作?
";
cout<<"是<1>,否<0>。
";
cin>>y;
if(y==0)
exit(0);
else
fflush(stdin);
}
}
七、测试数据和分析
1、插入操作:
输入数据:
L=()ListInsert(L,1,'k'),
正确结果:
L=(k)
顺序表的操作实现:
非循环单链表操作实现:
输入数据:
L=(EHIKMOP)ListInsert(L,9,'t'),
正确结果:
returnERROR;L=(EHIKMOP)
顺序表的操作实现:
非循环单链表操作实现:
输入数据:
L=(ABCEHKNPQTU)ListInsert(L,4,'u'),
正确结果:
L=(ABCuEHKNPQTU)
顺序表的操作实现:
非循环单链表操作实现:
2、删除操作:
输入数据:
L=()ListDelete(L,1,e)
正确结果:
ERROR,L=()
顺序表的操作实现:
非循环单链表操作实现:
输入数据:
L=(DEFILMNORU)ListDelete_Sq(L,5,e)
正确结果:
L=(DEFIMNORU),e='L'
顺序表的操作实现:
非循环单链表操作实现:
输入数据:
L=(CD)ListDelete_Sq(L,1,e)
正确结果:
L=(D),e='C'
顺序表的操作实现:
非循环单链表操作实现:
3、如线性表有n个结点,对两种存储结构下插入和删除的时间复杂度进行分析。
八、思考题
1、如何实现链表的逆置算法?
具体算法如下所示:
ListNode*reverseList(ListNode*head)
{
ListNode*p1,*p2,*p3;
if(head==NULL||head->next==NULL)
{
returnhead;
}
p1=head;
p2=head->next;
while(p2!
=NULL)
{
p3=p2->next;
p2->next=p1;
p1=p2;
p2=p3;
}
head->next=NULL;
head=p1;
returnhead;
}
九、实验总结感想:
这次实验因为是以前仔细的看过书所以做的比较好,也比较简单,总的来说就是在链表的实验时的删除操作比较麻烦,有些不好做,自己做删除的时候总是要好久的感觉,不知道因为什么。
这次实验是个给自己自信的机会。
说道改进其实也不知道还能有什么再好一点的,删除插入好像就这样了吧,自己就可以做的这个程度了。
计算机系数据结构实验报告
姓名:
学号:
专业班级:
计算机科学与技术091栈和队列
一、实验目的
深入了解栈和队列的特性,学会在实际问题下灵活运用它们。
二、问题描述
表达式求值运算是实现程序设计语言的基本问题之一,也是栈应用的一个典型例子。
设计并演示用算符优先级对算术表达式的求解过程。
三、实验要求
1、算法优先级别如下:
'+','-','*','/','(',')','#'
'+''>','>','<','<','<','>','>',
'-''>','>','<','<','<','>','>',
'*''>','>','>','>','<','>','>',
'/''>','>','>','>','<','>','>',
'(''<','<','<','<','<','=','',
')''>','>','>','>','','>','>',
'#''<','<','<','<','<','','='
2、以字符序列的形式从终端输入语法正确、不含变量的算术表达式,利用给出的算符优先级关系,实现对算术四则混合运算的求解过程。
3、根据给出的算符优先级,设置运算符栈和运算数栈;
4、在读入表达式的同时,完成运算符和运算数的识别处理,并将运算数的字符序列形式转换成整数形式,并进行相应的运算;
四、实验环境
PC微机
DOS操作系统或Windows操作系统
TurboC程序集成环境或VisualC++程序集成环境
五、实验算法分析
选择栈作为数据结构,所以所有操作都要围绕栈的特点来进行。
因为先入栈而被压在下面的意味着要后处理,所以优先级低的不能压着优先级高的而入栈。
对于同级的操作符,因为要按照从左往右的运算规则,所以也不能压着同级的操作符而入栈。
简单来说,与栈顶的操作符比较,优先级高的则入栈,否则操作符出栈作相应运算。
本算法使用两个栈,一个用来存放操作符,一个用来存放操作数和运算的结果。
六、实验步骤
1、问题描述:
1)以字符序列的形式从终端输入语法正确、不含变量的算术表达式,利用给出的算符优先级关系,实现对算术四则混合运算的求解过程。
2)根据给出的算符优先级,设置运算符栈和运算数栈;
3)在读入表达式的同时,完成运算符和运算数的识别处理,并将运算数的字符序列形式转换成整数形式,并进行相应的运算;
【实验程序代码具体分析如下:
】。
//////////////////main.cpp/////////////////
//#include"queue.h"
#include"stack.h"
#include
#include
#include
usingnamespacestd;
voidface()
{
cout<<"*===============================================*\n"
<<"欢迎来到(栈,队列)表达式求值\n\n"
<<"输入的表达式以=为结束\n"
<<"*===============================================*\n";
}
/*****判断运算符的优先级*****/
intpriority(charch)
{
switch(ch)
{
case'(':
case'#':
return0;break;
case'-':
case'+':
return1;break;
case'*':
case'/':
return2;break;
}
return-1;
}
/*****将中缀表达式转为后缀表达式放在Q里面*****/
voidinorderexp(Queue*Q,charstr[20])
{
StackS1,*S,S2;//S1栈用来辅助放运算符得到后缀表达式
//S2用来演示在得到后缀表达式过程中操作符在栈中的变化
cout<<"\n-----------------";
cout<<"\n操作符栈的变化:
"<charch,ch1;
stringstr1="";
S=&S1;
S->push('=');
S2=S1;
while(!
S2.empty())
{
S2.top(ch);
S2.pop();
cout<}
for(inti=0;;i++)
{
doublem3;
switch(str[i])
{
case'.':
case'0':
case'1':
case'2':
case'3':
case'4':
case'5':
case'6':
case'7':
case'8':
case'9':
str1=str1+str[i];
m3=atof(str1.c_str());
i++;
if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/'||str[i]==')'||str[i]=='=')
//当遇到了操作符或者括号是才进队列,否则继续读
{
i--;
Q->append(m3);
str1="";
break;
}
else
{
i--;
break;
}
case'(':
S->push(str[i]);
S2=S1;
while(!
S2.empty())
{
S2.top(ch);
S2.pop();
cout<}
cout<break