1.直接插入排序
插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率
在排序的过程中,先拍小序列再拍大序列
将整个序列分为两个部分有序的(从小到大)+无序
1.将队列第二个数字拿出存入tmp中
2.与第一个数字进行比较组成一个两个数的有序队列
3.依次从后面拿出数字与之前的序列进行比较
4.如果前面的数字大于tmp则依次向后移动
5.直达找到前面小于tmp的数字
6.此时tmp比i-1大 又比i+1小当前位置最好的位置
public static void inserSort(int[] a){
int j = 0;
int len = a.length;
int tmp = 0;
for(int i=1;i<len;i++){
tmp = a[i];
for( j=i-1;j>-1;j--){
if(a[j]>tmp){
a[j+1] = a[j];
}else{
break;
}
}
a[j+1] = tmp;
System.out.print("第"+i+"次:");
for(int k=0;k<a.length;k++){
System.out.print(a[k]+" ");
}
System.out.println();
}
}
2.希尔排序
插入排序升级版
将原有的无序序列 按一定的规则进行分组对所分的组进行插入排序
1.手动分组
2.按照手动分组进行循环
3.手动分组的数字 为在无序序列挑选组数的数字间隔
4.拿出之后进行插入排序
5.最后一次必须为一 进行一次插入排序完成
6.之前的分组提高插入排序的效率,实质上还是插入排序
最终版
Len/2达到自动分组的目的
最后一次必然为len=1所以最后一次进行完整的插入排序
public static void shellSort(int[] a){
int len = a.length;
int count = 0;
while(len!=0){
len=len/2;
for(int i=len;i<a.length;i+=len){
int tmp = a[i];
int j = 0;
for( j=i-len;j>=0;j-=len){
if(a[j]>tmp){
a[j+len] = a[j];
}else{
break;
}
}
a[j+len] = tmp;
}
System.out.print("第"+(count++)+"次:");
for(int k=0;k<a.length;k++){
System.out.print(a[k]+" ");
}
System.out.println();
}
}
【1、2】https://blog.csdn.net/qq_36390039/article/details/89850412
3.简单选择排序
每一次遍历序列将序列中的最小值放在无序序列之前
1.从0开始到length挑选出最小的一个放在最0
2.从1开始到length挑选最小的一个放在1
3.从2开始。。。。。
4.直到最后一个
5.不断地将后面最小的向前放
public static void selectSort(int[] a){
int tmp = 0;
int len = a.length;
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if(a[j]<a[i]){
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}
}
System.out.print("第"+(i)+"次:");
for(int k=0;k<a.length;k++){
System.out.print(a[k]+" ");
}
System.out.println();
}
4.堆排序
通过模拟建树的形式 以大根堆的形式进行排序
核心在于
Adjust调整
调整的过程遵循从下向上
最右只有一个最孩子 maxChildIndex = 2* root+1;
在左孩子和右孩子中挑选出最大的一个
在与父节点进行比较 将三者中最大的一个赋值给父节点
第0次:32 21 16 13 2 43
第1次:21 13 16 2 32 43
第2次:16 13 2 21 32 43
第3次:13 2 16 21 32 43
第4次:2 13 16 21 32 43
public static void heapSort(int[] array){
for(int root = array.length/2-1;root>=0;root--){
adjust(array, array.length,root);
}
int count = array.length;
int k = 0;
while(count>1){
int tmp = array[count-1];
array[count-1] = array[0];
array[0] = tmp;
count--;
adjust(array,count,0);
System.out.print("第"+k+++"次:");
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
}
}
public static void adjust(int[] array,int count,int root){
int maxChilndex;
while(root<=count/2-1){ //count/2-1拿到上一层的左子叶节点
if(root == count/2-1 && count%2==0){
//当叶节点为欧舒适 最有一个非叶子节点只有一个左孩子
maxChilndex = 2*root+1;
}else{
int left = 2*root+1;
int right = left+1;
if(array[left]>=array[right]){
maxChilndex = left;
}else{
maxChilndex = right;
}
}
if(array[root]<array[maxChilndex]){
int tmp = array[root];
array[root] = array[maxChilndex];
array[maxChilndex] = tmp;
root = maxChilndex;
}else{
return;
}
}
}
【3、4】
5.冒泡排序
最好理解的排序方式依次从头到尾遍历待排序的数组,两两交换 将大数向后移动
第0次:2 43 32 16 21 13
第1次:2 13 43 32 21 16
第2次:2 13 16 43 32 21
第3次:2 13 16 21 43 32
第4次:2 13 16 21 32 43
第5次:2 13 16 21 32 43
public static void bubbleSort(int[] arr){
/**
* 冒泡排序
* 时间复杂度 O(n^2)
*/
int temp = 0;
boolean flag = false;
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
if(!flag){
break;
}else{
flag = false;
}
}
}
优化设置一个开关flag 发生交换则将flag设为true 交换之后下一次不再进行同两个数进行比较
6.快速排序
分治思想
不断地缩小被排序的区间 将最小的区间排好以此类推整体排好
public static void quickSort(int[] a){
quick(a,0,a.length-1);
}
public static void quick(int[] a,int left,int right){
if(left>=right){
return;
}
int beleft = left;
int beright = right;
int key = a[left];
while(left<right){
while(left<right&&a[right]>=key){
right--;
}
if(left<right){
a[left] = a[right];
left++;
}
while(left<right&&a[left]<key){
left++;
}
if(left<right){
a[right] = a[left];
right--;
}
}
a[left] = key;
quick(a,beleft,left-1);
quick(a,right+1,beright);
}
1.递归的方式 当 left坐标大于等于right坐标 结束本趟遍历
2.当传入的区间left小于 right 证明最少有一个数
3.初始值 a[left] = key
4.在left小于right前提下 从right边向left遍历 大于key 将right赋值给a[left]
5.left向左走一格 保证不每次遍历只交换一个
6.当右侧交换完毕交换左侧 依次从左侧寻找第一个 a[left]>key将其交换到 right
7.最后一key为坐标 达到左侧 小于key右侧大于key
8.完成本组
9.递归下一组此时 key坐标left==right
10.将左侧和右侧 作为新的待排序数组 传入quick
【5、6】https://blog.csdn.net/qq_36390039/article/details/90046632
7.归并排序
分治思想从上到下 现将整个数组分成两个 再将两个分为四个。。。直到分为每一个数是一个组 两两合并 排序 最后合成一个大组
public static void mergeSort(int[] array,int start,int end){
if(start>=end){
return;
}
int mid = (start+end)>>>1;
mergeSort(array,start,mid); //分
mergeSort(array,mid+1,end); //分
merge(array,start,mid,end); //合
}
private static void merge(int[] array, int start, int mid, int end) {
int[] tmpArr = new int[array.length];
int tmpIndex = start;
int start2 = mid+1;
int i =start;
while(start<=mid && start2<=end) {
if (array[start] <= array[start2]) {
tmpArr[tmpIndex++] = array[start++];
} else {
tmpArr[tmpIndex++] = array[start2++];
}
}
while(start<=mid){
tmpArr[tmpIndex++] = array[start++];
}
while(start2<=end){
tmpArr[tmpIndex++] = array[start2++];
}
//重新写回 array
while(i<=end){
array[i] = tmpArr[i];
i++;
}
System.out.println(Arrays.toString(array));
}
【7】https://blog.csdn.net/qq_36390039/article/details/90181510
【非比较排序】https://blog.csdn.net/qq_36390039/article/details/90237966