C语言实验报告(改版)

时间:2024.4.13

通  知

各位老师:

本学期非计算机专业《C语言程序设计基础》课实验报告要求:

1.  统一用《武汉科技大学实验报告》本写。

2.  本学期交三次实验报告。

①  循环结构程序设计。

②       函数。

③  指针。


 实验1 循环结构程序设计

一、实验目的

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

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

3. 熟悉break语句和continue语句用法的不同之处。

二、实验内容

【例1】 打印出所有“水仙花数”。所谓“水仙花数”是指一个三位数,其各位数字的立方和正好等于该数本身。例如:153是一个“水仙花数”,因为153=13+53+33

解题思路:根据题目要求只要分别求出一个三位数的个位、十位、百位上的数字,然后判断是否满足(某一三位数a=a的百位的立方+a的十位的立方+a的个位的立方)这个公式,满足这个三位数就是“水仙花数”。

        main( )

        { int a, b, c ,n ;

       for(n=100 ; n<1000 ;n++)

         { a=n/100 ;

          b=n/10-a*10 ;

          c=n%10 ;

          if(a*100+b*10­+c==a*a*a+b*b*b+c*c*c)

printf(“%5d” , n) ;

         }

        }

        运行结果:

          水仙花数是:153  370  371  407

【例2】以下程序,输出下三角形状的乘法九九表。

#include <stdio.h>

main()

{ int i,j;

for (i=1;i<=9;i++)         /* 打印表头*/

     printf(" %4d",i);

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

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

     printf("%c",'_');

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

  for (i=1;i<=9;i++)        /* 循环体执行一次,打印一行*/

   { for (j=1;j<=i;j++)    

       printf(" %4d",i*j);  /* 循环体执行一次,打印一个数据*/

     printf("%c",'\n');     /* 每行尾换行*/

   }

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

}

输入并执行该程序,观察输出结果,试着修改程序打印上三角形状的乘法九九表。

三、编程序并上机调试运行。

1. 李先生岁数的平方与他的夫人的岁数之和是1053,而他的夫人的岁数的平方与他的岁数之和是873,请编写程序计算李先生及其夫人的岁数各是多少。

四、实验小结


实验2  函数

一实验目的

1掌握定义函数的方法;

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

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

4掌握全局变量和局部变量,动态变量和静态变量的概念和使用方法;

二、实验内容

【例1】:有5个人,第5个人说他比第4个人大2岁,第4个人说他对第3个人大2岁,第3个人说他对第2个人大2岁,第2个人说他比第1个人大2岁,第1个人说他10岁。求第5个人多少岁。

分析:           10         (n=1)

      age(n)=  

                 age(n-1)+2  (n>1)

程序如下:

main()

{clrscr();

 printf("%d",age(5));

}

age(int n)

{ int c;

 if (n==1) c=10;

 else c=age(n-1)+2;

 return c;

}

结果:18

【例2】反向输出一个整数(非数值问题)

非数值问题的分析无法象数值问题那样能得出一个初值和递归函数式,但思路是相同的。

分析方法:

①简化问题:设要输出的正整数只有一位,则“反向输出”问题可简化为输出一位整数。

②对大于10的正整数,逻辑上可分为两部分:个位上的数字和个位以前的全部数字。将个位以前的全部数字看成一个整体,则为了反向输出这个大于10的正整数,可按以下步骤:

   a、输出个位上的数字;

   b、将个位除外的其他数字作为一个新的整数,重复a步骤的操作。

其中b问题只是对原问题在规模上进行了缩小——递归。

所以,可将反向输出一个正整数的算法归纳为:

   if n为一位整数)

                输出n

           else

               { 输出n的个位数字;

                 对剩余数字组成的新整数重复“反向输出”操作;

               }

程序如下:

#include <stdio.h>

void main()

{ void printn(int x);

  int n;

  printf("Input n=");

  scanf("%d",&n);

  if (n<0)

   {n=-n;putchar('-');}

  printn(n);

}

void printn(int x)       

{if (x>=0&&x<=9)      

  printf("%d",x);      

else                  

{printf("%d",x%10);    

 printn(x/10);         

 }

 }

执行:Input n=12345

结果:54321

执行:Input n=-12479

结果:-97421

三、编程序并上机调试运行。

 (1) 编写程序,计算下面公式并输出结果。

要求:(1)编写一个函数计算n!

(2)编写主函数,由键盘输入n和m,调用(1)中的函数完成计算。

(3)输入n和m要给出提示,并检查n和m的合理性,不合理的输入应输出错误信息,并不再进行计算。

(4)运行程序并计算

四、实验小结


实验三   指针

实验目的       1、    了解指针参数的特殊性。

               2、    掌握函数、指针、数组的用法。

实验要求       1 .复习指针的定义与使用方法。复习函数指针和指针数组的使用方法。

               2 .编写程序,运行程序并记录运行结果。

实验内容

1 、想使指针变量 pt1 指向 a 和 b 中的大者, pt2 指向小者,以下程序能否实现此目的?

swap(int *p1,int *p2)

{

int *p;

p=p1;p1=p2;p2=p;

}

main()

{

int a,b;

scanf(“%d,%d”,&a,&b);

pt1=&a;pt2=&b;

if(a<b)swap(pt1.pt2);

printf(“%d,%d\n”,*pt1,*pt2);

}

上机调试此程序。如果不能实现题目要求,指出原因,并修改之。

2、2个学生各学 4 门课,计算总平均分,并输出第 n 个学生成绩

main()

{ void average(float *p,int n);

void search(float (*p)[4],int n);

float score[3][4]=

{{65,67,79,60},{80,87,90,81},

{90,99,100,98}};

average(*score,12);

search(score,2);

}

void average(float *p,int n)

{ float *p_end, sum=0,aver;

p_end=p+n-1;

for(;p<=p_end;p++)

sum=sum+(*p);

aver=sum/n;

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

}

void search(float (*p)[4], int n)

{ int i;

printf(" No.%d :\n",n);

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

printf("%5.2f ",*(*(p+n)+i));

}

三、编程序并上机调试运行。

(1)输入一个一维实型数组,输出其中的最大值、最小值和平均值。

四、实验小结


第二篇:《数据结构》(C语言版)严蔚敏著_数据结构实验指导


《数据结构》实验指导及报告书

         /        学年  第   学期

姓    名:______________

学    号:______________

班    级:______________

指导教师:______________

数学与统计学院

20##

预备实验   C语言的函数数组指针结构体知识

一、实验目的

1、复习C语言中函数、数组、指针、结构体与共用体等的概念。

2、熟悉利用C语言进行程序设计的一般方法。

二、实验预习

说明以下C语言中的概念

1、 函数:

2、 数组:

3、指针:

4、结构体

5、共用体

三、实验内容和要求

1、调试程序:输出100以内所有的素数(用函数实现)。

#include<stdio.h>

int isprime(int n){        /*判断一个数是否为素数*/

    int m;

       for(m=2;m*m<=n;m++)

              if(n%m==0) return 0;

       return 1;

}

