数据结构实验报告

时间:2024.4.5


上篇程序设计基础

实验数据类型、运算符和表达式

一、             实验目的:

1.掌握C语言数据类型,熟悉如何定义整型、字符型、实型变量,以及对它们赋值的方法,了解以上数据类型输出时所使用的格式转换符号。

2.学会使用C的有关运算符,以及包含这些运算符号的表达式,特别是自加(++)和自减(——)运算符的使用。

3.进一步熟悉C程序的编辑、编译、连接和运行的过程。

二、             实验内容:

1.输入以下程序,并编译、运行,分析运行结果:

main()

{ char c1,c2;

c1=97;c2=98;

printf(″% c  %c″,c1,c2);

}

运行输出结果a,b

2.输入并运行以下程序:

main()

{ int i,j,m,n;

i=8;j=10;

m=++i;n=j++;

printf(″%d,%d,%d,%d″,i,j,m,n);

}

分别作以下改动并运行:

(1)将第四行改为: m=i++;n=++j;

运行输出结果9,11,8,11

(2)程序改为:

main()

{ int i,j;

i=8;j=10;

printf(″%d,%d″,i++,j++);

}

运行输出结果8,10

(3)在(2)的基础上,将printf语句改为:

printf(″%d,%d″,++i,++j);

运行输出结果9,11

(4)再将printf语句改为:

printf(″%d,%d,%d,%d″,i,j,i++,j++);

运行输出结果8,10,8,10

(5)程序改为:

main()

{ int i,j,m=0,n=0;

i=8;j=10;

m+=i++;n-=--j;

printf(″i=%d,j=%d,m=%d,n=%d″,i,j,m,n);

}

运行输出结果i=9,j=9,m=8,n=-9

3.先判断以下程序的输出结果,再运行验证。

main()

{  int i=3,j=2,a,b,c,d;

d=(i*3,j=10);

a=(--i==j++)? --i:++j;

b=i++;

c=j;

printf(″%d,%d,%d,%d\n″,a,b,c,d);

}

运行输出结果12,2,12,10


实验2  顺序程序设计

一、     实验目的:

1.掌握赋值语句的使用。

2.掌握数据的输入输出方法,能正确使用各种格式转换符。

二、     实验内容:

1.输入以下程序:

 #include "stdio.h"

main()

{

int i;

char j;

for(i=1;i<10;i++)

{

scanf("%c",&j);

printf("%c",j);

}

}

(1)运行程序,输入a↙b↙c↙d↙e↙f↙g↙h↙i↙

观察程序的执行结果,是否能够输出字母a,b,c,d,e,f,g,h,i。为什么?

能够输出abcdefghi

(2)在scanf语句后面加上语句:

getchar();

运行程序,输入a↙b↙c↙d↙e↙f↙g↙h↙i↙

观察程序的执行结果,是否能够输出字母a,b,c,d,e,f,g,h,i。为什么?

不能输出abcdefghi,输出结果为acegi

2.编制一程序,用getchar函数输入字符,然后用putchar函数输出字符,同时要求输出字符的ASCII码。分别考虑用int和char型变量来接收键盘输入的字符,两者是否等价?

(1)

#include "stdio.h"

void main()

{

    char c;

    printf("请输入一个字符!\n");

    c=getchar();

    putchar(c);

    printf("\n");

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

}

(2)

#include "stdio.h"

void main()

{

    int c;

    printf("请输入一个字符!\n");

    c=getchar();

    putchar(c);

    printf("\n");

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

}

实验逻辑运算和判断选取控制

一、             目的要求

1.了解C语言表示逻辑量的方法(以0代表“假”,以1代表“真”);

2.学会正确使用逻辑运算符和逻辑表达式;

3.熟练掌握if语句和switch语句

二、             实验内容

先编程序,解以下问题,然后上机调试运行程序。

1.编写一程序,从键盘输入字符,判别输入字符是数字、大写字母还是小写字母,输出判别结果。

#include <stdio.h>

void main()

{

char c;

    printf("请输入一个字符!\n");

c=getchar();

    if (c>='a'&& c<='z')

    printf("你输入的是小写字母");

    else if (c>='A'&& c<='Z')

    printf("你输入的是大写字母");

    else if (c>='0'&& c<='9')

    printf("你输入的是数字");

    printf("\n");

}

运行效果图:

2.给出一个不多于5位的正整数,要求:

(1)求出它是几位数;

(2)分别打印出每一位数字;

(3)按逆序打印出各位数字。

#include <stdio.h>

#include <math.h>

void main()

{

       long int num;

       int a,b,c,d,e,m;

       printf("请输入一个整数(0~99999):");

       scanf("%d",&num);

       if(num>9999)

              m=5;

       else if(num>999)

              m=4;

       else if(num>99)

              m=3;

       else if(num>9)

              m=2;

       else

              m=1;

       printf("位数=%d\n",m);                  /*也可这样写,如下*/

       e=(int)(num/10000);                     /*e=num/10000%10;*/

       d=(int)(num-e*10000)/1000;              /*d=num/1000%10;*/

       c=(int)(num-e*10000-d*1000)/100;        /*c=num/100%10;*/

       b=(int)(num-e*10000-d*1000-c*100)/10;   /*b=num/10%10;*/

       a=(int)(num-e*10000-d*1000-c*100-b*10); /*a=num%10;*/

       printf("每位数字为:");

       switch(m)

       {

       case 5: printf("%d,%d,%d,%d,%d",e,d,c,b,a);

                     printf("\n反序数字为:");

                     printf("%d%d%d%d%d\n",a,b,c,d,e);

                     break;

       case 4: printf("%d,%d,%d,%d",d,c,b,a);

                     printf("\n反序数字为:");

                     printf("%d%d%d%d\n",a,b,c,d);

                     break;

       case 3: printf("%d,%d,%d",c,b,a);

                     printf("\n反序数字为:");

                     printf("%d%d%d\n",a,b,c);

                     break;

       case 2: printf("%d,%d",b,a);

                     printf("\n反序数字为:");

                     printf("%d%d\n",a,b);

                     break;

       case 1: printf("%d",a);

                     printf("\n反序数字为:");

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

                     break;

       }

}

3.有一函数,,用scanf函数输入任意x的值,求y的值。

#include <stdio.h>

main()

{

       int x,y;

       printf("请输入x的值\n");

       scanf("%d",&x);

       if(x<1)

              y=x*x;

       else if(x>=1&x<10)

              y=2*x-1;

       else if(x>10)

              y=3*x-1;

       printf("y的值为:,%d\n",y);

}

实验4     循环控制

一、             实验目的

1.熟悉用while语句,do-while语句和for语句实现循环的方法。

2.掌握在程序设计中用循环的方法实现各种算法(如穷举、迭代、递推等)。

二、             实验内容

编写程序并上机调试运行。

1.输入一行字符,分别统计出其中的英文字母、空格、数字和其它字符的个数。

#include<stdio.h>

main()

{

       char c;

       int w=0,x=0,y=0,z=0;

       while((c=getchar())!='\n')

       {if((c>='a'&& c<='z')||(c>='A' && c<='z'))

           w++;

    else if (c==' ')

           x++;

    else if (c>='0' && c<='9')

           y++;

    else

        z++;

   }

   printf("w=%d,x=%d,y=%d,z=%d\n",w,x,y,z);

}

2.输出九九表。

#include<stdio.h>

main()

{

       int i,j;

       for(i=1;i<10;i++) 

              printf("%4d",i);

              printf("\n------------------------------------\n");

       for(i=1;i<=9;i++)

              for(j=1;j<=9;j++)

              {   

                     if(j==9)

                            printf("%4d\n",i*j);

                     else

                            printf("%4d",i*j);

              }

              printf("\n");

}

 实验数组

一、             目的要求

1.掌握一维数组和二维数组的定义、赋值和输入输出的方法;

2.掌握字符数组和字符串函数的使用;

