1、常见的排序算法:
冒泡、选择、插入、快速、归并、堆排序等
2、展开分析:
(1)冒泡排序
通过比较相邻两个元素的大小进行互换的排序,每趟排序至少有一个元素处在正确的位置。平均时间复杂度O(n^2),空间复杂度O(1),稳定 。
双层训环,外层循环控制数组需要排序的趟数,每执行一趟,当前数组最大值沉底,然后沉底的最大值就不用再参与下一趟排序(换句话说,内层循环随着排序趟数增加,内层循环范围逐渐缩小)。
算法原理:
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
-
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。
-
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码实现:
void Sort_pow(int n,int a[])
{
for(int i=0;i<n-1;i++)//n个元素进行n-1次排序
{
for(int j=0;j<n-i-1;j++)//每趟排序比较的次数
{
if(a[j]>a[j+1])
{
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
(2)插入排序
算法原理:
插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序;
首先选择第一个元素作为有序数列,然后从原始数组中逐个选择并插入到有序数组中,平均时间复杂度O(n^2),空间复杂度O(1),稳定;
代码实现:
void Sort_insert(int n,int a[]){
//假设数组总的有n个元素,先视第一个元素为有序数组,
//然后从第二个元素开始往有序中插入,[0,i-1]为有序的
for(int i=1;i<n;i++){
int tmp=a[i];//待判断插入的元素
for(int j=i-1;j>=0&&tmp<a[j];j--){
//当带插入的元素,小于有序数组右端时,有序数组右端大于Tmp
//的元素要右移动,给插入的地方空出一个位置
a[j+1]=a[j]
}
a[j+1]=tmp;
}
}
(3)选择排序
算法原理:
1)和插入排序的思想类型,先选定原始数组中第一个元素作为当前有序数组最小值;
2)然后从原始数组第二个元素开始遍历,选择a[i+1......n]中的最小值
3)若该值与a[i]不相等,则交换
4)重复遍历n趟,最终得到的是一个升序数组。
代码实现:
void Sort_select(int n,int a[]){
//先选定a[i]作为有序
//从a[i+1,.....n]选出一个最小的值
//比较最小值与a[i]是否相等,否则交换
//重复遍历n趟,每遍历一趟,有序的长度+1,无序的长度-1
int i;//有序末端
int j;//无序的开端
int min;//无序中的最小值索引
for(int i=0;i<n;i++){//最外层循环负责总的进行多少趟排序,每拍一次,便有一个无序数组中的最小值加入到有序中
min=i;
//找a[i+1],...a[n]之间的最小值,与min交换
for(int j=i+1;j<n;j++){//内层循环 负责从当前的无序数组中选出最小值
if(a[j]<a[j+1]){
min=j;
}
}
//min!=i,则交换 a[i] 和 a[min]。
//交换后,保证了a[0]..a[i]之间元素有序。
if(min !=i){
swap(a[i],a[min]);
}
}
}
(4)快速排序
算法原理
快速排序的本质就是把基准数大的都放在基准数的右边,把比基准数小的放在基准数的左边,这样就找到了基准在数组中的正确位置.
以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。
(总结就是:
每一趟排序,先选择一个基准数据,并临时变量暂存,然后分别从数组的两端(可用两个指针)开始遍历:
从右往左,把小于基准数据的值交换到前面;
从左到右,把大于基准数据的值交换到后面
最后空出来的位置就是基准数据在有序情况下的位置
)
快排优秀博客:快速排序---(面试碰到过好几次)_nrsc-CSDN博客_快速排序
代码实现:
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// 找寻基准数据的正确索引
int index = getIndex(arr, low, high);
// 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
//quickSort(arr, 0, index - 1); 之前的版本,这种姿势有很大的性能问题,谢谢大家的建议
quickSort(arr, low, index - 1);
quickSort(arr, index + 1, high);
}
}
private static int getIndex(int[] arr, int low, int high) {
// 基准数据
int tmp = arr[low];
while (low < high) {
// 当队尾的元素大于等于基准数据时,向前挪动high指针
while (low < high && arr[high] >= tmp) {
high--;
}
// 如果队尾元素小于tmp了,需要将其赋值给low
arr[low] = arr[high];
// 当队首元素小于等于tmp时,向前挪动low指针
while (low < high && arr[low] <= tmp) {
low++;
}
// 当队首元素大于tmp时,需要将其赋值给high
arr[high] = arr[low];
}
// 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
// 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
arr[low] = tmp;
return low; // 返回tmp的正确位置
}
}
5)归并排序
算法原理
优秀博客链接: