数据结构实验报告(合工大)

时间:2024.3.31

数据结构实验报告

实验一:栈和队列

实验目的:

掌握栈和队列特点、逻辑结构和存储结构

熟悉对栈和队列的一些基本操作和具体的函数定义。

利用栈和队列的基本操作完成一定功能的程序。

实验任务

1.给出顺序栈的类定义和函数实现,利用栈的基本操作完成十进制数N与其它d进制数的转换。(如N=1357,d=8)

实验原理:将十进制数N转换为八进制时,采用的是“除取余数法”,即每次用8除N所得的余数作为八进制数的当前个位,将相除所得的商的整数部分作为新的N值重复上述计算,直到N为0为止。此时,将前面所得到的各余数反过来连接便得到最后的转换结果。

程序清单

#include<iostream>

#include<cstdlib>

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"<<endl;

cin>>N>>d;

if(N==0)

{

cout<<"输出转换结果:"<<N<<endl;

}

while(N)

{

S.push(N%d);

N=N/d;

}

cout<<"输出转换结果:"<<endl;

while(!S.empty())

{

       S.get_top(N);

cout<<N;

S.pop();

}

cout<<endl;

}

while(!S.empty())

{

S.get_top(x);

cout<<x;

S.pop();

}

}

测试数据:N=1348  d=8

运行结果:

2.给出顺序队列的类定义和函数实现,并利用队列计算并打印杨辉三角的前n行的内容。(n=8)

实验原理:杨辉三角的规律是每行的第一和最后一个数是1,从第三行开始的其余的数是上一行对应位置的左右两个数之和。因此,可用上一行的数来求出对应位置的下一行内容。为此,需要用队列来保存上一行的内容。每当由上一行的两个数求出下一行的一个数时,其中的前一个便需要删除,而新求出的数就要入队。

程序清单:

#include<iostream>

#include<cstdlib>

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_code append(const DATA_TYPE x);

       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<<endl;

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<<num1+num2<<" ";

Q.append(num1+num2);

num1=num2;

}

cout<<1<<endl;

Q.append(1);

}

}

运行结果:

3.给出链栈的类定义和函数实现,并设计程序完成如下功能:读入一个有限大小的整数n,并读入n个数,然后按照与输入次序相反的次序输出各元素的值。

实验原理:依次将栈中的元素出栈,因为栈的一个特点就是先进后出,。这样,当将原栈为空时,输出与输入次序相反,从而实现了本题的要求。

程序清单:

#include<iostream>

#include<cstdlib>

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 linkstack::get_top(DATA_TYPE &x)const

{

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:"<<endl;

cin>>n;

for(int i=1;i<=n;i++)

{

L.push(i);

}

while(!L.empty())

{

L.get_top(i);

cout<<i<<" ";

L.pop();

}

}

测试数据:n=9  i=1

运行结果:

实验二:单链表

实验目的:

理解线性表的链式存储结构。

熟练掌握动态链表结构及有关算法的设计。

根据具体问题的需要,设计出合理的表示数据的链表结构,并设计相关算法。

实验任务:

在一个递增有序的链表L中插入一个值为x的元素,并保持其递增有序特性。

1.实验数据:链表元素为(10,20,30,40,50,60,70,80,90,100,x分别为25851108

实验原理:给出了要插入的条件,但没有给定插入位置。因此,需要搜索满足这一条件的插入位置的前驱结点而不是序号。

程序清单:

#include<iostream>

#include<cstdlib>

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 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;

}

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;

}

error_code list::insert(const int &x)

{

       node *s;         node *q=head;             node *p=head->next;

       while(p!=NULL&&p->data<x)

       {

              q=p;                     p=p->next;

       }

       if(p==NULL)

       {

              s=new node;                s->data=x;

              s->next=NULL;                  q->next=s;            count++;

       }

       else{

              s=new node;         s->data=x;            s->next=q->next;

              q->next=s;            count++;

       }

       return success;

}

error_code list::delete_element(const int i)

{

       node *u;        node *p=head;             int j=0;

       while(j!=i-1&&p!=NULL)

       {

              p=p->next;           j++;

       }

       if(i<1||i>count)

              return arrange_error;

       u=p->next;                  p->next=u->next;

       delete u;                      count--;

       return success;

}