int main(){           /*输出100以内所有素数*/

       int i; printf("\n");

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

              if(isprime(i)==1) printf("%4d",i);

       return 0;

}

运行结果:

2、 调试程序:对一维数组中的元素进行逆序排列。

#include<stdio.h>

#define N 10

int main(){

       int a[N]={0,1,2,3,4,5,6,7,8,9},i,temp;

       printf("\nthe original Array is:\n ");

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

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

       for(i=0;i<N/2;i++){              /*交换数组元素使之逆序*/

              temp=a[i];

              a[i]=a[N-i-1];

              a[N-i-1]=temp;

       }

       printf("\nthe changed Array is:\n");

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

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

       return 0;

}

运行结果:

3、 调试程序:在二维数组中,若某一位置上的元素在该行中最大,而在该列中最小,则该元素即为该二维数组的一个鞍点。要求从键盘上输入一个二维数组,当鞍点存在时,把鞍点找出来。

#include<stdio.h>

#define M 3

#define N 4

int main(){

       int a[M][N],i,j,k;

       printf("\n请输入二维数组的数据:\n");

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

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

                     scanf("%d",&a[i][j]);

       for(i=0;i<M;i++){         /*输出矩阵*/

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

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

              printf("\n");

       }

       for(i=0;i<M;i++){

              k=0;

              for(j=1;j<N;j++)    /*找出第i行的最大值*/

                     if(a[i][j]>a[i][k])

                            k=j;

              for(j=0;j<M;j++)    /*判断第i行的最大值是否为该列的最小值*/

                     if(a[j][k]<a[i][k])

                            break;

              if(j==M)               /*在第i行找到鞍点*/

                     printf("%d,%d,%d\n",a[i][k],i,k);

       }

       return 0;

}

运行结果:

4、 调试程序:利用指针输出二维数组的元素。

#include<stdio.h>

int main(){

       int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};

       int *p;

       for(p=a[0];p<a[0]+12;p++){

              if((p-a[0])%4==0) printf("\n");

              printf("%4d",*p);

       }

       return 0;

}

运行结果:

5、 调试程序:设有一个教师与学生通用的表格,教师的数据有姓名、年龄、职业、教研室四项,学生有姓名、年龄、专业、班级四项,编程输入人员的数据,再以表格输出。

#include <stdio.h>

#define N 10

struct student{

       char name[8]; /*姓名*/

       int age;        /*年龄*/

       char job;      /*职业或专业,用s或t表示学生或教师*/

       union {

int class;            /*班级*/

char office[10];  /*教研室*/

}depa;

}stu[N];

int main(){

       int i; int n;

printf(“\n请输入人员数(<10):\n”);

scanf(“%d”,&n);

       for(i=0;i<n;i++){                        /*输入n个人员的信息*/

              printf("\n请输入第%d人员的信息:(name  age  job  class/office)\n",i+1);

              scanf("%s,%d,%c",stu[i].name, &stu[i].age, &stu[i].job);

              if(stu[i].job==’s’)

                     scanf("%d",&stu[i].depa.class);

        else

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

       }

       printf(“name    age    job    class/office”);

       for(i=0;i<n;i++){                        /*输出*/

              if(stu[i].job==’s’)

                     printf("%s %3d %3c %d\n",stu[i].name, stu[i].age, stu[i].job, stu[i].depa.class);

        else

                     printf("%s %3d %3c %s\n",stu[i].name, stu[i].age, stu[i].job, stu[i].depa.office);

       }

}

输入的数据:2

Wang 19 s 99061

Li 36 t computer

运行结果:

四、实验小结

五、教师评语


实验一  顺序表与链表

一、实验目的

1、掌握线性表中元素的前驱、后续的概念。

2、掌握顺序表与链表的建立、插入元素、删除表中某元素的算法。

3、对线性表相应算法的时间复杂度进行分析。

4、理解顺序表、链表数据结构的特点(优缺点)。

二、实验预习

说明以下概念

1、线性表:

2、顺序表:

3、链表:

三、实验内容和要求

1、阅读下面程序,在横线处填写函数的基本功能。并运行程序,写出结果。

#include<stdio.h>

#include<malloc.h>

#define ERROR 0

#define OK 1

#define INIT_SIZE 5     /*初始分配的顺序表长度*/

#define INCREM 5        /*溢出时,顺序表长度的增量*/

typedef  int ElemType;  /*定义表元素的类型*/

typedef struct Sqlist{

    ElemType *slist;      /*存储空间的基地址*/

    int length;           /*顺序表的当前长度*/

    int listsize;         /*当前分配的存储空间*/

}Sqlist;

int InitList_sq(Sqlist *L); /*                             */

int CreateList_sq(Sqlist *L,int n); /*                     */

int ListInsert_sq(Sqlist *L,int i,ElemType e);/*                 */

int PrintList_sq(Sqlist *L);  /*输出顺序表的元素*/

int ListDelete_sq(Sqlist *L,int i); /*删除第i个元素*/

int ListLocate(Sqlist *L,ElemType e); /*查找值为e的元素*/

int InitList_sq(Sqlist *L){

    L->slist=(ElemType*)malloc(INIT_SIZE*sizeof(ElemType));

    if(!L->slist) return ERROR;     

    L->length=0;                    

    L->listsize=INIT_SIZE;          

    return OK;                  

}/*InitList*/

int CreateList_sq(Sqlist *L,int n){

    ElemType e;

    int i;

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

        printf("input data %d",i+1);

        scanf("%d",&e);

        if(!ListInsert_sq(L,i+1,e))

            return ERROR;

    }

    return OK;

}/*CreateList*/

/*输出顺序表中的元素*/

int PrintList_sq(Sqlist *L){

    int i;

    for(i=1;i<=L->length;i++)

        printf("%5d",L->slist[i-1]);

    return OK;

}/*PrintList*/

int ListInsert_sq(Sqlist *L,int i,ElemType e){

    int k;

if(i<1||i>L->length+1)

return ERROR;   

if(L->length>=L->listsize){ 

L->slist=(ElemType*)realloc(L->slist,

(INIT_SIZE+INCREM)*sizeof(ElemType));

        if(!L->slist)

return ERROR;

L->listsize+=INCREM;                

}

    for(k=L->length-1;k>=i-1;k--){        

        L->slist[k+1]= L->slist[k];

    }

    L->slist[i-1]=e;                    

    L->length++;                        

    return OK;

}/*ListInsert*/

/*在顺序表中删除第i个元素*/

int ListDelete_sq(Sqlist *L,int i){

}

/*在顺序表中查找指定值元素,返回其序号*/

int ListLocate(Sqlist *L,ElemType e){   

}

int main(){

    Sqlist sl;

    int n,m,k;

    printf("please input n:");  /*输入顺序表的元素个数*/

    scanf("%d",&n);

    if(n>0){

        printf("\n1-Create Sqlist:\n");

        InitList_sq(&sl);

        CreateList_sq(&sl,n);

        printf("\n2-Print Sqlist:\n");

        PrintList_sq(&sl);

        printf("\nplease input insert location and data:(location,data)\n");

        scanf("%d,%d",&m,&k);

        ListInsert_sq(&sl,m,k);

        printf("\n3-Print Sqlist:\n");

        PrintList_sq(&sl);

        printf("\n");

        }

    else

        printf("ERROR");

    return 0;

}

l   运行结果

l   算法分析

2、为第1题补充删除和查找功能函数,并在主函数中补充代码验证算法的正确性。

删除算法代码:

l   运行结果

l   算法分析

查找算法代码:

l   运行结果

l   算法分析

3、阅读下面程序,在横线处填写函数的基本功能。并运行程序,写出结果。

#include<stdio.h>

#include<malloc.h>

#define ERROR 0

#define OK 1

typedef  int ElemType; /*定义表元素的类型*/

typedef struct LNode{  /*线性表的单链表存储*/

    ElemType data;

    struct LNode *next;

}LNode,*LinkList;

LinkList CreateList(int n); /*                                   */

void PrintList(LinkList L); /*输出带头结点单链表的所有元素*/

int GetElem(LinkList L,int i,ElemType *e); /*               */

LinkList CreateList(int n){

    LNode *p,*q,*head;

    int i;

    head=(LinkList)malloc(sizeof(LNode));        head->next=NULL;

    p=head;

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

       q=(LinkList)malloc(sizeof(LNode));       printf("input data %i:",i+1);

       scanf("%d",&q->data);            /*输入元素值*/

       q->next=NULL;                    /*结点指针域置空*/

       p->next=q;                       /*新结点连在表末尾*/

       p=q;

    }

    return head;

}/*CreateList*/

void PrintList(LinkList L){

    LNode *p;

    p=L->next;  /*p指向单链表的第1个元素*/

    while(p!=NULL){

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

        p=p->next;

    }

}/*PrintList*/

int GetElem(LinkList L,int i,ElemType *e){

    LNode *p;int j=1;

    p=L->next;

    while(p&&j<i){                     

        p=p->next;j++;

    }

    if(!p||j>i)

        return ERROR;                 

*e=p->data;                      

return OK;

}/*GetElem*/

int main(){

    int n,i;ElemType e;

    LinkList L=NULL;            /*定义指向单链表的指针*/

    printf("please input n:");  /*输入单链表的元素个数*/

    scanf("%d",&n);

    if(n>0){

        printf("\n1-Create LinkList:\n");

        L=CreateList(n);       

        printf("\n2-Print LinkList:\n");

        PrintList(L);          

        printf("\n3-GetElem from LinkList:\n");

        printf("input i=");

        scanf("%d",&i);

        if(GetElem(L,i,&e))    

            printf("No%i is %d",i,e);

        else

            printf("not exists");

    }else

        printf("ERROR");

    return 0;

}

l   运行结果

l   算法分析

4、为第3题补充插入功能函数和删除功能函数。并在主函数中补充代码验证算法的正确性。

插入算法代码:

l   运行结果

l   算法分析

删除算法代码:

l   运行结果

l   算法分析

以下为选做实验:

5、循环链表的应用(约瑟夫回环问题)

n个数据元素构成一个环,从环中任意位置开始计数,计到m将该元素从表中取出,重复上述过程,直至表中只剩下一个元素。

提示:用一个无头结点的循环单链表来实现n个元素的存储。

l   算法代码

6、设一带头结点的单链表,设计算法将表中值相同的元素仅保留一个结点。

提示:指针p从链表的第一个元素开始,利用指针q从指针p位置开始向后搜索整个链表,删除与之值相同的元素;指针p继续指向下一个元素,开始下一轮的删除,直至p==null为至,既完成了对整个链表元素的删除相同值。

l   算法代码

四、实验小结

五、教师评语


实验二 栈和队列

一、实验目的

1、掌握栈的结构特性及其入栈,出栈操作;

2、掌握队列的结构特性及其入队、出队的操作,掌握循环队列的特点及其操作。

二、实验预习

说明以下概念

1、顺序栈:

2、链栈:

3、循环队列:

4、链队

三、实验内容和要求

1、阅读下面程序,将函数Push和函数Pop补充完整。要求输入元素序列1 2 3 4 5 e,运行结果如下所示。

#include<stdio.h>

#include<malloc.h>

#define ERROR 0

#define OK 1

#define STACK_INT_SIZE 10  /*存储空间初始分配量*/

#define STACKINCREMENT 5  /*存储空间分配增量*/

typedef  int ElemType; /*定义元素的类型*/

typedef struct{

    ElemType *base;

    ElemType *top;

    int stacksize;     /*当前已分配的存储空间*/

}SqStack;

int InitStack(SqStack *S);   /*构造空栈*/

int push(SqStack *S,ElemType e); /*入栈*/

int Pop(SqStack *S,ElemType *e);  /*出栈*/

int CreateStack(SqStack *S);     /*创建栈*/

void PrintStack(SqStack *S);   /*出栈并输出栈中元素*/

int InitStack(SqStack *S){

    S->base=(ElemType *)malloc(STACK_INT_SIZE *sizeof(ElemType));

    if(!S->base) return ERROR;

    S->top=S->base;

    S->stacksize=STACK_INT_SIZE;

    return OK;

}/*InitStack*/

int Push(SqStack *S,ElemType e){

   

}/*Push*/

int Pop(SqStack *S,ElemType *e){

  

}/*Pop*/

int CreateStack(SqStack *S){

    int e;

    if(InitStack(S))

        printf("Init Success!\n");

    else{

        printf("Init Fail!\n");

        return ERROR;

    }

    printf("input data:(Terminated by inputing a character)\n");

    while(scanf("%d",&e))

        Push(S,e);

    return OK;

}/*CreateStack*/

void PrintStack(SqStack *S){

    ElemType e;

    while(Pop(S,&e))

        printf("%3d",e);

}/*Pop_and_Print*/

int main(){

    SqStack ss;

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

    CreateStack(&ss);

    printf("\n2-Pop&Print\n");

    PrintStack(&ss);

    return 0;

}     

l   算法分析:输入元素序列1 2 3 4 5,为什么输出序列为5 4 3 2 1?体现了栈的什么特性?

2、在第1题的程序中,编写一个十进制转换为二进制的数制转换算法函数(要求利用栈来实现),并验证其正确性。

l   实现代码

l   验证

3、阅读并运行程序,并分析程序功能。

#include<stdio.h>

#include<malloc.h>

#include<string.h>

#define M 20

#define  elemtype  char

typedef struct

{

    elemtype stack[M];

    int top;

}

stacknode;

void init(stacknode *st);

void push(stacknode *st,elemtype x);

void pop(stacknode *st);

void init(stacknode *st)

{

    st->top=0;

}

void push(stacknode *st,elemtype x)

{

    if(st->top==M)

        printf("the stack is overflow!\n");

    else

    {

        st->top=st->top+1;

        st->stack[st->top]=x;

    }

}

void pop(stacknode *st)

{

if(st->top>0)  st->top--;

    else  printf(“Stack is Empty!\n”);

}

int main()

{

    char s[M];

    int i;

    stacknode *sp;

    printf("create a empty stack!\n");

    sp=malloc(sizeof(stacknode));

    init(sp);

    printf("input a expression:\n");

    gets(s);

    for(i=0;i<strlen(s);i++)

    {

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

            push(sp,s[i]);

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

            pop(sp);

    }

    if(sp->top==0)

        printf("'('match')'!\n");

    else

        printf("'('not match')'!\n");

    return 0;

}

l   输入:2+((c-d)*6-(f-7)*a)/6

l   运行结果:

l   输入:a-((c-d)*6-(s/3-x)/2

l   运行结果:

l   程序的基本功能:

以下为选做实验:

4、设计算法,将一个表达式转换为后缀表达式,并按照后缀表达式进行计算,得出表达式得结果。

l   实现代码

5、假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点(不设队头指针),试编写相应的置空队列、入队列、出队列的算法。

实现代码:

四、实验小结

五、教师评语


实验三 串的模式匹配

一、实验目的

1、了解串的基本概念

2、掌握串的模式匹配算法的实现

二、实验预习

说明以下概念

1、模式匹配:

2、BF算法:

3、KMP算法:

三、实验内容和要求

1、阅读并运行下面程序,根据输入写出运行结果。

#include<stdio.h>

#include<string.h>

#define MAXSIZE 100

typedef struct{

    char data[MAXSIZE];

    int length;

}SqString;

int strCompare(SqString *s1,SqString *s2); /*串的比较*/

void show_strCompare();

void strSub(SqString *s,int start,int sublen,SqString *sub);

/*求子串*/

void show_subString();

int strCompare(SqString *s1,SqString *s2){

    int i;

    for(i=0;i<s1->length&&i<s2->length;i++)

       if(s1->data[i]!=s2->data[i])

           return s1->data[i]-s2->data[i];

    return s1->length-s2->length;

}

void show_strCompare(){

    SqString s1,s2;

    int k;

    printf("\n***show Compare***\n");

    printf("input string s1:");

    gets(s1.data);

    s1.length=strlen(s1.data);

    printf("input string s2:");

    gets(s2.data);

    s2.length=strlen(s2.data);

    if((k=strCompare(&s1,&s2))==0)

        printf("s1=s2\n");

    else if(k<0)

        printf("s1<s2\n");

    else

        printf("s1>s2\n");

    printf("\n***show over***\n");

}

void strSub(SqString *s,int start,int sublen,SqString *sub){

    int i;

    if(start<1||start>s->length||sublen>s->length-start+1){

       sub->length=0;

    }

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

       sub->data[i]=s->data[start+i-1];

    sub->length=sublen;

}

void show_subString(){

    SqString s,sub;

    int start,sublen,i;

    printf("\n***show subString***\n");

    printf("input string s:");

    gets(s.data);

    s.length=strlen(s.data);

    printf("input start:");

    scanf("%d",&start);

    printf("input sublen:");

    scanf("%d",&sublen);

    strSub(&s,start,sublen,&sub);

    if(sub.length==0)

        printf("ERROR!\n");

    else{

        printf("subString is :");

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

            printf("%c",sub.data[i]);

    }

    printf("\n***show over***\n");

}

int main(){

    int n;

    do {

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

        printf("1. strCompare\n");

        printf("2. subString\n");

        printf("0. EXIT\n");

        printf("\ninput choice:");

        scanf("%d",&n);

        getchar();

        switch(n){

            case 1:show_strCompare();break;

            case 2:show_subString();break;

            default:n=0;break;

        }

    }while(n);

    return 0;

}

l   运行程序

输入:

1

student

students

2

Computer Data Stuctures

10

4

运行结果:

2、实现串的模式匹配算法。补充下面程序,实现串的BF和KMP算法。

#include<stdio.h>

#include<string.h>

#define MAXSIZE 100

typedef struct{

    char data[MAXSIZE];

    int length;

}SqString;

int index_bf(SqString *s,SqString *t,int start);

void getNext(SqString *t,int next[]);

int index_kmp(SqString *s,SqString *t,int start,int next[]);

void show_index();

int index_bf(SqString *s,SqString *t,int start){

补充代码.....

}

void getNext(SqString *t,int next[]){

    int i=0,j=-1;

    next[0]=-1;

    while(i<t->length){

       if((j==-1)||(t->data[i]==t->data[j])){

           i++;j++;next[i]=j;

       }else

           j=next[j];

      }

}

int index_kmp(SqString *s,SqString *t,int start,int next[]){

    补充代码.....

}

void show_index(){

    SqString s,t;

    int k,next[MAXSIZE]={0},i;

    printf("\n***show index***\n");

    printf("input string s:");

    gets(s.data);

    s.length=strlen(s.data);

    printf("input string t:");

    gets(t.data);

    t.length=strlen(t.data);

    printf("input start position:");

    scanf("%d",&k);

    printf("BF:\nthe result of BF is %d\n",index_bf(&s,&t,k));

    getNext(&t,next);

    printf("KMP:\n");

    printf("next[]:");

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

        printf("%3d",next[i]);

    printf("\n");

    printf("the result of KMP is %d\n",index_kmp(&s,&t,k,next));

    printf("\n***show over***\n");

}

int main(){

show_index();

return 0;

}

输入:

abcaabbabcabaacbacba

abcabaa

1

运行结果:

四、实验小结

五、教师评语


实验四 二叉树

一、实验目的

1、掌握二叉树的基本特性

2、掌握二叉树的先序、中序、后序的递归遍历算法

3、理解二叉树的先序、中序、后序的非递归遍历算法

4、通过求二叉树的深度、叶子结点数和层序遍历等算法,理解二叉树的基本特性

二、实验预习

说明以下概念

1、二叉树:

2、递归遍历:

3、 非递归遍历:

4、层序遍历:

三、实验内容和要求

1、阅读并运行下面程序,根据输入写出运行结果,并画出二叉树的形态。

#include<stdio.h>

#include<malloc.h>

#define MAX 20

typedef struct BTNode{       /*节点结构声明*/

    char data ;               /*节点数据*/

    struct BTNode *lchild;

    struct BTNode *rchild ;  /*指针*/

}*BiTree;

void createBiTree(BiTree *t){ /* 先序遍历创建二叉树*/

    char s;

    BiTree q;

    printf("\nplease input data:(exit for #)");

    s=getche();

    if(s=='#'){*t=NULL; return;}

    q=(BiTree)malloc(sizeof(struct BTNode));

    if(q==NULL){printf("Memory alloc failure!"); exit(0);}

    q->data=s;

    *t=q;

    createBiTree(&q->lchild); /*递归建立左子树*/

    createBiTree(&q->rchild); /*递归建立右子树*/

}

void PreOrder(BiTree p){  /* 先序遍历二叉树*/

    if ( p!= NULL ) {

       printf("%c", p->data);

       PreOrder( p->lchild ) ;

       PreOrder( p->rchild) ;

    }

}

void InOrder(BiTree p){  /* 中序遍历二叉树*/

    if( p!= NULL ) {

     InOrder( p->lchild ) ;

    printf("%c", p->data);

    InOrder( p->rchild) ;

    }

}

void PostOrder(BiTree p){  /* 后序遍历二叉树*/

   if ( p!= NULL ) {

        PostOrder( p->lchild ) ;

       PostOrder( p->rchild) ;

        printf("%c", p->data);

    }

}

void Preorder_n(BiTree p){ /*先序遍历的非递归算法*/

    BiTree stack[MAX],q;

    int top=0,i;

    for(i=0;i<MAX;i++) stack[i]=NULL;/*初始化栈*/

    q=p;

    while(q!=NULL){

        printf("%c",q->data);

        if(q->rchild!=NULL) stack[top++]=q->rchild;

        if(q->lchild!=NULL) q=q->lchild;

        else

            if(top>0) q=stack[--top];

            else q=NULL;

    }

}

void release(BiTree t){ /*释放二叉树空间*/

    if(t!=NULL){

        release(t->lchild);

        release(t->rchild);

        free(t);

    }

}

int main(){

    BiTree t=NULL;

    createBiTree(&t);

    printf("\n\nPreOrder the tree is:");

    PreOrder(t);

    printf("\n\nInOrder the tree is:");

    InOrder(t);

    printf("\n\nPostOrder the tree is:");

    PostOrder(t);

    printf("\n\n先序遍历序列(非递归):");

    Preorder_n(t);

    release(t);

    return 0;

}

l   运行程序

输入:

ABC##DE#G##F###

运行结果:

2、在上题中补充求二叉树中求结点总数算法(提示:可在某种遍历过程中统计遍历的结点数),并在主函数中补充相应的调用验证正确性。

算法代码:

3、在上题中补充求二叉树中求叶子结点总数算法(提示:可在某种遍历过程中统计遍历的叶子结点数),并在主函数中补充相应的调用验证正确性。

算法代码:

4、在上题中补充求二叉树深度算法,并在主函数中补充相应的调用验证正确性。

算法代码:

选做实验:(代码可另附纸)

4、 补充二叉树层次遍历算法。(提示:利用队列实现)

5、补充二叉树中序、后序非递归算法。

四、实验小结

五、教师评语


实验五 图的表示与遍历

一、实验目的

1、掌握图的邻接矩阵和邻接表表示

2、掌握图的深度优先和广度优先搜索方法

3、理解图的应用方法

二、实验预习

说明以下概念

1、深度优先搜索遍历:

2、广度优先搜索遍历:

3、拓扑排序:

4、最小生成树:

5、最短路径:

三、实验内容和要求

1、阅读并运行下面程序,根据输入写出运行结果。

#include<stdio.h>

#define N 20

#define TRUE 1

#define FALSE 0

int visited[N];   

typedef struct    /*队列的定义*/

{

    int data[N];

    int front,rear;

}queue;

typedef struct    /*图的邻接矩阵*/

{

    int vexnum,arcnum;

    char vexs[N];

    int arcs[N][N];

}

graph;

void createGraph(graph *g);  /*建立一个无向图的邻接矩阵*/

void dfs(int i,graph *g);    /*从第i个顶点出发深度优先搜索*/

void tdfs(graph *g);          /*深度优先搜索整个图*/

void bfs(int k,graph *g);    /*从第k个顶点广度优先搜索*/

void tbfs(graph *g);          /*广度优先搜索整个图*/

void init_visit();            /*初始化访问标识数组*/

void createGraph(graph *g)   /*建立一个无向图的邻接矩阵*/

{   int i,j;

    char v;

    g->vexnum=0;

    g->arcnum=0;

    i=0;

    printf("输入顶点序列(以#结束):\n");

    while((v=getchar())!='#')

    {

        g->vexs[i]=v;        /*读入顶点信息*/

        i++;

    }

    g->vexnum=i;             /*顶点数目*/

    for(i=0;i<g->vexnum;i++) /*邻接矩阵初始化*/

        for(j=0;j<g->vexnum;j++)

            g->arcs[i][j]=0;

    printf("输入边的信息:\n");

    scanf("%d,%d",&i,&j);  /*读入边i,j*/

    while(i!=-1)              /*读入i,j为-1时结束*/

    {

        g->arcs[i][j]=1;

        g->arcs[j][i]=1;

        scanf("%d,%d",&i,&j);

    }

}

void dfs(int i,graph *g) /*从第i个顶点出发深度优先搜索*/

{

    int j;

    printf("%c",g->vexs[i]);

    visited[i]=TRUE;

    for(j=0;j<g->vexnum;j++)

        if((g->arcs[i][j]==1)&&(!visited[j]))

            dfs(j,g);

}

void tdfs(graph *g)      /*深度优先搜索整个图*/

{

    int i;

    printf("\n从顶点%C开始深度优先搜索序列:",g->vexs[0]);

    for(i=0;i<g->vexnum;i++)

        if(visited[i]!=TRUE)

            dfs(i,g);

}

void bfs(int k,graph *g)  /*从第k个顶点广度优先搜索*/

{

    int i,j;

    queue qlist,*q;

    q=&qlist;

    q->rear=0;

    q->front=0;

    printf("%c",g->vexs[k]);

    visited[k]=TRUE;

    q->data[q->rear]=k;

    q->rear=(q->rear+1)%N;

    while(q->rear!=q->front)

    {

        i=q->data[q->front];

        q->front=(q->front+1)%N;

        for(j=0;j<g->vexnum;j++)

            if((g->arcs[i][j]==1)&&(!visited[j]))

            {

                printf("%c",g->vexs[j]);

                visited[j]=TRUE;

                q->data[q->rear]=j;

                q->rear=(q->rear+1)%N;

            }

    }

}

void tbfs(graph *g) /*广度优先搜索整个图*/

{

    int i;

    printf("\n从顶点%C开始广度优先搜索序列:",g->vexs[0]);

    for(i=0;i<g->vexnum;i++)

        if(visited[i]!=TRUE)

            bfs(i,g);

}

void init_visit()   /*初始化访问标识数组*/

{

    int i;

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

        visited[i]=FALSE;

}

int main()

{

    graph ga;

    int i,j;

    createGraph(&ga);

    printf("无向图的邻接矩阵:\n");

for(i=0;i<ga.vexnum;i++)

{

        for(j=0;j<ga.vexnum;j++)

            printf("%3d",ga.arcs[i][j]);

        printf("\n");

    }

    init_visit();

    tdfs(&ga);

    init_visit();

    tbfs(&ga);

    return 0;

}

§  根据右图的结构验证实验,输入:

ABCDEFGH#

0,1

0,2

0,5

1,3

1,4

2,5

2,6

3,7

4,7

-1,-1

§  运行结果:

2、阅读并运行下面程序,补充拓扑排序算法。

#include<stdio.h>

#include<malloc.h>

#define N 20

typedef struct edgenode{  /*图的邻接表:邻接链表结点*/

    int adjvex;  /*顶点序号*/

    struct edgenode *next; /*下一个结点的指针*/

}edgenode;

typedef struct vnode{ /*图的邻接表:邻接表*/

    char data;    /*顶点信息*/

    int ind;      /*顶点入度*/

    struct edgenode *link;  /*指向邻接链表指针*/

}vnode;

void createGraph_list(vnode adjlist[],int *p); /*建立有向图的邻接表*/

void topSort(vnode g[],int n); /*拓扑排序*/

void createGraph_list(vnode adjlist[],int *p){ /*建立有向图的邻接表*/

    int i,j,n,e;

    char v;

    edgenode *s;

    i=0;n=0;e=0;

    printf("输入顶点序列(以#结束):\n");

    while((v=getchar())!='#')

    {

        adjlist[i].data=v;        /*读入顶点信息*/

        adjlist[i].link=NULL;

        adjlist[i].ind=0;

        i++;

    }

    n=i;

    *p=n;

    /*建立邻接链表*/

    printf("\n请输入弧的信息(i=-1结束):i,j:\n");

    scanf("%d,%d",&i,&j);

    while(i!=-1){

        s=(struct edgenode*)malloc(sizeof(edgenode));

        s->adjvex=j;

        s->next=adjlist[i].link;

        adjlist[i].link=s;

        adjlist[j].ind++;  /*顶点j的入度加1*/

        e++;

        scanf("%d,%d",&i,&j);

    }

    printf("邻接表:");

    for(i=0;i<n;i++){  /*输出邻接表*/

        printf("\n%c,%d:",adjlist[i].data,adjlist[i].ind);

        s=adjlist[i].link;

        while(s!=NULL){

            printf("->%d",s->adjvex);

            s=s->next;

        }

    }

}

void topSort(vnode g[],int n){ /*拓扑排序*/

}

int main(){

    vnode adjlist[N];

    int n,*p;

    p=&n;

    createGraph_list(adjlist,p);

    return 0;

}

§  根据输入,输出有向图的拓扑排序序列。并画出有向图。输入:

ABCDEF#

0,1

1,2

2,3

4,1

4,5

-1,-1

§  运行结果:

3、阅读并运行下面程序。

#include<stdio.h>

#define N 20

#define TRUE 1

#define INF 32766                    /*邻接矩阵中的无穷大元素*/

#define INFIN 32767                  /*比无穷大元素大的数*/

typedef struct

{ /*图的邻接矩阵*/

    int vexnum,arcnum;

    char vexs[N];

    int arcs[N][N];

}

graph;

void createGraph_w(graph *g,int flag);

void prim(graph *g,int u);

void dijkstra(graph g,int v);

void showprim();

void showdij();

/*建带权图的邻接矩阵,若flag为1则为无向图,flag为0为有向图*/

void createGraph_w(graph *g,int flag)

{

    int i,j,w;

    char v;

    g->vexnum=0;

    g->arcnum=0;

    i=0;

    printf("输入顶点序列(以#结束):\n");

    while((v=getchar())!='#')

    {

        g->vexs[i]=v;        /*读入顶点信息*/

        i++;

    }

    g->vexnum=i;

    for(i=0;i<6;i++)        /*邻接矩阵初始化*/

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

            g->arcs[i][j]=INF;

    printf("输入边的信息:\n");

    scanf("%d,%d,%d",&i,&j,&w);  /*读入边(i,j,w)*/

    while(i!=-1)              /*读入i为-1时结束*/

    {

        g->arcs[i][j]=w;

        if(flag==1)

            g->arcs[j][i]=w;

        scanf("%d,%d,%d",&i,&j,&w);

    }

}

void prim(graph *g,int u)/*出发顶点u*/

{

    int lowcost[N],closest[N],i,j,k,min;

    for(i=0;i<g->vexnum;i++)  /*求其他顶点到出发顶点u的权*/

    {

        lowcost[i]=g->arcs[u][i];

        closest[i]=u;

    }

    lowcost[u]=0;

    for(i=1;i<g->vexnum;i++)    /*循环求最小生成树中的各条边*/

    {   min=INFIN;

        for(j=0;j<g->vexnum;j++)   /*选择得到一条代价最小的边*/

            if(lowcost[j]!=0&&lowcost[j]<min)

            {

                min=lowcost[j];

                k=j;

            }

        printf("(%c,%c)--%d\n",g->vexs[closest[k]],g->vexs[k],lowcost[k]);      /*输出该边*/

        lowcost[k]=0;       /*顶点k纳入最小生成树 */

        for(j=0;j<g->vexnum;j++)  /*求其他顶点到顶点k 的权*/

            if(g->arcs[k][j]!=0&&g->arcs[k][j]<lowcost[j])

            {

                lowcost[j]=g->arcs[k][j];

                closest[j]=k;

            }

    }

}

void printPath(graph g,int startVex,int EndVex)

{

    int stack[N],top=0;   /*堆栈*/

    int i,k,j;

    int flag[N];  /*输出路径顶点标志*/

    k=EndVex;

    for (i=0;i<g.vexnum;i++) flag[i]=0;

    j=startVex;

    printf("%c",g.vexs[j]);

    flag[j]=1;

    stack[top++]=k;

    while (top>0) /*找j到k的路径*/

    {

        for (i=0;i<g.vexnum;i++)

        {

            if (path[k][i]==1 && flag[i]==0) /*j到k的路径含有i顶点*/

            {

                if (g.arcs[j][i]!=INF )   /*j到i的路径含有中间顶点*/

                {

                    printf("-> %c(%d) ",g.vexs[i],g.arcs[j][i]);

                            /*输出j到k的路径的顶点i*/

                    flag[i]=1;

                    j=i;

                    k=stack[--top];

                    break;

                }

                else

                {

                    if (i!=k) stack[top++]=i;  /*break;*/

                }

            }

        }

    }

void dijkstra(graph g,int v){  /*dijkstra算法求单源最短路径*/

    int path[N][N],dist[N],s[N];

    int mindis,i,j,u,k;

    for(i=0;i<g.vexnum;i++){

        dist[i]=g.arcs[v][i];

        s[i]=0;

        for(j=0;j<g.vexnum;j++)

            path[i][j]=0;

        if(dist[i]<INF){

            path[i][v]=1;

            path[i][i]=1;

        }

    }

    dist[v]=0;

    s[v]=1;

    for(i=0,u=1;i<g.vexnum;i++){

        mindis=INFIN;

        for(j=0;j<g.vexnum;j++)

            if(s[j]==0)

                if(dist[j]<mindis){

                    u=j;

                    mindis=dist[j];

                }

        s[u]=1;

        for(j=0;j<g.vexnum;j++)

            if((s[j]==0)&&dist[u]+g.arcs[u][j]<dist[j]){

                dist[j]=dist[u]+g.arcs[u][j];

                for(k=0;k<g.vexnum;k++)

                    path[j][k]=path[u][k];

                path[j][j]=1;

            }

    }

    printf("\n顶点%c->到各顶点的最短路径\n",g.vexs[v]);

    for(i=0;i<g.vexnum;i++){

        printf("\n顶点%c->顶点%c:",g.vexs[v],g.vexs[i]);

        if(dist[i]==INF||dist[i]==0)

            printf("无路径");

        else{

            printf("%d  ",dist[i]);

            printf("经过顶点:");

            printPath(g,v,i);  /*输出v到i的路径*/

        }

    }

}

void showprim()/*最小生成树prim算法演示*/

{

    graph ga;

    createGraph_w(&ga,1);

    prim(&ga,0);

}

void showdij(){   /*dijstra算法演示*/

    graph ga;

    createGraph_w(&ga,0);

    dijkstra(ga,0);

}

int main(){

showprim(); /*prim算法演示*/

getchar();

    showdij();  /*dijstra算法演示*/

    return 0;

}

§  下面的输入分别验证prim算法和dijstra算法。输入实例的第一部分为无向图,求其最小生成树;输入的第二部分为有向图,求其最短路径。

最小生成树                                 最短路径


ABCDEF#

0,1,6

0,2,1

0,3,5

1,2,5

1,4,3

2,3,5

2,4,6

2,5,4

3,5,2

4,5,6

-1,-1,-1

ABCDEF#

0,2,10

0,5,100

0,4,30

1,2,5

2,3,50

3,4,20

3,5,10

4,3,20

4,5,60

-1,-1,-1


§  运行结果:(并画出两个图)

最小生成树                                 最短路径


四、实验小结

五、教师评语


实验六 查找

一、实验目的

1、掌握查找表、动态查找表、静态查找表和平均查找长度的概念。

2、掌握线性表中顺序查找和折半查找的方法。

3、学会哈希函数的构造方法,处理冲突的机制以及哈希表的查找。

二、实验预习

说明以下概念

1、顺序查找:

2、折半查找:

3、哈希函数:

4、冲突及处理:

三、实验内容和要求

1. 静态查找表技术

依据顺序查找算法和折半查找算法的特点,对下面的两个查找表选择一个合适的算法,设计出完整的C源程序。并完成问题:

查找表1 : { 8 ,15 ,19 ,26 ,33 ,41 ,47 ,52 ,64 ,90 } ,查找key = 41

查找表2 : {12 ,76 ,29 ,15 ,62 ,35 ,33 ,89 ,48 ,20 } ,查找key =35

查找key=41的算法:                      比较次数:

查找key=35的算法:                      比较次数:

l   顺序查找算法算法实现代码

l   折半查找算法算法实现代码

2、哈希表的构造与查找

/* 采用开放地址法构造哈希表*/

#include<stdio.h>

#include<malloc.h>

#define MAXSIZE 25

#define P 13

#define OK 1

#define ERROR 0

#define DUPLICATE -1

#define TRUE 1

#define FALSE 0

typedef struct{  /*哈希表元素结构*/

    int key;  /*关键字值*/

    int flag; /*是否存放元素*/

}ElemType;

typedef struct {

    ElemType data[MAXSIZE];

    int count;      /*元素个数*/

    int sizeindex;  /*当前哈希表容量*/

}HashTable;

int d1[15]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; /*线性探测序列*/

int d2[15]={0,1,-1,2*2,-2*2,3*3,-3*3,4*4,-4*4,5*5,-5*5,6*6,-6*6,7*7,-7*7}; /*二次探测序列*/

void dataset(int ds[],int *len);

int InsertHash(HashTable *H,int e,int d[]);

int CreateHash(HashTable *H,int ds[],int len,int d[]);

int SearchHash(HashTable *H, int e,int d[]);

void menu();

/*输入查找表*/

void dataset(int ds[],int *len){

    int n,m;

    n=0;

    printf("\n查找表输入:");

    while(scanf("%d",&m)==1){  /*以输入一个非整数作为结束*/

        ds[n]=m;

        n++;

    }

    *len=n;

}

/*计算哈希地址,插入哈希表*/

int InsertHash(HashTable *H,int e,int d[]){

    int k,i=1;

    k=e%P;

    while(H->data[k].flag==TRUE||k<0){

        k=(e%P+d[i])%MAXSIZE;i++;

        if(i>=15)

            return ERROR;

    }

    H->data[k].key=e;

    H->data[k].flag=TRUE;

    H->count++;

    return OK;

}

/*构造哈希表*/

int CreateHash(HashTable *H,int ds[],int len,int d[]){

    int i;

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

        if(SearchHash(H,ds[i],d)!=-1)

            return DUPLICATE;

        InsertHash(H,ds[i],d);

        if(H->count>=MAXSIZE)

            return ERROR;

    }

    return OK;

}

/*初始化哈希表*/

void InitHash(HashTable *H){

    int i;

    for(i=0;i<MAXSIZE;i++){

        H->data[i].key=0;

        H->data[i].flag=FALSE;

    }

}

/*在哈希表中查找*/

int SearchHash(HashTable *H, int e,int d[]){

    int k,i=1;

    k=e%P;

    while(H->data[k].key!=e){

        k=(e%P+d[i])%MAXSIZE;i++;

        if(i>=15)

            return -1;

    }

    return k;

}

/*演示菜单*/

void menu(){

    int choice;int *p;

    HashTable h;

    h.count=0;h.sizeindex=MAXSIZE;

    int a[MAXSIZE]={0};

    int i,n,e;

    dataset(a,&n);  /*建立查找表*/

    getchar();

    printf("\n");

    do{

        printf("\n----哈希查找演示----\n");

        printf("\n1.线性探测构造哈希表\n");

        printf("\n2.二分探测构造哈希表\n");

        printf("\n3.退出\n");

        printf("\n输入选择:");

        scanf("%d",&choice);

        if(choice==1)

            p=d1;

        else if(choice==2)

            p=d2;

        else

            return;

        InitHash(&h);   /*初始化哈希表*/

        if(!(i=CreateHash(&h,a,n,p))) /*构造哈希表*/

            printf("\n哈希表构造失败!\n");

        else if(i==DUPLICATE)

            printf("\n哈希表具有重复关键字!\n");

        else{

            printf("\n哈希表:\n");

            for(i=0;i<h.sizeindex;i++)

                printf("%3d",h.data[i].key);

            printf("\n\n哈希查找\n输入要查找的key值:");

            getchar();

            scanf("%d",&e);

            if((i=SearchHash(&h,e,p))==-1)

                printf("\n%d未找到\n",e);

            else

                printf("\n%d在哈希表中下标为%d\n",e,i);

        }

        getchar();

    }while(1);

}

int main(){

    menu();

    return 0;

}

输入查找表为:19 14 23 1 68 20 84 27 55 11 10 79(注意以输入一个非整数结束)。

运行结果:

1)线性探测散列:

