排序实现(数据结构)

实验六  排序实现

实验目的:

1、深刻理解排序的定义和各种排序方法的特点,并能加以灵活应用;

2编程实现几种典型的排序算法,如插入排序,选择排序、交换排序、归并排序等;

3、熟悉几种典型的排序方法,了解各种方法的排序过程及其依据的原则,并对各种算法的特点、使用范围和效率有进一步的了解,掌握各种排序方法的时间复杂度的分析方法。

 

实验内容:

1、 编程实现几种典型的排序算法,如插入排序,选择排序、交换排序、归并排序。

2、 冒泡排序、快速排序的实现与比较。

/*  源程序的头文件 sort.h  */

产生随机数的算法:

 

voidgetrandat(Data ary[],int count)   /*  产生一批随机数,准备排序 */

{  int a

  int i;

 

srand(time(NULL));

  for(i=0;i<count;i++){    a=rand()%100+1;

                        ary[i].key=a;

                      }

} /*getrandat */

voidprdata(Data  ary[],int count)    /*  输出数据的函数 */

{ inti;  char ch;

  printf(“\n”);

  for(i=0;i<count;i++)printf(“%6d”,ary[i].key);

  printf(“\n”);

  printf(“\n\n  打回车键,结束显示。“); ch=getch();

} /*prdata */

 

[两种排序方法的比较源程序]

/*  sortcmp.c */

#include<sort.h>

#include <stdio.h>

#include <stdlib.h>

#define MAX 1000                         /* 数组最大界限 */

typedef int ElemType;                    /* 关键字的类型 */

typedef  struct

    { ElemType key;                 

      int shu;                        /*   其它属性域   */

     }Data;                          /* 一个纪录的结构体类型 */

Data ar[MAX],br[MAX];                 

Typedefstruct 

   { int lo,hi;

   }Selem;                         /* 栈的元素结构体类型*/

typedefstruct

   { Selem elem[MAX];                /* 一维数组子域 */

     int top;                          /* 栈顶指针子域    */

  }SqStack;                        /* 栈的顺序结构体类型*/

Stack s1;

/*  函数声明  */

void bubble(Data ary[],int n)

void qksort(Data ary[],int n)

void hoare(Data ary[],int l,int h)

void init_s(SqStack *s);

void push(SqStack *s,Selem e)                 /* 进栈一个元素 */

Selem pop(SqStack *s)

int  empty(SqStack s)

/*  主函数  */

main()

{ int k,n,j; j;  char ch;

   do { printf("\n\n\n");

       printf("\n\n     1. 产生一批随机数准备排序 ");

       printf("\n\n     2. 一般情况的起泡排序")

       printf("\n\n     3. 有序情况的起泡排序")

       printf("\n\n     4. 一般情况的快速排序")

       printf("\n\n     5. 有序情况的快速排序")

       printf("\n\n     6. 结束程序运行");

      printf("\n======================================");

       printf("\n     请输入您的选择 (1,2,3456)");

       scanf("%d",&k);

       switch(k)

         { case 1:{ printf(“the number of datas:”); /* 输入数据个数 */

               scanf(“%d”,&n);

                    getrandat(ar,n);  /*产生n个随机数 */

                   for(j=0;j<n;j++)br[j]=ar[j]; /* 保留复原始数据 */

                    prdata(ar,n);

                     } break;

             case 2:{ for(j=0;j<n;j++) ar[j]=br[j];       /* 恢复原始数据 */

                   bubble(ar,n);                /* n个数据起泡排序 */

                    prdata(ar,n);                       /* 排序后输出 */

                    } break;

             case 3: {   bubble( ar,n);            /* 有序情况的起泡排序 */

                      prdata(ar,n);

                  } break;

             case 4:{ for(j=0;j<n;j++) ar[j]=br[j]; /* 恢复原始数据 */

                  qksort(ar,n);            /* n个数据快速排序 */

                  prdata(ar,n);                   /* 排序后输出 */

                  } break;

             case 5:{ qksort(ar,n);          /* 有序情况的快速排序 */

                    prdata(ar,n);

                  } break;

          case 6: exit(0);

          } /* switch  */

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

      }while(k>=1 && k<6);

    printf("\n               再见!")

    printf(“\n        打回车键,返回。“);ch=getch();

} /* main  */

/* 起泡排序  */

void  bubble(Data ary[],int n)

{ int i,j,tag; Dtata x;

  i=0;

  do{ tag=0;

      for(j=0;j<n-1;j--)

       if (ary[j].key>ary[j+1].key) 

          { x=ary[j]; ary[j]=ary[j+1];

            ary[j+1]=x; tag=1;

          }

      i++;

     }while( i<n-1 &&tag==1); 

 } /* bubble */

/* 快速排序非递归算法 */

void  qksort(Data ary[],int n)

{   int low,high,i,tag; Selem x,y;

   init_s( &s1);                                /* 初始化一个空栈 */

    low=0; high=n-1; tag=1;

do{ while(low<high)

             {i=hoare(ary,low,high);      /* 调用一趟快速排序 */

               x.lo= i+1; x.hi=high;

                   push(&s1,x);

                   high=i-1;

                 }

        if(empty()==0) tag=0;

             else { y=pop(s1);

                  low==y.lo;  high=y.hi;

                 }

      }while(tag==1);

} /*qksort  */

/* 一趟快速排序 */