void list::print()

{

       node *p=head->next;

       while(p!=NULL)

       {

              cout<<p->data<<"  ";

              p=p->next;

       }

       cout<<endl;

}

void main()

{

       list l;

       int x;

       cout<<"创建一个链表(输入‘-1’结束)"<<endl;

       l.create2();

       cout<<"输入要插入的数(输入‘-1’结束):"<<endl;

       cout<<"输入一个数:";

       cin>>x;

       while(x!=-1)

       {

              l.insert(x);

              cout<<"输入一个数:";

              cin>>x;

       }

       l.print();

}

测试数据:链表元素为(10,20,30,40,50,60,70,80,90,100),x分别为25,85,110和8

运行结果:

2.将单链表L中的奇数项和偶数项结点分解开,并分别连成一个带头结点的单链表,然后再将这两个新链表同时输出在屏幕上,并保留原链表的显示结果,以便对照求解结果。

实验原理:依据题目的要求,需要再创建两个新链表来存储分离后的奇偶项,而奇偶项可以根据数字来控制,把他们取出来并重新连起来。

程序清单:

#include<iostream>

#include<cstdlib>

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;}

       divide(list &B,list &C);

       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;

}

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;

       node *pb=B.get_head();                    node *pc=C.get_head();

       for(int i=0;pa!=NULL;i++,pa=pa->next)

       {

              u=new node;                u->data=pa->data;

              if(i%2==0)

              {

                     pb->next=u;                pb=pb->next;

              }

              else

              {

                     pc->next=u;                 pc=pc->next;

              }

              pb->next=NULL;                pc->next=NULL;

       }

}

error_code list::insert(const int &x)

{

       node *s;         node *q=head;             node *p=head->next;

       while(p!=NULL&&p->data<x)

       {

              q=p;                     p=p->next;

       }

       if(p==NULL)

       {

              s=new node;                s->data=x;

              s->next=NULL;                  q->next=s;            count++;

       }

       else{

              s=new node;         s->data=x;            s->next=q->next;

              q->next=s;            count++;

       }

       return success;

}

error_code list::delete_element(const int i)

{

       node *u;        node *p=head;             int j=0;

       while(j!=i-1&&p!=NULL)

       {

              p=p->next;           j++;

       }

       if(i<1||i>count)

              return arrange_error;

       u=p->next;                  p->next=u->next;

       delete u;                      count--;

       return success;

}

void list::print()

{

       node *p=head->next;

       while(p!=NULL)

       {

              cout<<p->data<<"  ";

              p=p->next;

       }

       cout<<endl;

}

void main()

{

       list A,B,C;                 int x,y,z;

       A.create_R();        A.divide(B,C);

       cout<<"原表:";        A.output();

       cout<<"奇数表:";                  B.output();

       cout<<"偶数表:";                  C.output();

}

测试数据:第一组数据:链表元素为 (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

运行结果:

3.求两个递增有序链表L1和L2中的公共元素,并以同样方式连接成链表L3

实验原理设置两个指针怕,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->data<pb->data:表明A中这一元素在B中不存在,因而执行pa=pa->next以继续对A表中下一个元素的判断。

       反复执行上述比较,直到pa,pb至少有一个为空为止。此时,剩余的非空部分没有所需要的公共元素,因而搜索结束。

程序清单:

#include<iostream>

#include<cstdlib>

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->data<p2->data)

                            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;

       node *pb=B.get_head();                    node *pc=C.get_head();

       for(int i=0;pa!=NULL;i++,pa=pa->next)

       {

              u=new node;                u->data=pa->data;

              if(i%2==0)

              {

                     pb->next=u;                pb=pb->next;

              }

              else

              {

                     pc->next=u;                 pc=pc->next;

              }

              pb->next=NULL;                pc->next=NULL;

       }

}

error_code list::insert(const int &x)

{

       node *s;         node *q=head;             node *p=head->next;

       while(p!=NULL&&p->data<x)

       {

              q=p;                     p=p->next;

       }

       if(p==NULL)

       {

              s=new node;                s->data=x;

              s->next=NULL;                  q->next=s;            count++;

       }

       else{

              s=new node;         s->data=x;            s->next=q->next;

              q->next=s;            count++;

       }

       return success;

}

error_code list::delete_element(const int i)

