八大排序

 

直接插入排序:

排序思想:先假定前面有序,从第二个开始,将后面的所有数据插入到有序数组中去。

算法思想如果大时就交换:

public void insertSort(int[] a){

    int temp = 0;

    for(int i=1;i<a.length;i++){

        temp = a[i];

        for(int j=i-1;j>-1&&temp<a[j];j--){

        //大的时候往后排,找插入位置

        a[j+1]=a[j];

    }

    a[j+1]=temp;
}

希尔排序:是高级的直接插入排序

排序思想:

按步长grap(grap>1)进行分组,每组采用直接插入排序,步长不断缩小每次除2,先分组在排序

 

public void shellSort(int[] a){

//定义步长

int grap = a.length/2;

//定义中间变量

while(grap>1){

//分组,按照grap间隔进行分组

for(int i=grap;i<a.length;i++){

int temp = a[i];

for(int j = i-grap;j>-1&&temp<a[j];j=j-grap){

a[j+grap]=a[j];

}

//插入的位置

a[j+grap] = temp;

}

grap = grap /2;

}

}

简单选择排序:

排序思想:每次从待排序列中选择最小的放在最下的

 

public void selectSort(int[] a){

int temp = 0;

for(int i=0;i<a.length-1;i++){

for(int j=i+1;j<a.length;j++){

if(a[j]<a[i]){

temp = a[i];

a[i]=a[j];

a[j]=temp;

}

}

}

}

//下标标识,交换内存比较浪费资源

public void selectSort(int[] a){

int temp = 0;

int kmin = 0;

for(int i=0;i<a.length-1;i++){

kmin = i;

for(int j=i+1;j<a.length;j++){

if(a[j]<a[kmin]){

kmin = j;

}

//如果没有小的就不交换

if(i-kmin){

temp = a[kmin];

a[kmin] = a[i];

a[i] = temp;

}

}

}

}

堆排序:

思想:先把数据存入数组当中去,从1开始存,调整成堆,每次把最大的交换到最上面,然后和end所在位置交换,end--,在进行排序。

 

public void heapSort(int a[]){

//end:用于标识最后一个位置,pa用于标识end的父亲,t用于交换end和第一个,tag标识是否交换了,如果未交换就表示不需要调整了

int end,pa,t,tag;

//end指向最后一个

end = a.length;

while(end>1){

//调整成堆,默认调整,如果未调整就break,表示上面是最小的

while(1){

// pa要大于0

for(pa=end/2,tag=0;pa>0;pa--){

//比较左子女

if(a[pa]<a[pa*2]){

t = a[pa];

a[pa] = a[pa*2];

a[pa*2] = t;

tag = 1;

}

//比较右子女

if(pa*2+1<end&&a[pa]<a[pa*2+1]){

t = a[pa];

a[pa] = a[pa*2+1];

a[pa*2+1] = t;

tag = 1;

}

}

if(tag==0) break;

}

t = a[1];

a[1] = a[end];

a[end] = t;

//去掉最后一个页子

end -- ;

}

 

}

交换类排序:

冒泡排序:

第一个循环控制趟数,第二个循环比较排序

 

public void bubbleSort(int[] nums){

int temp = 0;

for(int i=0;i<nums.length-1;i++){

for(int j=0;j<nums.length-1-i;j++){

if(nums[j]>nums[j+1]){

temp = nums[j];

nums[j] = nums[j+1];

nums[j+1] = temp;

}

}

}

}

 

快速排序:

 

package Sort;

 

 

public class SortUtils {

 

/**

* 快速排序

* 分为三个步骤:找基准点,***切记从右往左先跑,找小于基准点的停,从左往右找大于基准点的停

* 左递归,右递归

* @param arr 待排序的数组

* @param left 左位置

* @param right 右位置

*/

public static void quickSort(int[] arr,int left,int right){

//如果left小于right,那么循环结束

if(left>=right){

return;

}

// 取最左面的作为基准点

int p = arr[left];

// 初始化i,j的位置

int i=left,j=right;

// 目的是把比p小的放在p前面,把比p大的放在p后面

 

//当前面的小于后面时

while(i<j){

// 从后面找小的

while(arr[j]>=p&&i<j){

j--;

}

// 从前边找大的,左移找大的

while(arr[i]<=p&&i<j){

i++;

}

 

// 如果i<j时,那么就进行交换

if(i<j){

int temp = arr[i];

arr[i]=arr[j];

arr[j]=temp;

}

}

// 交换位置

arr[left] = arr[i];

arr[i]=p;

// 进行递归左面排序

quickSort(arr,left,i-1);

// 进行递归右面排序

quickSort(arr,i+1,right);

}

 

 

/**

* @Author:LiuRuidong

* @Description: 归并排序,应用的是分治算法

* @Date:2018/2/27 15:31

* @Param:

* @return

*/

public static void mergeSort(int[] arr){

int[] temp = new int[arr.length];

mSort(arr,0,arr.length-1,temp);

}

private static void mSort(int[] arr,int left,int right,int[] temp ){

if(left<right){

// 分开

int mid = (left+right)/2;

// 左边进行排序

mSort(arr,left,mid,temp);

// 右边进行排序

mSort(arr,mid+1,right,temp);

// 治合

merge(arr,left,right,mid,temp);

}

}

private static void merge(int[] arr,int left,int right,int mid,int[] temp){

int i = left;

int j = mid+1;

int t = 0;

// i往mid跑,j往right跑

while(i<=mid&&j<=right){

if (arr[i]<=arr[j]){

temp[t++] = arr[i++];

}else{

temp[t++] = arr[j++];

}

}

while(i<=mid){

temp[t++] = arr[i++];

}

while(j<=right){

temp[t++] = arr[j++];

}

// 拷贝到另一个队列当中

t = 0;

while(left<=right){

arr[left++]=temp[t++];

}

}

}

时间复杂度计算:

遍历一遍是O(n),堆排序算法思想是建堆,见一次比较log(n)次,树的高度次,然后需要建(n-2)/2次,所以为nlogn

对于快排也是类似的思想,递归的时间复杂度:递归层数*log(n),最坏每次最大的最后面,o(n2)

快排的优化:查找中位数,当递归一定层数时采用 插入排序

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值