3.掌握与数组有关的算法(特别是排序算法)。

二、             实验内容

1.编写一程序,从键盘输入任意两个字符串,然后将两个字符串连接起来,不要使用strcat函数。

#include <stdio.h>

main ()

{

  char s1[80],s2[40];

  int i=0,j=0;

  printf("输入字符串1:");

  scanf("%s",s1);

  printf("输入字符串2:");

  scanf("%s",s2);

  while (s1[i]!='\0')

  i++;

  while (s2[j]!='\0')

  s1[i++]=s2[j++];

  s1[i]='\0';

  printf("The new string is:%s\n",s1);

}

2.编写一程序,从键盘输入任意两个字符串s1和s2,然后比较字符串的大小(字符串比较是从左到右逐位比较),如果s1>s2,输出1;s1=s2,输出0;s1<s2,输出-1。

#include<stdio.h>

main ( )

{      

  int i;

  char s1[100],s2[100];

  printf("输入字符串1:");

  gets (s1);

  printf("输入字符出2:");

  gets (s2);

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

  {

  if(s1[i]>s2[i])

         printf("1\n");

  else if(s1[i]==s2[i])

         printf("0\n");

  else

         printf("-1\n");

  break;

  }

}

3.   编写一程序,输入一字符串到数组中,然后将该数组中小写字母转换为大写字母,并复制到另一字符数组中。(复制时,‘\0’也要复制过去)

#include <stdio.h>

void main()

{

       int i;

       char s1[100],s2[100];

       printf("请输入一串字符:\n");

       scanf("%s",s1);

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

       {

       if(s1[i] >='a'&&s1[i]<='z')

       s2[i]=s1[i]-32;

       else

       s2[i]=s1[i];

       }

       printf("字符串转换为:\n%s\n",s2);

}

实验函数

一、             目的要求

1.掌握定义函数的方法;

2.掌握函数实参与形参的对应关系,以及“值传递”的方式;

3.掌握函数的嵌套调用和递归调用的方法;

4.掌握全局变量和局部变量、动态变量和静态变量的概念和使用方法。

二、             实验内容

1.输入一行字符串,然后写一函数输出该行字符串中最长的单词。例如I am a student中最长的单词为student。

#include<stdio.h>

#include<string.h>

void main()

{

  int i,j=0,len,m,a,b;

  char str[80];

  char c[100]={0};

  printf("输入一行字符:\n");

  gets(str);

  len=strlen(str);

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

         if(str[i]==' '||str[i]=='\0')

         {

                c[j]=i;

                j++;

         }

  for(m=1;m<=j;m++)

  {

         if((c[m]-c[m-1])>c[99])

         {

                c[99]=c[m]-c[m-1];

                a=c[m];

                b=c[m-1];

         }

         else c[99]=c[99];

  }

  for(i=b+1;i<=a-1;i++)

         printf("%c",str[i]);

  printf("\n");

}

2.写一个判断素数的函数,在主函数中输入一个整数,输出是否素数的信息。

#include<stdio.h>

#include<math.h>

void main()

{

    int m,i;

  printf("输入一个数:\n");

    scanf("%d",&m);

    for(i=2;i<=m-1;i++)

    {

        if(m%i==0)

            break;

    }

    if(m!=i)

        printf("%d不是素数",m);

    else

        printf("%d是素数",m);

}


实验7 指针

一、             实验目的:

1.掌握指针的概念,会定义和使用指针变量;

2.学会使用数组的指针和指向数组的指针变量;

3.学会使用字符串的指针和指向字符串的指针变量;

4.学会使用指向函数的指针变量;

5.了解指向指针的指针的概念及其使用方法。

二、             实验内容:

1.编制一函数实现任意3*3阶矩阵的转置,函数的参数用指针形式。在主函数中输入矩阵元素。

#include<stdio.h>

void main()

{

  void cm(int (*p1)[3],int (*p2)[3]);

  int a[3][3],b[3][3];

  int (*pa)[3],(*pb)[3],i,j;

         pa=a;pb=b;

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

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

                scanf("%d",*(pa+i)+j);

         printf("array a:\n");

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

  {

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

                printf("%5d",a[i][j]);

                printf("\n");

  }

  cm(pa,pb);

  printf("array b:\n");

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

  {

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

                printf("%5d",b[i][j]);

                printf("\n");

  }

}

void cm(int (*p1)[3],int (*p2)[3])

{

  int i,j;

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

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

                *(*(p2+i)+j)=*(*(p1+j)+i);

}

2.从键盘输入任意两个字符串s1和s2,然后用函数实现比较字符串的大小(字符串比较是从左到右逐位比较),如果s1>s2,函数返回1;s1=s2,函数返回0;s1<s2,函数返回 -1。函数的参数采用指针形式。

#include<stdio.h>

void main()

{

  char s1[30],s2[30];

  int i,j;

  char *p,*q;

  p=s1;q=s2;

  printf("请输入字符串s1:\n");

  gets(s1);

  printf("请输入字符串s2:\n");

  gets(s2);

  while(*p!='\0'&&*q!='\0'&&*p==*q)

  {

         p++;

         q++;

  }

  if(*p>*q)

         printf("1\n");

  else if(*p==*q)

         printf("0\n");

  else

         printf("-1\n");

}


实验结构体

一、             目的要求:

1.掌握结构体类型变量的定义和使用;

2.掌握结构体类型数组的概念和应用;

3.掌握链表的概念,初步学会对链表进行操作;

二、             实验内容:

1.有5个学生,每个学生的数据包括学号、姓名、三门课的成绩,从键盘输入5个学生的数据,要求打印出三门课总平均成绩,以及最高分的学生的数据(包括姓名、学号、三门课的成绩、平均分数)。要求用一个input函数输入成绩;用average函数求总平均分;用max函数找出最高分学生数据;总平均分和最高分的学生的数据在主函数中输出。

#include<stdio.h>

#define N 5

struct student

{ char num[6];

  char name[8];

  float score[3];

  float avr;

} stu[N];

void main()

{ int i,j,maxi;

  float sum,max,average;

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

  {printf("input score of student %d:\n",i+1);

   printf("No.:");

   scanf("%s",stu[i].num);

   printf("name:");

   scanf("%s",stu[i].name);

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

         {printf("score %d:",j+1);

          scanf("%f",&stu[i].score[j]);

         }

  }

  average=0;

  max=0;

  maxi=0;

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

  {sum=0;

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

         sum+=stu[i].score[j];     

   stu[i].avr=sum/3.0;                   

   average+=stu[i].avr;

   if(sum<max)                     

         {max=sum;maxi=i;}

  }

  average/=N;

  printf(" No.      name    scorel    score2    score3    average\n");

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

  {printf("%5s%10s",stu[i].num,stu[i].name);

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

          printf("%9.2f",stu[i].score[j] );

   printf("    %8.2f\n",stu[i].avr );

  }

  printf("average=%5.2f\n",average);

  printf("The highest score is:student %s,%s.\n",stu[maxi].num,stu[maxi].name  );

  printf("His scores are: %6.2f,%6.2f,%6.2f,average:%5.2f.\n",stu[maxi].score[0],

         stu[maxi].score[1],stu[maxi].score[2],stu[maxi].avr);

}

2.建立一个链表,每个结点包括:学号、姓名、性别、年龄。输入一个年龄,如果链表中的结点所包含的年龄等于此年龄,则将此结点删除。

#include<stdio.h>

#include<malloc.h>

#define LEN sizeof(struct student)

struct student

{

  char num[6];

  char name[8];

  char sex[2];

  int age;

  struct student *next;

} stu[10];

void main()