{

       node *u;        node *p=head;             int j=0;

       while(j!=i-1&&p!=NULL)

       {

              p=p->next;           j++;

       }

       if(i<1||i>count)

              return arrange_error;

       u=p->next;                  p->next=u->next;

       delete u;                      count--;

       return success;

}

void list::print()

{

       node *p=head->next;

       while(p!=NULL)

       {

              cout<<p->data<<"  ";

              p=p->next;

       }

       cout<<endl;

}

void main()

{

       list L1,L2,L3;

       L1.create_R();   L2.create_R();             L3.gongyou(L1,L2);

       cout<<"共有的元素为:";                     L3.output();

}

测试数据:第一组数据:

             第一个链表元素为 (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

运行结果:

实验三:二叉树

一、             实验目的

1. 掌握二叉树的动态链表存储结构及表示。

2. 掌握二叉树的三种遍历算法(递归和非递归两类)。

3. 运用二叉树三种遍历的方法求解有关问题。

二、实验任务

1.       建立一棵采用二叉链表结构存储的二叉树。

2.       分别采用递归和非递归两种方式对该二叉树进行先序、中序和后序遍历。

3.       求二叉树的高度以及二叉树中叶子结点的数目。

实验原理:在二叉链表存储结构中,每个结点应包括存储结点值的数据部分及指向两个孩子结点的指针,不妨设为data,lchild和rchild。对二叉树的遍历是在对各子树分别遍历的基础之上进行的。由于各子树的遍历和整个二叉树的遍历方式相同,因此,可借助对整个二叉树的遍历算法来实现对左、右子树的遍历。

程序清单:

#include<iostream.h>

#define maxlen 200

enum tagtype{L1,L2};

typedef struct node

{

char data;     struct node *lchild,*rchild;

}bnode;

typedef struct{

      bnode *ptr;     tagtype tag;

}stacknode;

enum error_code{success,underflow,overflow};

class stack

{

public:

stack();

bool empty()const;

bool full()const;

error_code get_top(stacknode &x);

error_code get_top(bnode* &x);

error_code push(stacknode x);

error_code push(bnode* x);

error_code pop();

private:

int count;                    bnode* data_xian[maxlen];

stacknode data_hou[maxlen];

};

stack::stack()

{

count=0;

}

bool stack::empty()const

{

if(count==0)

       return true;

return false;

}

bool stack::full()const

{

if(count==maxlen)

       return true;

return false;

}

error_code stack::get_top(stacknode &x)

{

if(empty())

       return underflow;

x=data_hou[count-1];

return success;

}

error_code stack::get_top(bnode* &x)

{

if(empty())

       return underflow;

x=data_xian[count-1];

return success;

}

error_code stack::push(stacknode x)

{

if(full())

       return overflow;

data_hou[count]=x;     count++;

return success;

}

error_code stack::push(bnode* x)

{

if(full())

       return overflow;

data_xian[count]=x;    count++;

return success;

}

error_code stack::pop()

{

if(empty())

       return underflow; count--;

return success;

}

bitree.h

#include"stack.h"

class bitree

{

public:

bitree();

bnode *create();

bnode *get_root(){return root;}

int max(int a,int b);

void preorder1(){preorder1(root);}

void inorder1(){inorder1(root);}

void postorder1(){postorder1(root);}

void preorder2(){preorder2(root);}

void inorder2(){inorder2(root);}

void postorder2(){postorder2(root);}

int high(bnode *T);

int leaf(bnode *T);

private:

bnode *root;

void visite(bnode *T);

void preorder1(bnode *T);

void inorder1(bnode *T);

void postorder1(bnode *T);

void preorder2(bnode *T);

void inorder2(bnode *T);

void postorder2(bnode *T);

};

bitree::bitree()

{

root=NULL;

}

bnode* bitree::create()

{

char ch;         bnode *p;

cout<<"输入二叉树的值:";                 cin>>ch;

if(ch=='#')

       return NULL;

p=new bnode;                     p->data=ch;

if(root==NULL)

       root=p;

p->lchild=create();                     p->rchild=create();

return p;

}

int bitree::max(int a,int b)

{

if(a>=b)

       return a;

return b;

}

void bitree::preorder1(bnode *T)

{

if(T!=NULL)

{

       visite(T);        preorder1(T->lchild);          preorder1(T->rchild);

}

}

void bitree::inorder1(bnode *T)

{

if(T!=NULL)

{

       preorder1(T->lchild);          visite(T);        preorder1(T->rchild); 

}

}

void bitree::postorder1(bnode *T)

{

if(T!=NULL)

{

       preorder1(T->lchild);          preorder1(T->rchild);         visite(T);

}

}

void bitree::preorder2(bnode *T)

{

stack s;

if(T!=NULL)

{

       s.push(T);

       while(!s.empty())

       {

              s.get_top(T);         s.pop();         visite(T);

              if(T->rchild!=NULL)

                     s.push(T->rchild);

              if(T->lchild!=NULL)

                     s.push(T->lchild);

       }cout<<endl;

}

}

void bitree::inorder2(bnode *T)

{

stack s;

if(T!=NULL)

{

       while(T!=NULL||!s.empty())

       {

              while(T!=NULL)

              {

                     s.push(T);                    T=T->lchild;

              }

              if(!s.empty())

              {

                     s.get_top(T);         s.pop();

                     visite(T);               T=T->rchild;

              }

       }cout<<endl;

}

}

void bitree::postorder2(bnode *T)

{

stack s;

stacknode x;

    do{    

       while(T!=NULL)

    {     

              x.ptr=T;        x.tag=L1;

              s.push(x);             T=T->lchild;

       }

        int continue1=1;

       while(!s.empty()&&continue1)

       {

              s.get_top(x);  s.pop();        T=x.ptr;

        switch(x.tag)

              {

                     case L1: x.tag=L2;

                s.push(x);      T=T->rchild;       continue1=0;

                            break;

                     case L2:visite(T);

                                   break;

              }

        }

       }while(!s.empty());

       cout<<endl;

}

int bitree::high(bnode *T)

{

if(T==NULL)

       return 0;

else

       return max(high(T->lchild),high(T->rchild))+1;

}

int bitree::leaf(bnode *T)

{

if(T==NULL)

       return 0;

if(T->lchild==NULL&&T->rchild==NULL)

       return 1;

return leaf(T->lchild)+leaf(T->rchild);

}

void bitree::visite(bnode *T)

{

cout<<T->data<<" ";

}

void main()

{

bitree b;        int x;

cout<<"创建一个先序二叉树(输入‘#’为空):"<<endl;        b.create();

cout<<"1.递归遍历"<<"     "<<"2.非递归遍历"<<endl;

cout<<"输入你的选择(输入-1退出):";           cin>>x;

while(x!=-1)

{

       switch(x){

       case 1:   

              cout<<"先序遍历为:";           b.preorder1();             cout<<endl;

              cout<<"中序遍历为:";           b.inorder1();        cout<<endl;

              cout<<"后序遍历为:";           b.postorder1();            cout<<endl;

              cout<<"树的高度为:";           cout<<b.high(b.get_root())<<endl;

              cout<<"叶子结点数为:";              cout<<b.leaf(b.get_root())<<endl;

              break;

       case 2:

              cout<<"先序遍历为:";                  b.preorder2();

              cout<<"中序遍历为:";                  b.inorder2();

              cout<<"后序遍历为:";                  b.postorder2();

              cout<<"树的高度为:";                  cout<<b.high(b.get_root())<<endl;

              cout<<"叶子结点数为:";              cout<<b.leaf(b.get_root())<<endl;

              break;

       }cout<<endl;

       cout<<"1.递归遍历"<<"     "<<"2.非递归遍历"<<endl;

       cout<<"输入你的选择(输入-1退出):";           cin>>x;

}

}

运行结果:

实验四:图

一、             实验目的

1. 掌握图的基本概念。

2. 掌握图的存储结构的设计与实现,基本运算的实现。

3. 掌握图的两种遍历算法,以及遍历算法的应用。

二、实验任务

1.分别以邻接矩阵和邻接表的存储结构建立图。

2.分别对图进行深度优先遍历和广度优先遍历。

3.求图中边的数目。

实验原理:邻接矩阵是表示图中顶点之间邻接关系的矩阵,即表示各顶点之间是否有边关系的矩阵。因此,对有n个顶点的图来说,其邻接矩阵A为n*n阶的,其中Aij表示顶点vi到vj之间是否有边或弧:若存在,则Aij为1,否则为0。邻接表的表示方式是将每个顶点的邻接点连成链表,并将各链表的表头指针合在一起,其中每个头指针与该结点的信息合为一个整体结点。在执行遍历dfs(v)时,搜索下一个访问顶点是从当前访问顶点v的邻接表中搜索的,因此,每搜索到一个邻接点即意味着搜索到一条以v为一个端点的边或弧,故应在dfs算法中计数。

程序清单

#include<iostream>

#include<cstdlib>

using namespace std;

const int maxvertex=100;

class graph

{

public:

       graph();

       void createadj();

       void trave_dfs();

       void trave_bfs();

       void dfs(int v);

       void bfs(int v);

       int firstadj(int v);

       int nextadj(int v,int m);

       void visit(int v);

       void edgenum();

       void dijkstra(int v0);

private:

       int vertex[maxvertex];

       int edge[maxvertex][maxvertex];

       int currentvertex;

       bool visited[maxvertex];

};

graph::graph()

{

       int i,j;

       for(i=0;i<maxvertex;i++)           vertex[i]=0;

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

              for(j=0;j<maxvertex;j++)

                     edge[i][j]=0;

}

void graph::createadj()

{

       int i,j,k;

       cout<<"输入当前顶点数:";             cin>>currentvertex;

       for(k=0;k<currentvertex;k++)

       {

              cout<<"输入第"<<k+1<<"个顶点的值:";

              cin>>vertex[k];

       }

       cout<<"输入两个顶点的值(输入-1,-1结束):";                cin>>i>>j;

       while(i!=-1&&j!=-1)

       {

              edge[i][j]=edge[j][i]=1;

              cout<<"输入两个顶点的值(输入-1,-1结束):";         cin>>i>>j;

       }

}

void graph::trave_dfs()

{

       int i;

       for(i=0;i<currentvertex;i++)             visited[i]=false;

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

              if(!visited[i])

                     dfs(vertex[i]);

}

void graph::trave_bfs()

{

       int i;

       for(i=0;i<currentvertex;i++)             visited[i]=false;

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

              if(!visited[i])

                     bfs(vertex[i]);

}

void graph::dfs(int v)

{

       int w;            visit(v);

       visited[v]=true;            w=firstadj(v);

       while(w!=-1)

       {

              if(!visited[w])        dfs(w);

              w=nextadj(v,w);

       }

}

void graph::bfs(int v)

{

       queue Q;

       int w,x;          visit(v);

       visited[v]=true;            Q.append(v);

       while(!Q.empty())

       {

              Q.get_front(x);     v=x;

              Q.serve();             w=firstadj(v);

              while(w!=-1)

              {

                     if(!visited[w])

                     {

                            visit(w);         visited[w]=true;

                            Q.append(w);

                     }w=nextadj(v,w);

              }

       }

}

int graph::firstadj(int v)

{

       if(v!=-1)

       {

              for(int i=0;i<currentvertex;i++)

                     if(edge[v][i]>0)

                            return i;

       }return -1;

}

int graph::nextadj(int v,int m)

{

       if(v!=-1&&m!=-1)

       {

              for(int i=m+1;i<currentvertex;i++)

                     if(edge[v][i]>0)

                            return i;

       }return -1;

}

void graph::visit(int v)

{

       cout<<v<<"  ";

}

void graph::edgenum()

{

       int num=0,i,j;

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

              for(j=0;j<currentvertex;j++)

                     if(edge[i][j]>0)

                            num++;

       cout<<num/2<<endl;

}

void main()

{

       graph G;

       cout<<"用邻接矩阵存储建立图:";  G.createadj();              cout<<endl;

       cout<<"对图的深度优先遍历:";            G.trave_dfs();              cout<<endl;

       cout<<"对图的广度优先遍历:";            G.trave_bfs();              cout<<endl;

       cout<<"该图的边数为:";                     G.edgenum();

}

实验五:查找

一、             实验目的

1. 掌握顺序表的查找方法,尤其是二分查找方法。

2. 掌握二叉排序树的建立与查找。

二、实验任务

1.         对下列数据表,分别采用二分查找算法实现查找,给出查找过程依次所比较的元素(的下标),并以二分查找的判定树来解释。

实验原理:设查找区域的首尾下标分别用变量low和high表示,将待查关键字x和该区域的中间元素的关键字进行比较。

程序清单

#include<iostream.h>

int bin_search(int a[],int n,int x);

int bin[25];    int i=0;

void main()

{

       int a[]={1,2,3,4,6,7,8,9,10,11,12,13,17,18,19,20,24,25,26,30,35,40,45,50,100};

       int x,n,num;         n=sizeof(a)/4;

       cout<<"二分查找为(输入-1查找结束):"<<endl;

       cout<<"输入要查找的数:";                 cin>>x;

       while(x!=-1)

       {

              num=bin_search(a,n,x);

              if(num==-1)

                     cout<<"查无此数。"<<endl;

              else{

                     cout<<"要查找的数的下标为:"<<num<<endl;

                     cout<<"依次查找的下标为:";

                     for(int j=0;j<i;j++)

                            cout<<bin[j]<<"  ";

                     i=0;               cout<<endl;

              }

              cout<<"输入要查找的数:";                 cin>>x;

       }

}

int bin_search(int a[],int n,int x)

{

       int mid,low=0,high=n-1;

       while(low<=high)

       {

              mid=(low+high)/2;              bin[i]=mid;    i++;

              if(a[mid]==x) return mid;

              else if(a[mid]<x)   low=mid+1;

              else                high=mid-1;

       }return -1;

}

测试数据

数据表为 (1,2,3,4,6,7,8,9,10,11,12,13,17,18,19,20,24,25,26,30,35,40,45,50,100)

查找的元素分别为: 2,8,20, 30,50,5,15,33,110

运行结果:

实验六:排序

一、             实验目的

1. 掌握各种内部排序算法。

2. 理解各种内部排序算法的特性、时间性能和空间性能,在此基础上能根据具体情况选择合适的排序算法。

二、实验任务

1.       实现希尔排序算法,并观察在采用不同的步长选取方法对排序过程中数据的比较和移动次数的影响。

实验原理:将待排序列划分为若干组,在每组内进行直接插入排序,以使整个序列基本有序,然后再对整个序列进行直接插入排序。

程序清单

#include<iostream.h>

void shell_sort(int a[],int n);

void main()

{

       int n;

       int a[]={180,203,32,46,25,76,17,58,99,100,11,102,13,54,75,6,27,18,19,29,2,82};

       n=sizeof(a)/4;        shell_sort(a,n);

       cout<<"希尔排序后为:";

       for(int i=0;i<n;i++)

              cout<<a[i]<<"  ";

       cout<<endl;

}

void shell_sort(int a[],int n)

{

       int i,j,temp,d=n/2;

       while(d>0)

       {

              for(i=d;i<n;i++)

              {

                     temp=a[i];            j=i-d;

                     while(j>=0&&a[j]>temp)

                     {

                            a[j+d]=a[j];          j=j-d;

                     }a[j+d]=temp;

              }d=d/2;

       }

}

运行结果

2.       实现堆排序算法,给出排序结果。

  

实验原理:首先,由无序序列建堆可通过反复调用筛选操作来实现。为此,需满足筛选的条件,即左、右子树必须为堆。因此,建堆过程要从下往上逐棵子树的进行筛选。从易于编程的角度出发,根的下标自然是按从大到小,即按照根的下标从n/2到1的次序调整各子树为堆。排序可通过反复执行如下操做而最终得到一个有序序列:输出根:即将根与当前子序列中的最后一个元素交换;调整根:将输出根之后的子序列调整为堆。

程序清单

#include<iostream.h>

void sift(int a[],int k,int m);

void heap_sort(int a[],int n);

void main()

{

       int i,n;

       int a[]={106,213,325,446,579,654,721,870,917,510,21,632,73,14,815,316,412,18,619,720,21,808,923,25,26};

       n=sizeof(a)/4;

       cout<<"堆排序的结果为:";          heap_sort(a,n);            cout<<endl;

}

void sift(int a[],int k,int m)

{

       int i,j,x;         bool finished=false;

       x=a[k];          i=k;        j=k*2;

       while(j<m&&!finished)

       {

              if(j<m&&a[j]<a[j+1])  j=j+1;

              if(x>=a[j])            finished=true;

              else{

                     a[i]=a[j];              i=j;         j=j*2;

              }

       }a[i]=x;

}

void heap_sort(int a[],int n)

{

       int i;

       for(i=(n-1)/2;i>=0;i--)         sift(a,i,n-1);

       for(i=n-1;i>=1;i--)

       {

              cout<<a[0]<<"  ";

              a[0]=a[i];              sift(a,0,i-1);

       }

}

测试数据

(106,213,325,446,579,654,721,870,917,510,21,632,73,14,815,316,412 ,18,619,720,21,808,923,

25,26)

运行结果

更多相关推荐:
数据结构实验报告

实验报告实验课程:数据结构实验项目:实验专业:计算机科学与技术姓名:**学号:***指导教师:**实验时间:20**-12-7重庆工学院计算机学院数据结构实验报告实验一线性表1.实验要求掌握数据结构中线性表的基…

数据结构实验报告(C语言)(强力推荐)

数据结构实验实验内容和目的掌握几种基本的数据结构集合线性结构树形结构等在求解实际问题中的应用以及培养书写规范文档的技巧学习基本的查找和排序技术让我们在实际上机中具有编制相当规模的程序的能力养成一种良好的程序设计...

数据结构实验———图实验报告

数据结构实验报告目的要求掌握图的存储思想及其存储实现掌握图的深度广度优先遍历算法思想及其程序实现掌握图的常见应用算法的思想及其程序实现实验内容键盘输入数据建立一个有向图的邻接表输出该邻接表3在有向图的邻接表的基...

数据结构实验报告格式

数据结构实验报告格式实验11顺序表的基本操作一实验目的1掌握使用VC上机调试线性表的基本方法2掌握线性表的基本操作插入删除查找等运算在顺序存储结构上的实现二实验内容顺序表的基本操作的实现三实验要求1认真阅读和理...

数据结构实验报告全集

数据结构实验报告全集实验一线性表基本操作和简单程序1实验目的1掌握使用VisualC60上机调试程序的基本方法2掌握线性表的基本操作初始化插入删除取数据元素等运算在顺序存储结构和链表存储结构上的程序设计方法2实...

数据结构实验报告5

计算机科学与工程系计算机科学与工程系2计算机科学与工程系附录可包括源程序清单或其它说明includeltiostreamgtincludeltstdiohgtusingnamespacestdtypedefst...

数据结构实验报告[4]

云南大学数据结构实验报告第四次实验学号姓名一实验目的复习线性表的逻辑结构存储结构及基本操作掌握顺序表和带头结点单链表了解有序表二实验内容必做题假设有序表中数据元素类型是整型请采用顺序表或带头结点单链表实现Ord...

数据结构树的实验报告

数据结构实验报告目的要求1掌握二叉树的存储实现2掌握二叉树的遍历思想3掌握二叉树的常见算法的程序实现实验内容1输入字符序列建立二叉链表2中序遍历二叉树递归算法3中序遍历二叉树非递归算法最好也能实现先序后序非递归...

数据结构实验报告

武汉大学国际软件学院实验报告课程名称专业年级姓名学号协作者实验学期课堂时数填写时间月6小结对本次实验的心得体会所遇到的问题及解决方法其他思考和建议7指导教师评语及成绩指导教师依据学生的实际报告内容用简练语言给出...

数据结构第一次上机实验报告

数据结构第一次上机实验报告线性表实验要求1实现顺序表结构的创建插入删除查找等操作2利用上述顺序表操作实现如下程序建立两个顺序表表示的集合集合中无重复的元素并求这样的两个集合的并交和源程序C实现visualstu...

数据结构实验报告(重邮)5个

学号数据结构实验报告学院班级姓名实验一线性链表的实现与操作题目设计一个100位以内的长整数加减运算的程序班级姓名学号完成日期一需求分析1本实验中100位长整数的每位上的数字必须为数字09之间长整数的位数并要求1...

安徽工业大学数据结构实验报告

安徽工业大学计算机学院数据结构实验报告姓名学号班级教师内容线性表基本操作的实现栈的基本操作串的模式匹配二叉树操作图的创建与遍历20xx525实验一线性表基本操作的实现一实验目的1掌握使用TurboC20上机调试...

数据结构实验报告(46篇)