排序(一)
排序
- 排序的概念:
将一组数据按照某个或某些关键字的大小,递增或递减的排列起来。 - 排序的稳定性:
两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具有稳定性的排序算法。 - 排序分类:
1.稳定性:
稳定性排序
不稳定性排序
2.内外:
内部排序:将所有数据一次性加载到内存中进行排序。 外部排序:数据不需要一次性加载到内存中进行排序。 - 基于比较的排序算法:
1.插入排序:
直接插入排序
希尔排序
2.选择排序:
选择排序
堆排序
3.交换排序:
冒泡排序
快速排序
4.归并排序:
基于非比较排序算法:
1.计数排序
2.基数排序
3.桶排序
插入排序算法思路及实现:
1.直接插入排序:(稳定)
适用场景:
数据较少或接近有序
算法思想及代码实现:
循环选择无序区间的元素,与有序区间内进行元素进行比较,判断其插入位置,进行插入.
public static void Sort(int[] arr){
//如果只有一个数据,则为有序,无需判断,因此i=1
for (int i = 1; i <arr.length ; i++) {
//保存插入元素值并标记插入元素之前的数
int key=arr[i];
int end=i-1;
//判断插入元素与前边数的大小,进行循环
while(end>=0 && arr[end]>key){
arr[end+1]=arr[end];
end--;
}
//插入元素
arr[end+1]=key;
}
}
时间复杂度:O(N^2)
空间复杂度:O(1)
算法优化:采用折半查找法找插入元素位置
public static void insertSort(int[] arr){
//如果只有一个数据,则为有序,无需判断,因此i=1
for (int i = 1; i <arr.length ; i++) {
//保存插入元素值并标记插入元素之前的数
int key=arr[i];
int right=i;//有序区间最右侧
int left=0;//有序区间最左侧
//二分查找法
while(right>left){
int mid=(left+right)/2;
if(key>=arr[mid]){
left=mid+1;
}else{
right=mid;
}
}
//元素搬移
for (int j = i; j >left; j--) {
arr[j]=arr[j-1];
}
//插入元素
arr[left]=key;
}
}
2.希尔排序:(不稳定)
适用场景:
数据较多且排序凌乱
算法思想及代码实现:
希尔排序是对插入排序的一种优化方式。将数据较多且分布凌乱的数据,通过分组实现数据实现数据减少及接近有序,再利用插入排序进行排序的一种方法。
循环将一组元素按一定间隔gap进行分组,所有距离为gap的即为一组,对同一组元素进行大小判断及交换(即插入排序),当gap==1时,进行排序后算法结束。
public static void insertSort(int[] arr){
//如果只有一个数据,则为有序,无需判断,因此i=1
for (int i = 1; i <arr.length ; i++) {
//保存插入元素值并标记插入元素之前的数
int key=arr[i];
int right=i;//有序区间最右侧
int left=0;//有序区间最左侧
//二分查找法
while(right>left){
int mid=(left+right)/2;
if(key>=arr[mid]){
left=mid+1;
}else{
right=mid;
}
}
//元素搬移
for (int j = i; j >left; j--) {
arr[j]=arr[j-1];
}
//插入元素
arr[left]=key;
}
}
时间复杂度:由于gap取值方式不定,因此不确定
空间复杂度:O(1)