{

  struct student *p,*pt,*head;

  int i,length,iage,flag=1;

  int find=0;

  while(flag==1)

  {

         printf("input length of list(<10):");

         scanf("%d",&length);

         if(length<10)

                flag=0;

  }

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

  {

         p=(struct student *)malloc(LEN);

         if(i==0)

                head=pt=p;

         else

                pt->next=p;

         pt=p;

         printf("No.:");

         scanf("%s",p->num);

         printf("name:");

         scanf("%s",p->name);

         printf("sex:");

         scanf("%s",p->sex);

         printf("age:");

         scanf("%d",&p->age);

  }

  p->next=NULL;

  p=head;

  printf("\n No.    name     sex   age\n");

  while(p!=NULL)

  {

         printf("%4s%8s%6s%6d\n",p->num,p->name,p->sex,p->age);

         p=p->next;

  }

  printf("input age:");

  scanf("%d",&iage);

  pt=head;

  p=pt;

  if(pt->age==iage)

  {

         p=pt->next;

         head=pt=p;

         find=1;

  }

  else

         pt=pt->next;

  while(pt!=NULL)

  {

         if(pt->age==iage)

         {p->next=pt->next;

          find=1;

         }

         else

                p=pt;

         pt=pt->next;

  }

  if(!find)

         printf(" not found  %d.",iage);

  p=head;

  printf("\n No.    name    sex   age\n");

  while(p!=NULL)

  {

         printf("%4s%8s",p->num,p->name);

         printf("%6s%6d\n",p->sex,p->age);

         p=p->next;

  }

}

下篇 数据机构

实验一  线性表的顺序表示和实现

一、     实验目的

1、理解线性表的逻辑结构特性;

2、熟练掌握线性表的顺序存储结构的描述方法,以及在该存储结构下的基本操作。

二、     实验内容

实验1.1  用线性表的顺序存储结构实现十项基本操作:初始化、求长度、取元素、求前导、求后继、查找、插入、删除、判定空表、置空,生成sqlist.h文件;编写main函数调用。

【提示】sqlist.h文件的代码实现线性表的顺序存储结构的基本操作;另建一个顺序表.cpp文件实现main函数,以用户交互的方式调用顺序表的各个功能。

(1)   操作步骤:

对于这个实验是用线性表的顺序存储结构实现的十项基本操作,程序量比较大,需要按提示中的通过用户交互方式调用顺序表的各功能。

(2)   程序代码:

MysqList.cpp文件中的代码:

#include <iostream.h>

#include "MysqList.h"

void main()

{    sqlist L;

        int x,i,e,aa=1,bb;

     cout<<"  1.用户生成线性表."<<endl;

     cout<<"  2.自动生成线性表."<<endl;

     cout<<"  3.插入元素."<<endl;

     cout<<"  4.删除元素."<<endl;

     cout<<"  5.删除多余的元素."<<endl;    

     cout<<"  6.打印线性表."<<endl;

     cout<<"  7.打印线性表长度."<<endl;

        cout<<"  8.查找元素e的位置."<<endl;

        cout<<"  9.查找第i个元素的值."<<endl;

     cout<<"  10.置空线性表."<<endl;

     cout<<"  11.判断表是否为空."<<endl;

        cout<<"  12.退出."<<endl<<endl;

  while(aa)

    {cout<<endl<<endl;

     cout<<"请选择一项操作的编号!(1/2/3/4/5/6/7/8/9/10/11/12):";

     cin>>x;

     switch(x)

        {case 1:creat_Sqlist(L);break;

         case 2:cout<<"1 2 3 4 5 6 7"<<endl;break;

         case 3:cout<<"请输入插入的元素值! e=";

                 cin>>e;

                cout<<"请输入插入位置! i=";

                 cin>>i;

                 bb=Listinsert_Sq(L,i,e);

                             if(bb==ERROR)cout<<"不合理的插入位置";

                             if(bb==OVERFLOW)cout<<"表已满,溢出";break;

         case 4:cout<<"请输入删除元素的位置! i=";

                        cin>>i;

                        Listdelete_Sq(L,i);break;

         case 5:Deletesame(L);break;

         case 6:prt_sqlist(L);break;

      case 7:cout<<"线性表长度="<<ListLength(L);break;

        case 8:cout<<"请输入查找的元素值! e=";

             cin>>e; bb=LocateElem(L,e);

                      if (bb==0) cout<<"元素"<<e<<"未找到。";

                      else cout<<"元素e="<<e<<"的位置是"<<LocateElem(L,e);;break;

      case 9:cout<<"请输入查找元素的位置! i=";

             cin>>i;

                if(GetElem(L,i)) cout<<"第"<<i<<"元素的值是="<<GetElem(L,i);

                      else cout<<"输入的位置不对"<<endl; break;

         case 10: ClearList(L);break;

         case 11: ListEmpty(L);break;

         case 12: aa=0;

         }

       }

  }

MysqList.h文件中的代码:

//线性表的操作实现(顺序存储结构)

//编号从1开始,编号为0的元素放弃不用

#include <iostream.h>

const  OK=1;

const  ERROR=0;

const  TRUE=1;

const  FALSE=0;

const  OVERFLOW=-2;

const  UNDERFLOW=-1;

const  MAXSIZE=20;

//结构定义

typedef  struct {

   int *elem;  //存储空间基址,即用指针表示数组的方法

   int len;  //线性表的当前表长

}sqlist;

//初始化

void creat_Sqlist(sqlist &L)

   {int i=1,x;

       L.elem=new int[MAXSIZE];

       cout<<"请输入线性表的元素,输入0结束! "<<endl;

       do

              {cin>>x;L.elem[i]=x; i++;}

       while(x!=0);

        L.len=i-2;// L.elem[i]=0后i又加1,所以i-2

   }

//求长度

int ListLength(sqlist L)

{

  return L.len;

}

//获取线性表第I个元素(1<=i<=L.len)

int GetElem(sqlist L,int i)

{if (i<1||i>L.len) return ERROR;

return L.elem[i];}

//查找元素e的位置

int LocateElem(sqlist L, int e)

{ int i;

L.elem[0]=e; //设哨兵

for(i=L.len;L.elem[i]!=e;--i){}

  return i;

    }

//插入算法:在线性表的第i-1和第i元素之间插入一个新元素e

int Listinsert_Sq(sqlist &L ,int i, int e)

 {int j;

if(i<1 || i>L.len+1)  return ERROR;   //不合理的插入位置 i

  if ( L.len==MAXSIZE) return OVERFLOW;   // 表已满

for (j=L.len;j>=i;--j)

L.elem[j+1]=L.elem[j];   // 插入位置后的元素右移

L.elem[i]=e;      //插入e

++L.len;          //表长加1

return OK;

     }

//删除算法:删除线性表中第个i元素。

int Listdelete_Sq(sqlist &L,int i)

 { int j;

   if (i<1 || i>L.len)  return  ERROR;  //不合理的删除位置 i

   if (L.len==0)  return  UNDERFLOW;    //表已空

   for (j=i;j<=L.len-1;j++)       

      L.elem[j]=L.elem[j+1];     //被删除元素之后的元素左移

    --L.len;   //表长减1

  return OK;

   }

//删除非递减线性表中多余的相同元素

int Deletesame(sqlist &L)

{int i;

 if (L.len<=1) return ERROR;

  i=1;

  while ( i<L.len)

       if (L.elem[i]==L.elem[i+1])  Listdelete_Sq (L,i+1);

    else  i++;}

//打印

void  prt_sqlist(sqlist L)

   { int i;

        for(i=1;i<=L.len;i++)

           cout<<L.elem[i]<<"   ";

     cout<<endl;

   }

//置空

void ClearList(sqlist &L)

{L.len=0;}

//判断是否为空

bool ListEmpty(sqlist &L)

{ return(L.len==0); }

实验1.2  用一维数组做存储结构,就地逆置一线性表,即将结点的前趋与后继关系颠倒。如:(a1,a2,...an)逆置后为(an,an-1,...,a1)。***

(1)   操作步骤:

此实验需要用到三个循环:第一个循环式输入数组数据,第二个循环实现数组中数据的逆序,第三个循环将逆序后新数组中的数据输出。