哈希表形态:

84在哈希表中的位置:

2)二次探测散列:

哈希表形态:

84在哈希表中的位置:

四、实验小结

五、教师评语


实验七 排序

一、实验目的

1、掌握内部排序的基本算法;

2、分析比较内部排序算法的效率。

二、实验预习

说明以下概念

1、简单排序:

2、希尔排序:

3、快速排序:

4、堆排序:

三、实验内容和要求

1. 运行下面程序:

#include <stdlib.h>

#include <stdio.h>

#define MAX 50

int slist[MAX]; /*待排序序列*/

void insertSort(int list[], int n);

void createList(int list[], int *n);

void printList(int list[], int n);

void heapAdjust(int list[], int u, int v);

void heapSort(int list[], int n);

/*直接插入排序*/

void insertSort(int list[], int n)

{

    int i = 1, j = 0, node = 0, count = 1;

    printf("对序列进行直接插入排序:\n");

    printf("初始序列为:");

    printList(list, n);

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

    {

        node = list[i];

        j = i - 1;

        while(j >= 0 && node < list[j])

        {

            list[j+1] = list[j];

            --j;

        }

        list[j+1] = node;

        printf("第%d次排序结果:", count++);

        printList(list, n);

    }

}

/*堆排序*/

void heapAdjust(int list[], int u, int v)

{

    int i = u, j , temp = list[i];

        j = 2 * i;

    while (j <= v)

    {

        if(j < v && list[j] < list[j+1])

            j++; /*若右孩子较大,则把j修改为右孩子的下标*/

        if(temp < list[j])

        {

            list[i] = list[j]; /*将list[j]调到父亲的位置上*/

            i = j;

            j = 2 * i; /*修改i和j的值,以便继续向下筛选*/

        }

        else

            break; /*筛选完成,终止循环*/

    }

    list[i] = temp; /*被筛结点的值放入最终位置*/

}

void heapSort(int list[], int n)

{

    int i = 0, temp = 0, count = 1;

    printf("对序列进行堆排序:\n");

    printf("初始序列为:");

    printList(list, n);

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

        heapAdjust(list, i, n); /*建立初始堆*/

    printf("建立的初始堆为:");

    printList(list, n);

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

    {/*循环,完成堆排序*/

        temp = list[1];

        list[1] = list[i];

        list[i] = temp; /*将第一个元素同当前区间内最后一个元素对换*/

        heapAdjust(list, 1 , i-1); /*筛选出list[1]结点*/

        printf("第%d次排序结果:", count++);

        printList(list, n);

    }

}

/*生成待排序序列*/

void createList(int list[], int *n)

