<span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">#include<stdio.h>
/****四种(冒泡,选择,快速,插入)排序(递增)下标都是从0开始的******/
int dig[1000];
int n;
/*****1 (交换类) 冒泡排序***时间复杂度:O(n^2)***/
/**思想:一趟排序中(从起始位置开始)是将最大的关键字沉到数组的底部。
n个数字排序,需要n-1趟,(假设就两个数字,那么只要一趟排序将最大的数值沉到数组底部,此序列就是有序的啦)
若序列本身就是有序的,那么只要一趟即可,(为什么还需要一趟呢?此趟是验证序列都没有发生交换,那么此序列就是有序的)
**/</span>
void bubblingSort(int msort[],int num){
int tmp;
int flag;
for(int i = 0;i < num-1;i++){
flag = 0;
for(int j = 0;j < num-i-1;j++){
if(msort[j]>msort[j+1]){
flag = 1;
tmp = msort[j];
msort[j] = msort[j+1];
msort[j+1] = tmp;
}
}
if(!flag) break;
}
for(int i = 0;i < num;i++){
printf("%d ",msort[i]);
}
printf("\n");
}
/****2 (插入类) 直接插入排序***O(n^2)**/
/**
思想:假设 2,5,7,10 已经排好了, 而接下来 数字式 6 ,一看就知道把 6 插入到5 和 7 之间。
怎么插入呢?:边插边将数组后移。6 比10 小, 那么10 后移;6比7小,7后移;6比5大,那么就把6插到5的后边(5的后边是个空的,因为前面已经把数组后移啦!!)
**/
void insertSort(int msort[],int num){
int tmp,j;
for(int i = 1;i < num;i++){
tmp = msort[i];
for( j = i-1;j >= 0;j--){
if(tmp<msort[j]){
msort[j+1] = msort[j];
}
else{
break;
}
}
msort[j+1] = tmp;
}
for(int i = 0;i <num;i++){
printf("%d ",msort[i]);
}
printf("\n");
}
/****3 (选择类) 简单选择排序****O(n^2)*/
/**
思想:第i 趟排序是指从n-i-1个记录中,找出一个最小的记录与第i个记录交换。那么第i个记录就是较小的。
列如:第一趟排序:从n个记录中(从dig[1]...dig[n])找到最小的与第一个记录交换,那么第一个就是最小的。
第二趟排序:从数组后面的n-1个记录中(从dig[2].....dig[n]),找出一个次小的,与第2个记录交换。
由此看来也是需要n-1趟排序
**/
void selectSort(int msort[],int num){
int minn,pos;
for(int i = 0;i < num-1;i++){
minn = 1111111;
for(int j = i;j < num;j++){
if(msort[j]<minn){
minn = msort[j];
pos = j;
}
}
if(i!=pos){
int tmp;
tmp = msort[pos];
msort[pos] = msort[i];
msort[i] = tmp;
}
}
for(int i = 0;i <num;i++){
printf("%d ",msort[i]);
}
printf("\n");
}
/****4 (交换类) 快速排序***O(nlogn)**/
/**
思想:待排的序列:dig[start].....dig[end],首先任意选取一个记录(通常以第一个记录作为枢轴(啥是枢轴?其实枢轴也没啥概念(不用理解他)))
然后按照下述原则重新排列其余记录。将所有关键字(就是数组里的值)小于它的记录放在它的位置之前,将所有关键字大于它的记录放在它的位置之后。
由此以该“枢轴”记录最后所落的位置i作为分界线,将序列dig[start]....dig[end],分割成两个两个子序列dig[start]...dig[i-1](此序列的值都是无序的但是他们的值都小于枢轴的值)
和dig[i+1]....dig[end]((此序列的值也是无序的但是他们的值都大于枢轴的值)。这个过程为一次划分。!!!
划分过程的具体实现:附设两个指针(此处的指针并不是指向内存地址的指针,而是指向数组的位置)low,high。low的初值=start,high = end;
设枢轴记录的关键字为pivotkey,则首先从high所指向位置向前搜索找到第一个关键字小于pivotkey的记录和枢轴的记录交换,然后从low所指向的位置向后搜索找到第一个关键字大于pivotkey的记录和枢轴的记录交换。
重复这两步,直至low==high为止。(为什么要附设两个指针从两边开始呢?枢轴右边的都是大于它的,那么只要从右边找到第一个小于枢轴的
和枢轴交换一下,那么小于枢轴的记录就到了枢轴的左边。枢轴的左边也是同样道理)
快排的实现用到递归。
**/
// 划分 划分操作的时间复杂度是O(n)
int mpartition(int msort[],int low,int high){
int pivotkey = msort[low];
int tmp;
while(low < high){
while(low < high&&msort[high]>=pivotkey) --high;
tmp = msort[low];
msort[low] = msort[high];
msort[high] = tmp;
while(low < high&&msort[low]<=pivotkey) ++low;
tmp = msort[low];
msort[low] = msort[high];
msort[high] = tmp;
}
return low;
}
/*****上述划分每一次交换需要进行3次记录移动(赋值)的操作。而实际上,对枢轴记录的赋值操作是多余的,因为只有到了low==high时
此位置才是枢轴记录的最后位置,因此只要在此位置给枢轴赋值即可。******/
int improve_mpartition(int msort[],int low,int high){
int pivotkey = msort[low];
int tmp;
while(low < high){
while(low < high&&msort[high]>=pivotkey) --high;
msort[low] = msort[high];
while(low < high&&msort[low]<=pivotkey) ++low;
msort[high] = msort[low];
}
msort[low] = pivotkey;
return low;
}
// 递归操作的时间复杂度是o(log n)
void quickSort(int msort[],int low,int high){
int pivotloc;
/***递归的终止条件是待排序的子序列是一个序列(也就是(序列的左边界)low<high(序列的右边界))***/
if(low < high){
pivotloc = improve_mpartition(msort,low,high);
quickSort(msort,low,pivotloc-1);
quickSort(msort,pivotloc+1,high);
}
}
int main(){
/**
输入n个数
**/
scanf("%d",&n);
for(int i = 0; i < n;i++){
scanf("%d",&dig[i]);
}
/****
因为数组作为参数无法实现值传递, 所以用循环将数组实现复制
****/
int m1sort[100],m2sort[100],m3sort[100],m4sort[100];
for(int i = 0;i < n;i++){
m1sort[i] = dig[i];m2sort[i] = dig[i];
m3sort[i] = dig[i];m4sort[i] = dig[i];
// m5sort[i] = dig[i];
}
/****1 (交换类) 冒泡排序*****/
printf("冒泡排序\n");
bubblingSort(m1sort,n);
/****2 (插入类) 直接插入排序*****/
printf("直接插入排序\n");
insertSort(m2sort,n);
/****3 (选择类) 简单选择排序*****/
printf("简单选择排序\n");
selectSort(m3sort,n);
/****4 (交换类) 快速排序*****/
printf("快速排序\n");
quickSort(m4sort,0,n-1);
for(int i = 0;i < n;i++){
printf("%d ",m4sort[i]);
}
}</span></span></span>
(数据结构排序的实验四)快速,冒泡,简单选择,直接插入排序的c语言实现!!
最新推荐文章于 2022-08-14 23:27:59 发布