(2)   程序代码:

#include "iostream.h"

void main()

{

       int *p;

       int m,j,i;

       cout<<"数组元素个数"<<endl;

       cin>>m;

       p=new int[m];

       cout<<"输入数组元素"<<endl;

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

       {

              cin>>p[i];

       }

       for(i=0;i<m/2;i++)

       {

        j=p[i];p[i]=p[m-i-1];p[m-i-1]=j;

       }

       cout<<"逆置后的结果"<<endl;

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

       {

       cout<<p[i]<<"  ";

       }

       cout<<endl;

}

实验二  线性表的链式表示和实现

一、实验目的

1.   理解线性表的逻辑结构特性;

2.   熟练掌握线性表的链表存储结构的描述方法,以及在该存储结构下的基本操作;并能灵活运用;

二、实验内容

实验2.1  用线性表的链式存储结构实现十项基本操作:初始化(要求终端输入数据建立链表,可用正序或逆序中的一种生成)、求长度、取元素、求前导、求后继、查找、插入、删除、判定空表、置空,生成Llist.h文件;编写main函数调用。

【提示】Llist.h文件的代码实现线性表的链式存储结构的基本操作;另建一个链表.cpp文件实现main函数,以用户交互的方式调用顺序表的各个功能。

(1)   操作步骤:

此实验题和实验一中的题目差不多,需要理解顺序存储与链式存储的不同之处。

(2)   程序代码:

MysqList.cpp文件中的代码:

#include "MyLinkList.h"

void main()

{LinkList L=NULL,s,La=NULL,Lb=NULL;

 int x,i,y,aa=1,n;

  while(aa)

    {cout<<endl;

     cout<<"  1.逆序生成有序链表"<<endl;

        cout<<"  2.在单链表中的第i个结点前插入一个元素x"<<endl;

     cout<<"  3.在单链表中值为x的结点前插入一个元素y,如果x值不存在,则把y插在表尾"<<endl;

        cout<<"  4.删除单链表中第i个元素"<<endl;

     cout<<"  5.删除单链表中值为x的结点"<<endl;

     cout<<"  6.打印线性表"<<endl;

     cout<<"  7.查找元素X的位置"<<endl;

        cout<<"  8.查找第i个元素的值"<<endl;

        cout<<"  9.逆置单链表"<<endl;

     cout<<"  10.合并两个有序表"<<endl;

        cout<<"  11.退出。"<<endl;

     cout<<"请选择一项操作的编号!(1/2/3/4/5/6/7/8/9/10/11):";

     cin>>x;

     switch(x)

        {case 1:cout<<"输入链表长度n=";

                cin>>n;

                      CreateList_L(L,n);break;

         case 2:cout<<"请输入插入的元素值! x="; cin>>x;

                cout<<"请输入插入位置! i="; cin>>i;

                      if (i<1||i>ListLength_L(L)) cout<<"输入的位置i不正确。"<<endl;

                   s=new LNode;s->data=x;s->next=NULL;         

                      ListInsert_L(L,i,s);break;

         case 3:cout<<"请输入 x=";

                 cin>>x;

                cout<<"请输入插入的元素值! y=";

                 cin>>y;

                 Linklist_ins(L,x,y);break;

         case 4:cout<<"请输入删除元素的位置! i=";

                        cin>>i;

                        if(i<1||i>ListLength_L(L)) cout<<"输入的位置i不正确。"<<endl;

                        else    cout<<"删除第"<<i<<"个元素为"<<ListDelete_L(L,i)<<endl;break;

         case 5:cout<<"请输入删除元素的值!X=";

                        cin>>x;

                        if(Linklist_del2(L,x)) cout<<"删除成功"<<endl;

                        else cout<<"链表中没有元素"<<x<<"删除失败"<<endl; break;

         case 6:prt_Linklist(L);cout<<"    线性表长度="<<ListLength_L(L)<<endl;break;

      case 7:cout<<"请输入查找的元素值! x=";cin>>x;

                   LocateElem(L,x);break;

        case 8:cout<<"请输入查找元素的位置! i=";

             cin>>i;

                if(Getelem(L,i)) cout<<"第"<<i<<"元素的值是="<<Getelem(L,i)<<endl;

                      else cout<<"输入的位置不对"<<endl; break;

      case 9:InvertLinkedList(L);

                   cout<<"逆置后的单链表: ";prt_Linklist(L);break;

      case 10:cout<<"建立第一个有序表,输入链表长度:";

                cin>>n;              

                      CreateList_L(La,n);

                  cout<<"建立第二个有序表,输入链表长度:";

                cin>>n;

                      CreateList_L(Lb,n);

                   MergeList_L(La,Lb,L);

                      cout<<"合并后的有序表:";prt_Linklist(L);break;

         case 11: aa=0;

         }

       }

  }

MyLinkList.h中的代码:

#include "MyLinkList.h"

void main()

{LinkList L=NULL,s,La=NULL,Lb=NULL;

 int x,i,y,aa=1,n;

     cout<<"  1.逆序生成有序链表"<<endl;

        cout<<"  2.在单链表中的第i个结点前插入一个元素x"<<endl;

     cout<<"  3.在单链表中值为x的结点前插入一个元素y,如果x值不存在,则把y插在表尾"<<endl;

        cout<<"  4.删除单链表中第i个元素"<<endl;

     cout<<"  5.删除单链表中值为x的结点"<<endl;

     cout<<"  6.打印线性表"<<endl;

     cout<<"  7.查找元素X的位置"<<endl;

        cout<<"  8.查找第i个元素的值"<<endl;

        cout<<"  9.逆置单链表"<<endl;

     cout<<"  10.合并两个有序表"<<endl;

        cout<<"  11.退出。"<<endl;

  while(aa)

   {

     cout<<"请选择一项操作的编号!(1/2/3/4/5/6/7/8/9/10/11):";

     cin>>x;

     switch(x)

        {case 1:cout<<"输入链表长度n=";

                cin>>n;

                      CreateList_L(L,n);break;

         case 2:cout<<"请输入插入的元素值! x="; cin>>x;

                cout<<"请输入插入位置! i="; cin>>i;

                      if (i<1||i>ListLength_L(L)) cout<<"输入的位置i不正确。"<<endl;

                   s=new LNode;s->data=x;s->next=NULL;         

                      ListInsert_L(L,i,s);break;

         case 3:cout<<"请输入 x=";

                 cin>>x;

                cout<<"请输入插入的元素值! y=";

                 cin>>y;

                 Linklist_ins(L,x,y);break;

         case 4:cout<<"请输入删除元素的位置! i=";

                        cin>>i;

                        if(i<1||i>ListLength_L(L)) cout<<"输入的位置i不正确。"<<endl;

                        else    cout<<"删除第"<<i<<"个元素为"<<ListDelete_L(L,i)<<endl;break;

         case 5:cout<<"请输入删除元素的值!X=";

                        cin>>x;

                        if(Linklist_del2(L,x)) cout<<"删除成功"<<endl;

                        else cout<<"链表中没有元素"<<x<<"删除失败"<<endl; break;

         case 6:prt_Linklist(L);cout<<"    线性表长度="<<ListLength_L(L)<<endl;break;

      case 7:cout<<"请输入查找的元素值! x=";cin>>x;

                   LocateElem(L,x);break;

        case 8:cout<<"请输入查找元素的位置! i=";

             cin>>i;

                if(Getelem(L,i)) cout<<"第"<<i<<"元素的值是="<<Getelem(L,i)<<endl;

                      else cout<<"输入的位置不对"<<endl; break;

      case 9:InvertLinkedList(L);

                   cout<<"逆置后的单链表: ";prt_Linklist(L);break;

      case 10:cout<<"建立第一个有序表,输入链表长度:";

                cin>>n;              

                      CreateList_L(La,n);

                  cout<<"建立第二个有序表,输入链表长度:";

                cin>>n;

                      CreateList_L(Lb,n);

                   MergeList_L(La,Lb,L);

                      cout<<"合并后的有序表:";prt_Linklist(L);break;

         case 11: aa=0;

         }

       }

  }