{

     int i = 1,a;

     printf("请输入待排序序列(长度小于50,以输入一个字符结束):\n");

     while(scanf("%d",&a)==1)

     {

        list[i] = a;

        i++;

     }

     *n=i-1;

     getchar();

}

/*输出排序结果*/

void printList(int list[], int n)

{

     int i = 1;

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

     {

         printf("  %d  ", list[i]);

         if(i % 10 ==0 && i != 0)

             printf("\n");

     }

     printf("\n");

}

int main()

{

    int choice=1,length;

    while(choice!=0)

    {

        printf("\n");

        printf("***** 内部排序算法演示程序 *****\n");

        printf("\n1. 直接插入排序 \n");

        printf("\n2. 堆排序 \n");

        printf("\n0. 退出\n");

        printf("\n请选择:");

        scanf("%d", &choice);

        getchar();

        switch(choice)

        {

        case 1:

            {

                createList(slist, &length);

                insertSort(slist, length);

                break;

            }

        case 2:

            {

                createList(slist, &length);

                heapSort(slist, length);

                break;

            }

        default:choice=0;

        }

        printf("\n");

    }

    return 0;

}

输入待排序序列:49 38 65 97 13 27 49(以输入一个字符作为结束)

1)直接插入排序运行结果(写出每一趟的状态):