voidhoare(int ary[],int l,int h)

{ int i,j; Data x;

  i=l; j=h; x=ary[l];

  do{ while((i<j)&& ary[j]>=x)j--;

      if (i<j) { ary[i]=ary[j]; i++;}

      while((i<j)&&ary[i]<=x)i++;

      if(i<j) { ary[j]=ary[i]; j--}

     }while(i<j);

   ary[i]=x;                                    /* 枢轴记录定位 */

   return(i);                             /* 返回左、右区分界处 */

} /*  hoar */   

/* 关于栈的操作 */

void  init_s(SqStack *s)                      /* 初始化一个空栈 */

{s->top=0;

 } /* init_s */;        

/* 进栈一个元素 */

void push(SqStack *s,Selem e)                

{ if(s->top==MAX-1)printf(“\nstack  Overflow!\n”);

  else { s->top++;

         s->elem[s->top]=e;

        }

 }/* push  */

/* 出栈一个元素  */

Selem pop(SqStack *s) init_s(&s1);           

{ Selem e;

 if(s->top==0){ printf(“\n satck Empty!\n”);

              e.lo=-1; e.hi=-1;

               }

   else { e=s->elem[s->top];

          s->top--;

         }

 return(e);

 }/*  pop */

 

    本程序中,qksort用非递归实现快速排序,在这个函数里,调用了hoare函数,函数,hoareary[l…h]进行一趟快速排序,执行该函数后,将ary[]从下标i处分成左右两个分区,其中左分区中的数据均小于等于ary[i].key,而右分区中的数据均大于等于ary[i].keyl≤i≤h)。将右区尾指针(记录下标)保存入栈,对左区再调用hoare进行快速排序。另外,此处用到的栈与以前的栈结构稍有不同,(因为栈中同时要放进两个值),故操作也稍有不同。例:入栈时,要两个参数即右区首、尾指针组成的结构体变量入栈。

    快速排序的最坏情况亦即各元素已有序时,再进行快速排序,这种情况下其实并不快,这种情况下的冒泡排序反而很快。可见算法的优劣并不是绝对的。快速排序适合于记录关键字无序的情况。

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

typedef int KeyType;

typedef char    OtherType ;

typedef struct

{

        KeyType key;

        OtherType   other_data;

}RecordType;

 void getrandat(RecordTypeary[],int count)    /*  产生一批随机数,准备排序 */

{ 

         int a;

      int i;

 

   srand(time(NULL));

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

  {    a=rand()%100+1;

                       ary[i].key=a;

                      }

 } 

 

int QKPass(RecordType r[],int low,int high)

{

        RecordType x;

        x=r[low];

        while(low<high)

        {

                 while(low<high&&r[high].key)

                         high--;

                 if(low<high)

                 {r[low]=r[high];low++;}

                 while(low<high&&r[low].key<x.key)

                         low++;

                 if(low<high)

       {r[high]=r[low];high--;}

        }

        r[low]=x;

        return low;

}

void prdata(RecordType ary[],int count)    /*  输出数据的函数 */

{ int i;  

  printf("\n");

  for(i=0;i<count;i++) printf("%6d",ary[i].key);

  printf("\n");

 

 

  printf("\n\n   打回车键,结束显示。");

  

 }

void QKSort(RecordType r[],int low,int high)

{

        if(low<high)

        {

            int pos;

                 pos=QKPass( r,  low, high);

        QKSort(   r, low,pos-1);

        QKSort(   r, pos+1,high);

        }

  

}

 

 

void main()

{

 

RecordType ar[31],br[31];

int j,n;

printf("the number of datas:"); /* 输入数据个数 */

scanf("%d",&n);

getrandat(ar,n);  /*产生n个随机数 */

for(j=0;j<n;j++)br[j]=ar[j];

   prdata(ar,n); 

QKSort(ar ,1,n );           /*n个数据快速排序 */

                    prdata(ar,n);                

}

2、统计成绩

[问题描述]给出n个学生的考试成绩表,每条信息由姓名和分数组成,试设计一个算法:

1)按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次;

2)按名次列出每个学生的姓名与分数。

[基本要求]学生的考试成绩表必须通过键盘输入数据而建立,同时要对输出进行格式控制。

[算法实现]下面给出的是用直接选择排序算法实现的C语言程序。

//给出n个学生的考试成绩表,每条信息由姓名和分数组成,试设计一个算法:

//1、按分数高低次序,打印出每个学生在考试中获得的名次,分数相同的为同一名次;

//2、按名次列出每个学生的姓名与分数。

 

#define  n 10    //假设本班共10名同学

#include"stdio.h"

typedef  struct student

{ charname[8];

  int score;

  }STUDENT;

STUDENT  stu[n],temp;

 

void main(  )

{  int  num, i,  j,  max;

   printf("\n请输入学生成绩: \n");

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

  { printf("姓名:");

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

scanf ("%4d", &stu[i].score);

}

   num=1;

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

  { max=i;

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

      if(stu[j].score>stu[max].score)

      max=j;

    if (max!=i)

 {  temp =stu[max];

    stu[max]=stu[i];

    stu[i]= temp;

  }

 if((i>0)&&(stu[i].score<stu[i-1].score))

   num=num+1;

 printf("%4d%s%4d", num,stu[i].name, stu[i].score);

  }

}

 

猜你喜欢

转载自blog.csdn.net/ccccc49813645075/article/details/80219211