实验2.2  单链表中的元素以递增序存放,编程删除表中所有值大于mink且小于maxk的元素。

(1)   操作步骤:

分为三个步骤:创建链表,并按递增顺序输入;输出链表的数据;删除介于两个数据之间的元素。

(2)   程序代码;

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

typedef int ElemType;

typedef  struct LNode

   { ElemType data;                      /* 数据子域      */

     struct LNode *next;                 /* 指针子域      */

   }LNode;                               /* 结点结构类型  */

LNode *L;

/*  函数声明  */

LNode *creat_L();

void delete_L(LNode *L,int i);  //返回值格式变为空

/*  建立线性链表*/

LNode *creat_L()

{

    LNode *h,*p,*s;  ElemType x;

    h=(LNode *)malloc(sizeof(LNode));                 /* 分配头结点 */

    h->next=NULL;

    p=h;

    printf("输入一串数字(以-1结束):\ndata= ");

    scanf("%d",&x);                                   /*  输入第一个数据元素 */

    while( x!=-1)                                     /*  输入-1,结束循环 */

    {

        s=(LNode *)malloc(sizeof(LNode));             /*  分配新结点 */

        s->data=x;  s->next=NULL;

        p->next=s;  p=s;

        printf("data= ");

        scanf("%d",&x);                               /* 输入下一个数据*/

    }

    return(h);

} /* creat_L  */

/* 输出单链表中的数据元素*/

void out_L(LNode *L)

{

    LNode *p;

    p=L->next;

    printf("\n数据是:");

    while(p!=NULL)

    {

        printf("%5d",p->data);

        p=p->next;

    }

} /* out_link */

/* 删除大于x小于y的值*/

void delete_L(LNode *L,int a,int b)

{

    LNode *p,*q;

    p=L;

    q=p;

    p=p->next;

    if(p==NULL) printf("ERROR:链表为空");

    while(p!=NULL)

    {

   

        if((p->data >a) && (p->data <b))

        {  q->next=p->next;

           free(p);

            p=q->next;

        }

        else

        {  q=p;

            p=p->next;

        }

    }

  }  /* delete_L */

void main()

{

    int a,b;

    L=creat_L( );  out_L(L);

    printf("\n\n请输入你要删除的元素的范围x和y:\n");

    scanf("%d%d",&a,&b);

    delete_L(L,a,b);  out_L(L);

    printf("\n");

} /* main */

实验三  内部排序算法设计

一、实验目的

1、熟练掌握各种内排序方法,深刻理解排序算法及执行过程;

2、学会分析各种内排序算法的性能;

3、了解各种排序方法的优缺点,对于实际问题能够选择一种好的排序方案。

二、实验内容

实验3.1 实现下述算法,并用以下无序序列加以验证:

49,38,65,97,76,13,27,49

(1)、直接插入排序、折半插入排序、冒泡排序

(2)、简单选择排序

(3)、快速排序

(1)  操作步骤:

此实验是对各种排序方法的实验过程,对给定数据采用不同的方法进行排序操作,每种排序方法需要用一个函数来完成。

(2)  程序代码:

#include <iostream.h>

const MAXSIZE=20;

#define LT(a,b) ((a)<(b))

#define GT(a,b) ((a)>(b))

typedef int KeyType;

typedef int InfoType;

typedef struct{

  KeyType key;

  InfoType otherinfo;

}RedType;

typedef struct{

  RedType r[MAXSIZE+1];   //r[0]闲置做哨兵

  int length;

}SqList;

//直接插入排序

void InsertSort(SqList &L)

{ int i,j;

  for(i=2;i<=L.length;++i)

    if(LT(L.r[i].key,L.r[i-1].key)){

      L.r[0]=L.r[i];

      for(j=i-1; LT(L.r[0].key,L.r[j].key); --j)

        L.r[j+1]=L.r[j];

      L.r[j+1]=L.r[0]; }

}

//折半插入排序

void BInsertSort(SqList &L)

{ int i,j,low,high,m;

  for(i=2;i<=L.length;++i){

    L.r[0]=L.r[i];

    low=1;high=i-1;

    while(low<=high){

      m=(low+high)/2;

      if (LT(L.r[0].key,L.r[m].key)) high=m-1;

      else low=m+1;

    }

    for(j=i-1;j>=high+1;--j) L.r[j+1]=L.r[j];

    L.r[high+1]=L.r[0];

  }

}

//希尔排序

void ShellInsert(SqList &L, int dk)

{/* 对顺序表L作一趟希尔排序。 前后记录位置的增量是dk

 r[0]只是暂存单元,不作哨兵用。当j≤0时,插入位置已找到*/

  for (int i=dk+1;i<=L.length;++i)

    if LT(L.r[i].key,L.r[i-dk].key)

      {

        L.r[0]=L.r[i];

        for (int j=i-dk;j>0 && LT(L.r[0].key,L.r[j].key);j-=dk)

          L.r[j+dk]=L.r[j];  /*记录后移,查找插入位置*/

        L.r[j+dk]=L.r[0];

      }

}

/*按增量序列dlta[0…t-1]对顺序表L作希尔排序*/

void ShellSort(SqList &L, int dlta[], int t)

  for (int k=0;k<t;++k)

    ShellInsert(L,dlta[k]);  /*一趟增量为dlta[k]的插入排序*/

}

//QuickSort

int Partition(SqList &L,int low,int high)

{

  int pivotkey;

  L.r[0]=L.r[low];

  pivotkey=L.r[low].key;

  while(low<high){

    while(low<high&&L.r[high].key>=pivotkey) --high;

    L.r[low]=L.r[high];

    while(low<high&&L.r[low].key<=pivotkey) ++low;

    L.r[high]=L.r[low];

  }

  L.r[low]=L.r[0];

  return low;

}

void QSort(SqList &L,int low,int high)

{

  int pivotloc;

  if(low<high){

    pivotloc=Partition(L,low,high);

    QSort(L,low,pivotloc-1);

    QSort(L,pivotloc+1,high);

  }

}

void QuickSort(SqList &L)

{

  QSort(L,1,L.length);

}

/* End QuickSort related function*/

//SelectSort

int SelectMinKey(SqList &L,int i)

{ int k;

  int j;

  k=i;

  for(j=i;j<L.length+1;j++)

    if(L.r[k].key>L.r[j].key)

      k=j;

  return k;

}

void SelectSort(SqList &L)

{

  RedType t;

  int i,j;

  for(i=1;i<L.length;++i){

    j=SelectMinKey(L,i);

    if(i!=j) {

      t=L.r[i];

      L.r[i]=L.r[j];

      L.r[j]=t;

    }

  }

}/*End SelectSort related function */

//堆排序

typedef SqList HeapType;

void HeapAdjust(HeapType &H,int s,int m)

{

  RedType rc;

  int j;

  rc=H.r[s];

  for(j=2*s;j<=m;j*=2){

    if(j<m && LT(H.r[j].key,H.r[j+1].key)) ++j;

    if(!LT(rc.key,H.r[j].key)) break;

    H.r[s]=H.r[j];

    s=j;

  }

  H.r[s]=rc;

}

void HeapSort(HeapType &H)

{

  RedType t;

  int i;

  for(i=H.length/2;i>0;--i)

    HeapAdjust(H,i,H.length);

  for(i=H.length;i>1;--i){

    t=H.r[1];

    H.r[1]=H.r[i];

    H.r[i]=t;

    HeapAdjust(H,1,i-1);

  }

}

//打印

void  prt_sqlist(SqList L)

   { int i;

        for(i=1;i<=L.length;i++)

           cout<<L.r[i].key<<"   ";

     cout<<endl;

   }

void main()

