一、实验目的和要求
目的:熟练掌握快速排序、冒泡排序和插入排序算法。
要求:编写程序实现对给定序列排序,要求分别完成对序列的快速排序、冒泡排序和插入排序,并输出排序结果。
二、实验内容
(1)快速排序
基本思想是:
- 先从数列中取出一个数作为基准数。
- 分区过程 ,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
- 再对左右区间重复第二步,直到各区间只有一个数。
简单来说,快速排序就是在区间中随机挑选一个元素作基准,将小于基准的元素放在基准之前,大于基准的元素放在基准之后,再分别对小数区与大数区进行排序。
(2)冒泡排序
基本思想是:
- 从数组头部开始,不断比较相邻的两个元素的大小,通过交换两个元素的值让较大的元素逐渐往后移动,直到数组的末尾。经过第一轮的比较,就可以找到最大的元素,并将它移动到最后一个位置。
- 第一轮结束后,继续第二轮。仍然从数组头部开始比较,让较大的元素逐渐往后移动,直到数组的倒数第二个元素为止。经过第二轮的比较,就可以找到次大的元素,并将它放到倒数第二个位置。
- 以此类推,进行 n-1(n 为数组长度)轮“冒泡”后,就可以将所有的元素都排列好。
(3)插入排序
插入排序的的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中,最终得到的序列就是已经排序好的数据。
换句话说,插入排序就是将数组里面的第一个数当作有序的,往后的每一个数都和有序数组里面的每一个数作比较,找到合适的位置插入,结果仍然是有序的。
三、依据的基本原理
程序首先设置一个大小为10的列表,用swich语句让用户选择三种排序方法:
- 冒泡排序
- 插入排序
- 快速排序
- 如果用户没有输入1,2,3的其中一个数字,则返回”输入错误”
四、实验步骤
冒泡排序算法的步骤如下:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
百度百科上的流程图
快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
- 首先设定一个分界值,通过该分界值将数组分成左右两部分。
- 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
- 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
- 重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
插入排序的步骤:
- 从有序数列和无序数列{a2,a3,…,an}开始进行排序;
- 处理第i个元素时(i=2,3,…,n),数列{a1,a2,…,ai-1}是已有序的,而数列{ai,ai+1,…,an}是无序的。用ai与ai-1,a i-2,…,a1进行比较,找出合适的位置将ai插入;
- 重复第二步,共进行n-i次插入处理,数列全部有序。
五、实验结果及分析
冒泡排序:
N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次。
插入排序:
如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可;最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。平均来说插入排序算法的时间复杂度为O(n^2)。
快速排序:
六、附录(程序源码)
#include <stdio.h>
#define SIZE 10
//快速排序
void quickSort(int x[],int indexL,int indexR){
int i,j,mid,temp,k;
i=indexL;j=indexR;mid=x[i];
if(i>=j){
return;
}
while(i<j){
while(i<indexR&&x[i]<=mid){
i++;
}
while(j>indexL&&x[j]>=mid){
j--;
}
if(i<j){
temp=x[i];
x[i]=x[j];
x[j]=temp;
for(k=0;k<SIZE;k++){
printf("%d ",x[k]);
}
printf("\n");
}
}
if(j!=indexL){
temp=x[j];
x[j]=mid;
x[indexL]=temp;
for(k=0;k<SIZE;k++){
printf("%d ",x[k]);
}
printf("\n");
}
quickSort(x,indexL,j-1);
quickSort(x,j+1,indexR);
}
//插入排序
void insertSort(int x[]){
printf("insertSort:\n");
int i,j,temp,index,k;
for(k=0;k<SIZE;k++){
printf("%d ",x[k]);
}
printf("\n");
for(i=0;i<SIZE-1;i++){
temp=x[i+1];index=i+1;
for(j=i+1;j>=0;j--){
if(temp<x[j]){
x[j+1]=x[j];
index=j;
}
}
if(index!=i+1){
x[index]=temp;
for(k=0;k<SIZE;k++){
printf("%d ",x[k]);
}
printf("\n");
}
}
}
//冒泡排序
void bubbleSort(int x[]){
printf("bubbleSort:\n");
int i,j,temp,k;
for(k=0;k<SIZE;k++){
printf("%d ",x[k]);
}
printf("\n");
for(i=0;i<SIZE;i++){
for(j=0;j<SIZE-i-1;j++){
if(x[j]>x[j+1]){
//补充代码,实现冒泡排序
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
for(k=0;k<SIZE;k++){
printf("%d ",x[k]);
}
printf("\n");
}
}
}
}
int main() {
int a[SIZE]={11,44,22,23,77,89,31,25,29,10};
int kind;
printf("\tMenu\n\t[1]bubbleSort\n\t[2]insertSort\n\t[3]quickSort\n");
scanf("%d",&kind);
switch(kind){
case 1:
bubbleSort(a);break;
case 2:
insertSort(a);break;
case 3:
printf("quickSort:\n");
int s;
for(s=0;s<SIZE;s++){
printf("%d ",a[s]);
}
printf("\n");
quickSort(a,0,SIZE-1);
break;
default:
printf("Input ERROR\n");
}
return 0;
}