int main()
{
int i;
int arr[]={49,38,65,97,76,13,27,49};
int n=sizeof(arr)/sizeof(arr[0]);
//数据开始的排列
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
//排序后
InsertSort(arr,n);//直接插入排序
BinarySearch(arr,n);//折半查找排序
ShellSort(arr,n);//希尔排序
BubbleSort(arr,n);//冒泡排序
int low=0;
int high=n-1;
QuickSort(arr,low,high);//快速排序
//若每一次选中的枢轴元素能将待排序列划分为均匀的两个部分,递归深度最低,效率最高
printf("快速排序:>");
for(i=0;i<n;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
SimpleSelectSort(arr,n);//简单选择排序
return 0;
}
//排序算法
#include <stdio.h>
#include <string.h>
//直接插入排序:每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成
//空间复杂度O(1),时间复杂度:最好情况是原本有序--O(n),最坏情况逆序--O(n^2),平均时间复杂度--O(n^2);,s算法稳定性--稳定
void InsertSort(int arr[],int n)
{int i,j,temp;for(i=1;i<n;i++)//遍历元素{if(arr[i]<arr[i-1])//若当前关键字小于前驱{temp=arr[i];//temp暂存当前元素for(j=i-1;j>=0&&arr[j]>temp;--j)//检查当前元素前驱的所有元素{arr[j+1]=arr[j];//大于temp的后移}arr[j+1]=temp;//将temp复制到插入位置}}//打印printf("直接插入排序:>");for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");
}
//思路:先用折半查找找到应该插入的位置,再移动元素
//时间复杂度O(n^2),空间复杂度O(1);
void BinarySearch(int arr[],int n)
{int i,j,low,high,mid;int temp;for(i=1;i<n;i++)//依次排序{temp=arr[i];//暂存当前元素low=0;high=i-1;//设置折半查找的位置while(low<=high)//结束条件{mid=(low+high)/2;//取中间点if(arr[mid]>temp)//查找左半子表high=mid-1;else//查找右半子表,/当arr[mid]==temp;为了保证稳定性,应继续在mid所指位置右边寻找插入位置low=mid+1;}for(j=i-1;j>high+1;j--)arr[j+1]=arr[j];//统一后移元素,空出插入位置arr[j+1]=temp;//插入操作}//打印printf("折半排序:>");for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");
}
//希尔排序:先追求表中元素部分有序,再逐渐逼近全局有序
//先将待排序表分割成若干如i,i+d,i+2d....的特殊子表,对各个子表分别进行直接插入排序
//缩小增量d直到d=1
//空间复杂度O(1),时间复杂度不确定:最坏O(n^2),稳定性:不稳定。仅适用于顺序表
void ShellSort(int arr[],int n)
{int d,i,j;for(d=n/2;d>=1;d=d/2)//步长变化for(i=d;i<n;i++)if(arr[i]<arr[i-d])//需要=将arr[i]插入有序增量表中{int temp=arr[i];//暂存在tempfor(j=i-d;j>0&&arr[j]>temp;j=j-d){arr[j+d]=arr[j];//记录后移}arr[j+d]=temp;//插入}//打印printf("希尔排序:>");for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");
}
//根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置
//空间复杂度O(1),时间复杂度:最好情况有序,O(n),最坏情况逆序O(n^2),平均时间复杂度O(n^2);
void BubbleSort(int arr[],int n)
{int i,j;int flag=1;for(i=0;i<n-1;i++)//n个元素进行n-1趟{for(j=0;j<n-i-1;j++){if(arr[j]>arr[j+1]){int temp=arr[j+1];arr[j+1]=arr[j];arr[j]=temp;flag=0;}}if(flag==1)//没有进入说明已经有序break;}//打印printf("冒泡排序:>");for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");
}
//在待排序表中,任取一个元素作为枢轴(通常取首元素),通过一趟排序将待排序表划分为独立的
//两部分L(1...k-1),L(k+1...n),使得L(1...k-1)中所有的元素小于枢轴元素,使得L(k+1...n)的元素都大于等于枢轴元素
//枢轴元素放在了最终位置k上,这个过程为一次划分然后递归
//空间复杂度=O(递归层数),最少递归层数log2(n)+1,最大递归层数n,时间复杂度=O(n*递归层数)
//最好时间复杂度O(n*log2(n)),最坏时间复杂度O(n^2);,最好空间复杂度O(log2(n)),最坏O(n);
//稳定性:不稳定
int Partition(int arr[],int low,int high)
{int pivot=arr[low];//枢轴元素while(low<high)//用low和high搜索枢轴最终位置{while(low<high&&arr[high]>=pivot)--high;arr[low]=arr[high];//比枢轴小的元素移动到左端while(low>high&&arr[low]<=pivot)++low;arr[high]=arr[low];//比枢轴大的元素移动到右边}arr[low]=pivot;//枢轴元素存放最终位置return low;//返回枢轴元素存放的最终位置
}
void QuickSort(int arr[],int low,int high)//范围0到n-1
{if(low<high)//递归跳出的条件{int pivotpos=Partition(arr,low,high);//划分子表QuickSort(arr,low,pivotpos-1);//划分左子表QuickSort(arr,pivotpos+1,high);//划分右子表}
}
//思想:每一趟在在排序元素中选择关键字最大或最小的元素假如有序子序列中
//空间复杂度:O(1)时间复杂度O(n^2);稳定性:不稳定
void SimpleSelectSort(int arr[],int n)
{int i,j;for(i=0;i<n-1;i++){int min=i;for(j=i+1;j<n;j++){if(arr[j]<arr[min])min=j;if(min!=i){int temp=arr[i];arr[i]=arr[min];arr[min]=temp;}}}//打印printf("简单选择排序:>");for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");
}int main()
{int i;int arr[]={49,38,65,97,76,13,27,49};int n=sizeof(arr)/sizeof(arr[0]);//数据开始的排列for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");//排序后InsertSort(arr,n);//直接插入排序BinarySearch(arr,n);//折半查找排序ShellSort(arr,n);//希尔排序BubbleSort(arr,n);//冒泡排序int low=0;int high=n-1;QuickSort(arr,low,high);//快速排序//若每一次选中的枢轴元素能将待排序列划分为均匀的两个部分,递归深度最低,效率最高printf("快速排序:>");for(i=0;i<n;i++){printf("%d ",arr[i]);}printf("\n");SimpleSelectSort(arr,n);//简单选择排序return 0;
}