{

  int a[]={49,38,65,97,76,13,27,49};

  int dlta[]={5,3,1};   //希尔排序增量

   int i,k=1,t=3;

  SqList s;

  for(i=1;i<9;i++) s.r[i].key=a[i-1];  //生成顺序表

  s.length=i-1;

  cout<<"待排序列为:";      prt_sqlist(s);

  cout<<endl<<"1,插入排序"<<endl<<"2,折半排序"<<endl<<"3,希尔排序"<<endl<<"4,快速排序"<<endl<<"5,选择排序"<<endl<<"6,堆排序"<<endl;

  while(k)  {

       cout<<"按键1..6,选择一种排序方法,按0退出    ";

       cin>>k;

       switch(k){

              case 1:

                     InsertSort(s);break;

              case 2:

                     BInsertSort(s);break;

              case 3:

                     ShellSort(s,dlta,t);break;

              case 4:

                      QuickSort(s);break;

              case 5:

                     SelectSort(s);break;

              case 6:

                     HeapSort(s);break;

      }

       cout<<"排序的结果:"<<endl;prt_sqlist(s);

}}

实验四  栈、队列算法设计

一、实验目的

1、熟悉栈这种特殊线性结构的特性;

2、熟练掌握栈在顺序存储结构和链表存储结构下的基本运算;

3、熟悉队列这种特殊线性结构的特性;

4、熟练掌握队列在链表存储结构下的基本运算。

二、             实验内容

实验4.1  用顺序和链式存储结构分别实现栈的初始化、求长度、获取栈顶元素、压栈、出栈、判空、置空等操作,生成sqStack.h文件和LinkStack.h文件;编写main函数调用。

(1)   用顺序存储结构实现基本操作。

(2)   程序代码:

sqstack..cpp文件中的代码

#include <iostream.h>

#include "sqstack.h"

void main()

{

  int x; sqstack Sa;

  cout<<"-----------------栈的演示程序----------------"<<endl;

  cout<<"首先初始化栈,此时栈为空"<<endl;

  InitStack(Sa);

  cout<<"输入入栈序列,压栈,输0结束。"<<endl;

  cin>>x;

  while(x!=0)

  {    Push(Sa,x);cin>>x;}

  cout<<"现在栈有"<<StackLength(Sa)<<"个元素"<<endl;

  cout<<"现在出栈,把元素保存到变量中"<<endl;

  Pop(Sa,x);cout<<"出栈的元素为"<<x<<endl;

  cout<<"让我们看看还剩哪个元素"<<endl;

  while(!StackEmpty(Sa))

              {Pop(Sa,x);cout<<x<<endl;  }

}

sqstack.h文件中的程序代码:

const ERROR=0;

const TRUE= 1;

const FALSE= 0;

const OK= 1;

const STACK_INIT_SIZE= 10;

const STACKINCREMENT= 1;

const OVERFLOW= 0;

typedef int SElemType;

typedef struct

{ SElemType *elem;

  int top;

  int stacksize;

}sqstack;

//构造一个一定大小的空栈

void InitStack(sqstack &S)

{

       S.elem=new SElemType[STACK_INIT_SIZE]; 

    S.top=-1;

    S.stacksize=STACK_INIT_SIZE;  

}

//销毁栈

void DestroyStack(sqstack &S)

{delete []S.elem; }

//置为空栈

void ClearStack(sqstack &S)

{S.top=-1;}

//判空

bool StackEmpty(sqstack &S)

{ if(S.top==-1) return TRUE;

  else  return FALSE;

}

//栈的长度

int StackLength(sqstack S)

       {return S.top+1;}

//获取栈顶元素

int GetTop(sqstack &S,SElemType &e)

{ if(S.top==-1) return ERROR;

  e=S.elem[S.top]; return OK;}

//压栈

int Push(sqstack &S,SElemType e)

{ if(S.top==S.stacksize)return OVERFLOW;

  S.elem[++S.top]=e;

  return OK;

}

//出栈

int Pop(sqstack &S,SElemType &e)

{ if(S.top==-1) return ERROR;

   e=S.elem[S.top--];  return OK;}

(3)   用链式存储结构实现基本操作。

(4)   程序代码:

MyLinkList.cpp中的文件代码:

//栈的链式存储表示

#include <iostream.h>

#include "MyLinkList.h"

const       STACK_INIT_SIZE=10;       //存储空间初始分配量

const       STACKINCREMENT=2;      //存储空间分配增量

//结点类型, 结点指针类型

typedef    LinkList LinkStack;      

//----栈的基本操作---------

//初始化,设S为空栈

void InitStack(LinkStack &s)

{s=NULL;}

void Push_L(LinkStack &s,int e ){

       LinkStack p;

       p=new LNode;

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

       }

bool Pop_L(LinkStack &s, int &e){

       LinkStack p;

       if(s)

       {     p =s;s= s->next;

              e=p->data;

              delete p;

              return TRUE;

       } else return FALSE;

}

void main()

{

  int x; LinkStack Sa;

  cout<<"-----------------链栈的演示程序----------------"<<endl;

  cout<<"首先初始化栈,此时栈为空"<<endl;

  InitStack(Sa);

  cout<<"输入入栈序列,压栈,输0结束。"<<endl;

  cin>>x;

  while(x!=0)

  {    Push_L(Sa,x);cin>>x;}

  cout<<"现在栈有"<<ListLength_L(Sa)<<"个元素"<<endl;

  cout<<"现在出栈,把元素保存到变量中"<<endl;

  while(Sa)

       {Pop_L(Sa,x);cout<<"出栈的元素为"<<x<<endl;}

  if(!Sa) cout<<"现在栈为空"<<endl;}

MyLinkList.h中的文件代码:

//创建不带表头结点的单链表

#include<iostream.h>

const OK=1;

const ERROR=0;

const TRUE=1;

const FALSE=0;

//带表头结点的单链表的结构定义:

typedef  struct LNode{

    int  data;

    struct LNode  *next;

}LNode,*LinkList;

// 建立单链表,逆序

void CreateList_L(LinkList &L, int n)

{     LNode *p;

    L= NULL; //生成头指针

       int i;

       cout<<"输入"<<n<<"个链表元素:"<<endl;

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

       { p=new LNode;

      cin>>p->data;  //逆序输入an,an-1 ….  a1

       p->next=L; L=p;}

}

//判断是否为空

bool empty_list(LinkList L)

{ return (L==NULL)?TRUE:FALSE;

}

//获取单链表长度

int ListLength_L(LinkList L)

{ //L为链表的头指针,本函数返回 L 所指链表的长度

LinkList p;

int k=0;

p=L;

while (p) { k++; p=p->next; } //k计非空结点数

return k; } // ListLength_L

//取单链表中的第i (i>0)个结点)

int  Getelem(LinkList L, int i)

   { LinkList p;; int j=1;

     p=L;

     while( p && j<i)

      { p=p->next;++j; }

     if(!p||j>i) return ERROR;

     else return p->data; }

//在链表查找某元素,返回位置

void LocateElem(LinkList L,int x)

       { int j;LNode *p;  //P为扫描指针,j为计数器

        if(empty_list(L)) cout<<"空表。"<<endl;

        else {

          p=L;j=1;

          while((p->data!=x) && p){j++; p=p->next;}

       if(p->data==x)cout<<"元素"<<x<<"是第"<<j<<"个元素"<<endl;

       else cout<<"没找到元素"<<x<<endl;

        }

}

//在单链表L中的第i (i>0)个结点前插入一个元素x

int ListInsert_L(LinkList &L,int i,LNode *s){

       if (i==1) {s->next=L;L=s;return OK;}

       else{

              LNode *p;int j;

              p=L;j=1;

              while(p&&j<i-1){p=p->next;++j;}

           if(!p||j>i-1) return ERROR;

              else{s->next=p->next;p->next=s;return OK;}

       }

}//ListInsert_L