2)堆排序运行结果(写出每一趟的状态):

2、在1题中补充希尔排序算法。

算法代码:

输入待排序序列:49 38 65 97 13 27 49(以输入一个字符作为结束)

运行结果(写出每一趟的状态):

3、在1题中补充快速排序算法。

算法代码:

输入待排序序列:49 38 65 97 13 27 49(以输入一个字符作为结束)

运行结果(写出每一趟的状态):

四、实验小结

请比较各个排序算法的性能。

五、教师评语

更多相关推荐:
c语言实验报告

四川师范大学计算机科学学院C语言程序设计实验手册20xx年2月年级20xx级专业电子商务班级04班姓名罗桂清学号20xx110438指导教师廖雪花1C语言程序设计实验课程简介课程名称C语言程序设计实验课程性质专...

c语言实验报告

课程设计报告学院课程名称专业班级学生姓名学号指导教师完成时间年月目录1菜单选择程序课程设计2学生信息管理系统课程设计题目1菜单选择程序课程设计一课程设计内容与要求1主菜单编写程序能够显示以下的主菜单主菜单1字母...

C语言实验报告书写格式及模板

大学学院实验报告专业名称实验室实验课程C实验名称姓名学号同组人员实验日期语言程序设计程序设计12345678

c语言实验报告模板完成版

高级语言程序设计学生实验报告专业计算机科学与技术学号姓名1实验一C程序的运行环境和使用方法1实验目的1了解所用的计算机系统的基本操作方法学会独立使用该系统2了解在该系统上如何编辑编译连接和运行一个C程序3通过运...

C语言实验报告(八)

华北水院高级语言程序设计C语言实验报告20xx20xx学年第二学期20xx级专业班级学号一实验题目文件二实验目的略三实验内容1程序验证用记事本编辑文本文件file1txt分析一下程序的功能及结果并验证inclu...

大学C语言实验报告答案

郑州大学09级C语言实验报告答案实验一1includeltstdiohgtvoidmainintabcscanfquotdddquotampaampbampcprintfquotsumdnquotabc2inc...

C语言实验报告样本

实验报告课程名称C语言程序设计实验项目顺序结构程序设计实验仪器计算机系别机电工程学院专业机械设计制造及其自动化班级学号机械110120xx010008学生姓名郭奎宇实验日期20xx年10月24日成绩指导教师一实...

C语言实验报告(五)

C语言实验报告五一实验目的1掌握使用C语言中数组的方法2掌握如何定义数组如何引用数组元素3掌握二维数组的元素在内存中的存放方式4掌握什么是字符串字符串结束符的作用5实现字符串的存储和操作包括字符串的输入和输出6...

《C语言》课内实验报告7

C语言实验报告一实验题目结构体的应用二实验目的1进一步掌握结构体变量数组的定义和使用方法掌握结构体与指针的应用2学习共用体的概念和使用3学习链表的概念和使用三实验内容1有6个学生每个学生的数据包括学号姓名性别4...

C语言贪吃蛇实验报告

C语言程序设计实训报告姓名专业班级指导教师二011年7月14日11112目录实训目的和要求1实训目的和任务1实训要求122122实训任务内容1游戏规则1流程设计23313233软件使用说明3编辑程序主要软件3编...

c语言三种基本控制结构实验报告

学生实验报告实验课名称C语言实验项目名称三种基本控制结构专业名称班学级号学生姓名教师姓名月日实验日期年月日实验室名称六实验中遇到的问题解决方法及体会在实验过程中写的很多程序显示错误的结果做起来不熟练体会到平时上...

C语言程序设计实验报告9

C语言程序设计实验报告九专业计算机科学与技术班级卓越工程师班日期20xx年12月23日实验组别第一组成绩第九次实验结构与联合实验指导教师李开学生姓名学号实验名称结构与联合实验一实验目的1熟悉和掌握结构的说明和引...

c语言实验报告(38篇)