算法与数据结构实验报告.docx
《算法与数据结构实验报告.docx》由会员分享,可在线阅读,更多相关《算法与数据结构实验报告.docx(62页珍藏版)》请在冰豆网上搜索。
算法与数据结构实验报告
算法与数据结构实验报告
算法与数据结构实验报告
学院:
计算机与信息学院
专业班级:
姓名:
学号:
实验一 栈和队列
实验目的:
掌握栈和队列特点、逻辑结构和存储结构
熟悉对栈和队列的一些基本操作和具体的函数
定义。
利用栈和队列的基本操作完成一定功能的程序。
实验任务:
1.给出顺序栈的类定义和函数实现,利用栈的基
本操作完成十进制数 N 与其它 d 进制数的转换。
(如 N=1357,d=8)
实验原理:
将十进制数 N 转换为八进制时,采用的是“除取
余数法”,即每次用 8 除 N 所得的余数作为八进
制数的当前个位,将相除所得的商的整数部分作
为新的 N 值重复上述计算,直到 N 为 0 为止。
此时,将前面所得到的各余数反过来连接便得到
最后的转换结果。
程序清单:
#include
#include
using namespace std;
typedef int DATA_TYPE;
const int MAXLEN=100;
enum error_code
{
success,overflow,underflow
};
class stack
{
public:
stack();
bool empty()const;
error_code get_top(DATA_TYPE &x)const;
error_code push(const DATA_TYPE x);
error_code pop();
bool full()const;
private:
DATA_TYPE data[MAXLEN];
int count;
};
stack:
:
stack()
{
count=0;
}
bool stack:
:
empty()const
{
return count==0;
}
error_code
stack:
:
get_top(DATA_TYPE
&x)const
if(empty())
return underflow;
else
{
x=data[count-1];
return success;
}
}
error_code stack:
:
push(const DATA_TYPE x)
{
if(full())
return overflow;
else
{
data[count]=x;
count++;
}
}
error_code stack:
:
pop()
{
if(empty())
return underflow;
else
{
count--;
return success;
}
}
bool stack:
:
full()const
{
return count==MAXLEN;
}
void main()
{
stack S;
int N,d;
cout<<"请输入一个十进制数 N 和所需转换的进
制 d"<cin>>N>>d;
if(N==0)
{
cout<<"输出转换结果:
"<}
while(N)
S.push(N%d);
N=N/d;
}
cout<<"输出转换结果:
"<while(!
S.empty())
{
S.get_top(N);
cout<S.pop();
}
cout<}
while(!
S.empty())
{
S.get_top(x);
cout<S.pop();
}
}
测试数据:
N=1348 d=8
运行结果:
2.给出顺序队列的类定义和函数实现,并利用队
列计算并打印杨辉三角的前 n 行的内容。
(n=8)
实验原理:
杨辉三角的规律是每行的第一和最后
一个数是 1,从第三行开始的其余的数是上一行
对应位置的左右两个数之和。
因此,可用上一行
的数来求出对应位置的下一行内容。
为此,需要
用队列来保存上一行的内容。
每当由上一行的两
个数求出下一行的一个数时,其中
的前一个便需要删除,而新求出的数就要入队。
程序清单:
#include
#include
using namespace std;
typedef int DATA_TYPE;
const int MAXLEN=100;
enum error_code
{
success,underflow,overflow
};
class queue
{
public:
queue();
bool empty()const;
error_code get_front(DATA_TYPE &x)const;
error_codeappend(constDATA_TYPEx);
error_code serve();
bool full()const;
private:
int front,rear;
DATA_TYPE data[MAXLEN];
};
queue:
:
queue()
{
rear=0;
front=0;
}
bool queue:
:
empty()const
{
return (front%MAXLEN==rear%MAXLEN);
}
error_code
queue:
:
get_front(DATA_TYPE
&x)const {
if(empty())
return underflow;
else
{
x=data[front%MAXLEN];
return success;
}
}
error_code queue:
:
append(const DATA_TYPE x)
{
if(full())
return overflow;
else
{
data[rear%MAXLEN]=x;
rear++;
}
}
error_code queue:
:
serve()
{
if(empty())
return underflow;
else
{
front++;
return success;
}
}
bool queue:
:
full()const
{
return((rear+1)%MAXLEN==front); }
void main()
{
queue Q;
int num1,num2;
int i=0;
cout<<1<Q.append
(1);
num1=0;
num2=1;
for(i=0;i<=7;i++)
{
int j=0;
int k=0;
num1=0;
for(j=0;j<=i;j++)
{
Q.get_front(num2);
Q.serve();
cout<Q.append(num1+num2);
num1=num2;
}
cout<<1<Q.append
(1);
}
}
运行结果:
3.给出链栈的类定义和函数实现,并设计程序完
成如下功能:
读入一个有限大小的整数 n,并读
入 n 个数,然后按照与输入次序相反的次序输出
各元素的值。
实验原理:
依次将栈中的元素出栈,因为栈的一
个特点就是先进后出,这样,当将原栈为空时,
输出与输入次序相反,从而实现了本题的要求。
程序清单:
#include
#include
using namespace std;
typedef int DATA_TYPE;
typedef struct LNode
{
DATA_TYPE data;
LNode *next;
}LNode;
enum error_code
{
range_error,success,underflow
class linkstack
{
public:
linkstack();
~linkstack();
bool empty()const;
error_code push(const DATA_TYPE x);
error_code get_top(DATA_TYPE &x)const;
error_code pop();
private:
LNode *top;
int count;
DATA_TYPE data;
};
linkstack:
:
linkstack()
{
top=NULL;
count=0;
}
bool linkstack:
:
empty()const
{
return (count==0);
}
error_code linkstack:
:
push(const DATA_TYPE
x)
{
LNode *s=new LNode;
s->data=x;
s->next=top;
top=s;
count++;
return success;
}
error_code
&x)const
linkstack:
:
get_top(DATA_TYPE
{
if(empty())
return underflow;
else
{
x=top->data;
return success;
}
}
error_code linkstack:
:
pop()
if(empty())
return underflow;
else
{
LNode *u=new LNode;
u=top;
top=top->next;
delete u;
count--;
return success;
}
}
linkstack:
:
~linkstack()
{
while(!
empty())
{
pop();
}
}
void main()
{
linkstack L;
int n;
cout<<"请任意输入一个整数 n:
"<cin>>n;
for(int i=1;i<=n;i++)
{
L.push(i);
}
while(!
L.empty())
{
L.get_top(i);
cout<
L.pop();
}
}
测试数据:
n=9 i=1
运行结果:
实验二 单链表
实验目的:
理解线性表的链式存储结构。
熟练掌握动态链表结构及有关算法的设计。
根据具体问题的需要,设计出合理的表示数据的
链表结构,并设计相关算法。
实验任务:
1.在一个递增有序的链表 L 中插入一个值为 x
的元素,并保持其递增有序特性。
实验数据:
链表元素为
(10,20,30,40,50,60,70,80,90,100),x 分别为 25,
85,110 和 8。
实验原理 :
给出了要插入的条件,但没有给定插
入位置。
因此,需要搜索满足这一条件的插入位
置的前驱结点而不是序号。
程序清单:
#include
using namespace std;
enum error_code{
success,
overflow,
underflow,
rangeerror
};
typedef int elementtype ;
typedef struct LinkNode {
elementtypedata;
struct LinkNode*next;
} node;
class list{
private:
intcount;
node*head;
public:
list();
~list(){};
public:
error_codeget_element(constinti,
elementtype &x) const;
node * get_head() const {return head;}
void create();
void display();
void insert1(elementtype x);
};
list:
:
list(){
head = new node;
head -> next = NULL;
count = 0;
}
voidlist:
:
create(){
elementtype x; node *s,*rear;
cin >> x;
rear = head;
while ( x !
= -9999 ){
count ++;
s = new node;
s -> data = x;
s -> next=NULL;
rear -> next = s;
rear = s;
cin >> x;
}
}
void list:
:
display(){
node *p;
p=head->next;
while (p!
=NULL){
cout<data<<"";
p=p->next;
}
cout<}
void list:
:
insert(elementtype x)
{
node* u,*P;
P=head;
while(P->next!
=NULL && P->next->dataP=P->next;
if(P->next==NULL||P->next->data>x)
{ u=new node;
u->data=x;
u->next=P->next;
P->next=u;
count++;
}
}
void main()
{
list L;
elementtype x;
L.create();
L.display();
cout<<"请输入要插入的值 x"<cin>>x;
L.insert(x);
L.display();
}
运行结果:
X=25
X=85
X=110
X=8
2.将单链表L中的奇数项和偶数项结点分解开,
并分别连成一个带头结点的单链表,然后再将这
两个新链表同时输出在屏幕上,并保留原链表的
显示结果,以便对照求解结果。
实验测试数据:
第
一
组
数
据
:
链
表
为
(1,2,3,4,5,6,7,8,9,10,20,30,40,50,60)
第
二
组
数
据
:
链
表
为
(10,20,30,40,50,60,70,80,90,100)
实验原理:
依据题目的要求,需要再创建两个新
链表来存储分离后的奇偶项,而奇偶项可以根据
数字来控制,把他们取出来并重新连起来。
程序清单:
#include
using namespace std;
enum error_code{
success,
overflow,
underflow,
rangeerror
};
typedef int elementtype ;
typedef struct LinkNode {
elementtypedata;
struct LinkNode*next;
} node;
class list{
private:
intcount;
node*head;
public:
list();
~list(){};
public:
node * get_head() const {return head;}
void create();
void display();
};
list:
:
list(){
head = new node;
head -> next = NULL;
count = 0;
}
voidlist:
:
create(){
elementtype x; node *s,*rear;
cin >> x;
rear = head;
while ( x !
= -9999 ){
count ++;
s = new node;
s -> data = x;
s -> next=NULL;
rear -> next = s;
rear = s;
cin >> x;
}
}
void list:
:
display(){
node *p;
p=head->next;
while (p!
=NULL){
cout<data<<"";
p=p->next;
}
cout<}
voiddivide(list A, list &B,list &C)
{
node *PA,*PB,*PC,*s;
PB=B.get_head();
PC=C.get_head();
PA = A.get_head() -> next;
while ( PA !
= NULL )
{
if((PA->data)%2!
=0)
{
s=new node;
s->data=PA->data;
PB->next = s;
PB=s;
PB->next=NULL;
PA=PA->next;
}
else
{
s=new node;
s->data=PA->data;
PC->next = s;
PC=s;
PC->next=NULL;
PA=PA->next;
}
}
}
void main()
{
list L,L1,L2;
L.create();
divide(L,L1,L2);
cout<<"原链表:
"<L.display();
cout<<"偶链表:
"<L2.display();
cout<<"奇链表:
"<L1.display();
实验结果:
第一组数据:
第二组数据:
1. 求两个递增有序链表 L1 和 L2 中的公共元素,
并以同样方式连接成链表 L3。
实验测试数据:
第一组数据:
第一个链表为(1,3,6,10,15,16,17,18,
19,20)
第二个链表为( 1,2,3,4,5,6,7,8,9,
10,18,20,30)
第二组数据:
第一个链表元素为 (1,3,6,10,15,16,17,
18,19,20)
第二个链表元素为 (2,4,5,7,8,9,12,
22)
实验原理:
设置两个指针怕,pa,pb 分别依次指
示 A,B 表 中 的 元 素 , 其 初 始 值 分 别 为
A.head->next 和 B.head->next。
在 pa,pb 均非空
时,根据其值的大小关系可能有如下三种情况。
(1).pa->data==pb->data:
搜索到公共元素,应在
C 表表尾插入一个结点,其值为 pa->data,然后
继续 A 表中下一个元素的搜索,即 pa=pa->next,
同时 pb 也往后移。
(2). pa->data>pb->data:
表明 A 表中这一元素可
能在 B 表当前元素的后面,因此要往 B 表的后面
搜索,故而执行 pb=pb->next,然后继续搜索。
(3). pa->datadata:
表明 A 中这一元素在 B
中不存在,因而执行 pa=pa->next 以继续对 A 表
中下一个元素的判断。
反复执行上述比较,直
到 pa,pb 至少有一个为空为止。
此时,剩余的非
空部分没有所需要的公共元素,因而搜索结束。
程序清单:
#include
#include
using namespace std;
typedef struct snode
{
int data;
struct snode *next;
}node;
enum error_code{arrange_error,success};
class list
{
public:
list();
void create2();
int length() const;
error_code get_element(const int i,int &x) const;
error_code insert(const int &x);
error_code delete_element(const int i);
node *locate(const int x) const;
node *get_head(){return head;}
void list:
:
gongyou(list &L1,list &L2)
void print();
private:
int count;
node *head;
};
list:
:
list()
{
head=new node; head->next=NULL;
count=0;
}
void list:
:
create2()
{
int x; node *p=head;
node *s; cout<<"输入一个值:
";
cin>>x;
while(x!
=-1)
{
s=new node; s->data=x;
s->next=NULL; p->next=s;
p=s; cout<<"输入一个值:
";
cin>>x;
}
}
int list:
:
length() const
{
return count;
}
error_code list:
:
get_element(const int i,int &x)
const
{
int j=1; node *p=head->next;
while(p!
=NULL&&j!
=i)
{
p=p->next; j++;
}
if(p==NULL)
return arrange_error;
x=p->data;
return success;
}
void list:
:
gongyou(list &L1,list &L2)
{
node*p1=L1.head->next;node
*p2=L2.head->next;
node *p3=head; node *u;
while(p1!
=NULL&&p2!
=NULL)
{
if(p1->data==p2->data)
{
u=new node; u->data=p1->data; p3->next=u;
p1=p1->next; p2=p2->next; p3=p3->next;
}
else{
if(p1->datadata)
p1=p1->next;
else
p2=p2->next;
}
}
p3->next=NULL;
}
node *list:
:
locate(const int x) const
{
node *p=head->next;
while(p!
=NULL)
{
if(p->data==x)
return p;
p=p->next;
}
return NULL;
}
void list:
:
divide(list &B,list &C)
{
node *u; node *pa=head->next;