//在单链表中值为x的结点前插入一个元素y,如果x值不存在,则把y插在表尾。

 void Linklist_ins(LinkList &L, int x, int y)

   { LNode *p,*q,*s;

     s=new LNode; s->data=y;s->next=NULL;

     p=L;

     while ( p && p->data!=x )  { q=p; p=p->next;}

        if(p==L){s->next=L;L=s;}

     else{s->next=p; q->next=s;}

  }

//删除单链表L中的第i (i>0)个元素。

int ListDelete_L(LinkList &L,int i)

       {LNode *p,*q;

        int j;

       if (i==1) {q=L;L=L->next;}

       else{

              p=L;  j=1 ;

              while (p ->next && j<i-1)  //指针P定位到ai的前驱结点

               { p=p->next;   ++j;}

              q=p->next;   p->next=q->next; }   //修改指针

           return q->data; delete q;       //释放结点空间

//删除单链表L中的值为x的结点

int Linklist_del2(LinkList &L, int x)

  { LNode *p,*q;

    p=L;

    while ( p && p->data!=x )   { q=p; p=p->next;}

    if (!p)  return ERROR;

    if(p==L)L=L->next;

       else q->next=p->next;

       delete p;return OK;

  }

//输出单链表

void prt_Linklist(LinkList L)

 { LNode *p;

   p=L;

   while (p) {cout<<p->data<<"   "; p=p->next;    }

 }

void InvertLinkedList( LinkList &L) {

   LNode *p,*s;

   p = L; L = NULL; // 设逆置后的链表的初态为空

   while ( p ) {         // p 为遍历指针,指向待逆置链表的头

       s = p; p = p->next; //删除 p 所指链表的第一个结点(s 结点)

       s->next = L; L = s; // 将 s 结点插入到逆置表的表头

       }

  } // InvertLinkedList

//合并有序表

void MergeList_L(LinkList &La,LinkList &Lb, LinkList &Lc)

{     //pa、pb、 pc分别是La、Lb、Lc的遍历指针

    LNode *pa,*pb,*pc;//三个链表的遍历指针

       pa = La; pb= Lb;

       //确定合并后链表的头

    if (pa->data <= pb->data ) {Lc=pc=La;pa=pa->next;}

    else  {Lc=pc=Lb; pb=pb->next;}

       while (pa && pb) //当La、Lb未结束时

        { if (pa->data <= pb->data )

                 {pc->next = pa; pc = pa; pa = pa->next;}

             else { pc->next = pb; pc = pb; pb = pb->next;}

                }

     pc->next = pa?pa:pb;

   }

实验4.2  编写一个判断表达式中括号是否匹配的程序。

(1)   操作步骤

(2)   程序代码:

/*栈实现判断表达式中括号是否配对的算法,包括(),[],{}三类括号并可以任意嵌套使用*/

#include "sqstack_char.h"

#include <iostream.h>

#include <string.h>

int  IsOk(sqstack &S,char pExp[])

{ int i;

  char c;

  int nLen = strlen(pExp);

  bool bResult=TRUE;

  for (i=0;i<nLen && bResult;i++)

       {//左括号入栈

     if (pExp[i]=='{' || pExp[i] == '[' || pExp[i] == '(') Push(S,pExp[i]);

     //右括号判断,可能出栈或出错

        if (pExp[i] == '}')

              {if (!Pop(S,c) || c!='{') bResult = FALSE;}//出错

     if (pExp[i] == ']')

              {if (!Pop(S,c) || c != '[') bResult = FALSE;}//出错

     if (pExp[i] == ')')

              {if (!Pop(S,c) || c != '(') bResult = FALSE;}//出错

    }

  return bResult && StackEmpty(S);

}

void main()

{ sqstack Sa;

  cout<<"-----判断表达式中括号是否配对-----"<<endl;

  InitStack(Sa);

  char exp[]="12*(12+5)*(({}))";

  if(IsOk(Sa,exp)) cout<<"正确"<<endl;

  else cout<<"出错"<<endl;

  char exp1[]="12*(12+5)*(({})]))";

  if(IsOk(Sa,exp1)) cout<<"正确"<<endl;

  else cout<<"出错"<<endl;}

sqstack_char.h文件中代码:

const ERROR=0;

const TRUE= 1;

const FALSE= 0;

const OK= 1;

const STACK_INIT_SIZE= 10;

const STACKINCREMENT= 1;

const OVERFLOW= 0;

typedef char SElemType;

typedef struct

{ SElemType *elem;

  int top;

  int stacksize;

}sqstack;

//构造一个一定大小的空栈

void InitStack(sqstack &S)

{

       S.elem=new SElemType[STACK_INIT_SIZE]; 

    S.top=-1;

    S.stacksize=STACK_INIT_SIZE;  

}

//销毁栈

void DestroyStack(sqstack &S)

{delete []S.elem; }

//置为空栈

void ClearStack(sqstack &S)

{S.top=-1;}

//判空

bool StackEmpty(sqstack &S)

{ if(S.top==-1) return TRUE;

  else  return FALSE;

}

//栈的长度

int StackLength(sqstack S)

       {return S.top+1;}

//获取栈顶元素

int GetTop(sqstack &S,SElemType &e)

{ if(S.top==-1) return ERROR;

  e=S.elem[S.top]; return OK;}

//压栈

int Push(sqstack &S,SElemType e)

{ if(S.top==S.stacksize)return OVERFLOW;

  S.elem[++S.top]=e;

  return OK;

}

//出栈

int Pop(sqstack &S,SElemType &e)

{ if(S.top==-1) return ERROR;

   e=S.elem[S.top--];  return OK;}

实验4.3  用递归的方法解决阶乘问题和费波那契数列。

1、 阶乘

(1)   程序代码:

/*用递归算法求n的阶乘

  fab(n)=  1. 1                n=1

           2. n*fab(n-1        n>1*/

#include <iostream.h>

int fab(int n)

{if(n==0)  return 1;

 else   return n*fab(n-1);

}

int main()

 {  int n;

    cout<<"请输入数值n:  "<<endl;

    cin>>n;

    cout<<endl<<"n的阶乘为: "<<fab(n)<<endl;

    return n;

}

2、 费波那契数列

(1)   程序代码:

/*求解二阶斐波那奇数列的值

  n=0  fib(n)=0               

  n=1  fib(n)=1                     

  n>1  fib(n)=fib(n-1)+fib(n-2)*/

#include <iostream.h>

int fib(int n)

{if(n==0) return 0;

 else if(n==1)  return 1;

      else  return fib(n-1)+fib(n-2);

}      

int main()

{   int n;

    cout<<"请输入整数n: ";

    cin>>n;

    cout<<endl<<"第n项斐波那奇数列值为: "<<fib(n)<<endl;

    return 0;

}

实验4.4  用链式存储结构实现队列的初始化、进队、出队操作,生成LinkQueue.h文件,编写main函数调用。

(1)   程序代码:

MyLinkList.cpp中的代码:

//链式队列

#include <iostream.h>

#include "MyLinkList.h"

typedef LinkList QueuePtr;

typedef int QElemType;

typedef struct{

   QueuePtr front;

   QueuePtr rear;

}LinkQueue;

void InitQueue(LinkQueue &Q) {

       //构造一个空队列Q

        Q.front=Q.rear=new LNode;      

        Q.front->next=NULL;  }

void Destroyqueue(LinkQueue &Q) {

       //队列Q存在则销毁Q

        while(Q.front){

          Q.rear=Q.front->next;

          delete Q.front;Q.front=Q.rear;}

          }

void EnQueue(LinkQueue &Q,QElemType e) {

       //队列Q存在,插入元素e为Q的队尾元素

         QueuePtr p;

         p=new LNode;     

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

         Q.rear->next=p;

         Q.rear=p;}

int DeQueue(LinkQueue &Q,QElemType &e) {

       //Q为非空队列,删除Q的队头元素,并用e返回其值

        if(Q.front==Q.rear)return ERROR;  //Q为空队列

        QueuePtr p;

        p=Q.front->next;   //第一个元素

        e=p->data;

        Q.front->next=p->next;   //删除

        if(Q.rear==p)  Q.rear=Q.front;

        delete p ;

        return OK;}

bool QueueEmpty(LinkQueue Q)

// 队列Q存在,若Q为空队列则返回TRUE,否则返回FALSE

       {if(Q.front->next=NULL) return TRUE;

     else return FALSE;}

int QueueLenght(LinkQueue Q)

// 队列Q存在,返回Q的元素个数,即队列的长度

       {int j=1;

     QueuePtr p=Q.front->next;

        while(p){p=p->next;j++;}

        return j-1;     }

int GetHead(LinkQueue Q,QElemType &e)

       //Q为非空队列,用e返回Q的队头元素

{     if(Q.front==Q.rear)return ERROR;  //Q为空队列

        QueuePtr p=Q.front->next;   //第一个元素

        e=p->data; return OK;}

main()

{

  int x; LinkQueue Qa;

  cout<<"-------------链队的演示程序-------------"<<endl;

  cout<<"1、初始化链队,此时链队为空"<<endl;

  InitQueue(Qa);

  cout<<"2、元素120、110、22入队"<<endl;

  x=120;EnQueue(Qa,x);

  x=110;EnQueue(Qa,x);

  x=22;EnQueue(Qa,x);

  cout<<"3、链队有"<<QueueLenght(Qa)<<"个元素"<<endl;

  DeQueue(Qa,x);

  cout<<"4、队头元素出队"<<x<<endl;

  GetHead(Qa,x);

  cout<<"5、现在的队头元素为"<<x<<endl;

  cout<<"6、现在销毁链队"<<endl; Destroyqueue(Qa);

  cout<<"现在链队为空"<<endl;  }

MyLinkList.h文件中的代码:

// 创建不带表头结点的单链表

#include<iostream.h>

const OK=1;

const ERROR=0;

const TRUE=1;

const FALSE=0;

//带表头结点的单链表的结构定义:

typedef  struct LNode{

    int  data;

    struct LNode  *next;

}LNode,*LinkList;

// 建立单链表,逆序

void CreateList_L(LinkList &L, int n)

{     LNode *p;

    L= NULL; //生成头指针

       int i;

       cout<<"输入"<<n<<"个链表元素:"<<endl;

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

       { p=new LNode;

      cin>>p->data;  //逆序输入an,an-1 ….  a1

       p->next=L; L=p;}

}

//判断是否为空

bool empty_list(LinkList L)

{ return (L==NULL)?TRUE:FALSE;

}

//获取单链表长度

int ListLength_L(LinkList L)

{ //L为链表的头指针,本函数返回 L 所指链表的长度

LinkList p;

int k=0;

p=L;

while (p) { k++; p=p->next; } //k计非空结点数

return k; } // ListLength_L

//取单链表中的第i (i>0)个结点)

int  Getelem(LinkList L, int i)

   { LinkList p;; int j=1;

     p=L;

     while( p && j<i)

      { p=p->next;++j; }

     if(!p||j>i) return ERROR;

     else return p->data; }

//在链表查找某元素,返回位置

void LocateElem(LinkList L,int x)

       { int j;LNode *p;  //P为扫描指针,j为计数器

        if(empty_list(L)) cout<<"空表。"<<endl;

        else {

          p=L;j=1;

          while((p->data!=x) && p){j++; p=p->next;}

       if(p->data==x)cout<<"元素"<<x<<"是第"<<j<<"个元素"<<endl;

       else cout<<"没找到元素"<<x<<endl;

        }

}

//在单链表L中的第i (i>0)个结点前插入一个元素x

int ListInsert_L(LinkList &L,int i,LNode *s){

       if (i==1) {s->next=L;L=s;return OK;}

       else{

              LNode *p;int j;

              p=L;j=1;

              while(p&&j<i-1){p=p->next;++j;}

           if(!p||j>i-1) return ERROR;

              else{s->next=p->next;p->next=s;return OK;}

       }

}//ListInsert_L

//在单链表中值为x的结点前插入一个元素y,如果x值不存在,则把y插在表尾。

 void Linklist_ins(LinkList &L, int x, int y)

   { LNode *p,*q,*s;

     s=new LNode; s->data=y;s->next=NULL;

     p=L;

     while ( p && p->data!=x )  { q=p; p=p->next;}

        if(p==L){s->next=L;L=s;}

     else{s->next=p; q->next=s;}

  }

//删除单链表L中的第i (i>0)个元素。

int ListDelete_L(LinkList &L,int i)

       {LNode *p,*q;

        int j;

       if (i==1) {q=L;L=L->next;}

       else{

              p=L;  j=1 ;

              while (p ->next && j<i-1)  //指针P定位到ai的前驱结点

               { p=p->next;   ++j;}

              q=p->next;   p->next=q->next; }   //修改指针

           return q->data; delete q;       //释放结点空间

//删除单链表L中的值为x的结点

int Linklist_del2(LinkList &L, int x)

  { LNode *p,*q;

    p=L;

    while ( p && p->data!=x )   { q=p; p=p->next;}

    if (!p)  return ERROR;

    if(p==L)L=L->next;

       else q->next=p->next;

       delete p;return OK;

  }

//输出单链表

void prt_Linklist(LinkList L)

 { LNode *p;

   p=L;

   while (p) {cout<<p->data<<"   "; p=p->next;    }

 }

void InvertLinkedList( LinkList &L) {

   LNode *p,*s;

   p = L; L = NULL; // 设逆置后的链表的初态为空

   while ( p ) {         // p 为遍历指针,指向待逆置链表的头

       s = p; p = p->next; //删除 p 所指链表的第一个结点(s 结点)

       s->next = L; L = s; // 将 s 结点插入到逆置表的表头

       }

  } // InvertLinkedList

//合并有序表

void MergeList_L(LinkList &La,LinkList &Lb, LinkList &Lc)

{     //pa、pb、 pc分别是La、Lb、Lc的遍历指针

    LNode *pa,*pb,*pc;//三个链表的遍历指针

       pa = La; pb= Lb;

       //确定合并后链表的头

    if (pa->data <= pb->data ) {Lc=pc=La;pa=pa->next;}

    else  {Lc=pc=Lb; pb=pb->next;}

       while (pa && pb) //当La、Lb未结束时

        { if (pa->data <= pb->data )

                 {pc->next = pa; pc = pa; pa = pa->next;}

             else { pc->next = pb; pc = pb; pb = pb->next;}

                }

     pc->next = pa?pa:pb;

   }

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

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

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

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

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

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

数据结构实验报告格式

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

数据结构实验报告全集

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

数据结构实验报告5

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

数据结构实验报告[4]

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

数据结构实验报告

目录实验一线性表的基本操作1实验目的22实验环境23实验内容主要代码调试与运行24总结14实验二栈的基本操作1实验目的152实验环境153实验内容主要代码调试与运行154总结18实验三赫夫曼树1实验目的182实...

数据结构实验报告

数据结构与算法课内实验报告1题目针对线性表或栈或队列任选一种编程实现选择顺序或链式任选一种存储结构下数据结构建立元素插入删除等基本操作并演示实际例子运行结果算法设计通过出入栈来进行一系列操作源程序defined...

数据结构实验报告

合肥师范学院实验报告姓名课程名称数据结构

数据结构实验报告

数据结构实验报告1000实验一顺序表的删除Description实现一个线性表对一个n不超过1000的线性表进行删除操作Input第一行有一个整数n表示线性表的大小第二行有n个整数分别是list1list2li...

数据结构实验报告

专业信息管理与信息系统年级姓名题目数据结构实验报告实验一线性表题目线性表链式存储结构下基本操作的实现初始化赋值取值插入删除归并等程序清单includeltstdiohgtdefinelistinitsize20...

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