package suanfa;
/**
* @author lackiechan
*
*/
public class Sort {
/**
* 插入排序 稳定性:稳定 时间复杂度(n2)
* 1、直接插入排序法
* 算法思想:1、把n个要排序的数组看成一个含有1个已排序有序表和一个含有n-1个未排序的元素的无序表
* 2、从无序表中取出第i(取n-1次)个元素,将它和有序表中的元素进行比较
* 3、把该元素查到已排序的序列表中形成新的有序表
* 4、重复n-1次即可完成插入排序
* 假如把直接插入排序应用于链表存储结构不用移动元素,而是修改指针
* 插入排序是稳定 即:插入相等的值是插入有序表的后面 没有改变原来的排序
* @param arr 这是传入的数组
* @return int[] 返回排好序的数组
*/
public static int[] insertSort(int... array){ //直接插入排序
int temp;//第i趟拿出来比较的数
int j;//内循环
for(int i=1;i<array.length;i++){//取(数组长度-1)趟
temp=array[i];//把取出的元素作为和有序表比较,temp为取出来的元素
for(j=i;j>0&&temp<array[j-1];j--){//j为内循环的参考值 for循环也可以用j=i; while(j>0&&temp<array[j-1]) {array[j]=array[j-1];; j--;}代替
array[j]=array[j-1];//元素右移动一位
}
array[j]=temp;//把该元素插到指定的位置
}
return array;
}
/**折半排序:是直接插法的改进
* 在理解直接插入排序的前提下:
* 把有序表进行折半和无序表中拿出的元素比较 提高查找效率
* @param array
* @return
*/
public static int[] halfInsertSort(int... array){
int temp;//第i趟拿出来比较的数 哨兵
for(int i=1;i<array.length;i++){
temp=array[i];
int low=0;
int high=i-1;
while(low<=high){
int middle=(low+high)/2;
if(temp<array[middle]){
high=middle-1;
}
else low=middle+1;
}
for(int j=i;j>high+1;j--){ //把要插入位置和它后面的元素全部后移一位 然后把元素插到该位置
array[j]=array[j-1];//后移动一位
}
array[high+1]=temp;//high+1为要插入的位置
}
return array;
}
/**
* 希尔排序 稳定性:不稳定 时间复杂度O(nlogn)
* 希尔排序也是一种插入排序方法,实际上是一种分组插入方法
* 先取一个小于n的整数d1作为一个增量,把表的全部记录分成d1个组,所有
* 距离为d1的倍数的记录放在同一个组中,在各组内进行直接插入排序,然后
* ,取第二个增量d2(<d1),重复上述的分组和排序,直至所取的dt=1,即所有
* 记录放在同一组中进行直接插入排序为止
*/
public static int[] shellSort(int... array){
int gap = array.length/2;
int temp;
while(gap>0){
for(int i=gap;i<array.length;i++){
temp = array[i];
int j = i - gap;
while(j>=0 && temp < array[j]){
array[j+gap] = array[j];
j = j - gap;
}
array[j+gap] = temp;
}
gap = gap/2;
}
return array;
}
/**
* 冒泡排序 稳定性:稳定 时间复杂度O(n2)
* 冒泡排序
* 算法思想:每排一趟大的沉下去 第i趟大第i大的沉下来
* @param array
* @return
*/
public static int[] bubbleSort(int... array){
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++){
if(array[j]>array[j+1]){
int temp=array[j+1];
array[j+1]=array[j];
array[j]=temp;
}
}
}
return array;
}
/**返回快速排序 区轴的位置
* @param low
* @param high
* @param array
* @return
*/
public static int quickSortLocation(int low,int high,int... array){
int pivotkey=array[low];
while(low<high){
while(low<high&&array[high]>=pivotkey) high--;//当高位指针的值比参考元素的值大时 指针向左移动一位(即向左扫描)
array[low]=array[high];//当高位指针的值比参考元素的值小时,把高位指针的值移到low位
while(low<high&&array[low]<=pivotkey)low++;//当低位指针的值比参考元素的值小时 指针向右移动一位(即向右扫描)
array[high]=array[low];//当低位指针的值比参考元素的值大时,把低位指针的值移到high位
}
array[low]=pivotkey;
return low;
}
/**
* 快速排序 稳定性:不稳定 时间复杂度O(nlogn)
* 算法思想: 在R[low..high]中任选一个记录作为基准(Pivot),
* 以此基准将当前无序区划分为左、右两个较小的子区间R[low..pivotpos-1)和R[pivotpos+1..high],
* 并使左边子区间中所有记录的关键字均小于等于基准记录(不妨记为pivot)的关键字pivot.key,
* 右边的子区间中所有记录的关键字均大于等于pivot.key,而基准记录pivot则位于正确的位置(pivotpos)上,它无须参加后续的排序。
* @param low
* @param high
* @param array
* @return
*/
public static int[] quickSort(int low,int high,int... array){
if(low<high){
int pivotLoc=quickSortLocation(low,high,array);
quickSort(pivotLoc+1,high,array);
quickSort(low,pivotLoc-1,array);
}
return array;
}
/**
* 选择排序稳定性: 不稳定 时间复杂度O(n2)
* 选择排序
* 算法思想:在每第i趟在n-i+1个记录中选出最小值作为有序序列的第i个记录
* (和简单插入排序有点像左边是有序表 不过选择插入是将无序表中最小值直接插到有序表的最后位置)
* @param array
* @return
*/
public static int[] selectSort(int... array){
for(int i=0;i<array.length-1;i++){//需选择n-1趟
for(int j=i+1;j<array.length;j++){
if(array[i]>array[j]){
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
}
}
return array;
}
/**调整堆为大顶堆
* @param array
* @param index
* @param last
*/
public static void heapAdjust(int[] array,int index,int last){//树的根节点记为1 所以数组的第一个数array[0] 没有参加排序
int temp=array[index];
for(int j=2*index;j<=last;j*=2){//
if(j<last&&array[j]<array[j+1]) ++j;//左右右子树比较 若右子树大则j加1 这个作用主要是 想默认array[j]大 方便和index的值比较
if(temp>array[j])break;//若temp大则跳出循环把他插入index
array[index]=array[j];//大的值替换到index位置
index=j;
}
array[index]=temp;
}
/**
* 堆排序稳定性 不稳定 时间复杂度O(nlogn)
* 堆排序
* @param array
* @return
*/
public static int[] heapSort(int... array){
for(int i=(array.length-1)/2;i>0;--i)
heapAdjust(array,i,array.length-1);
for(int i=array.length-1;i>1;--i){
int temp=array[i];//最后一个记录相互交换
array[i]=array[1];
array[1]=temp;
heapAdjust(array,1,i-1);//重新调整为大顶堆
}
return array;
}
/**归并排序
* @param array
* @return
*/
public static int[] megreSort(int... array){
return array;
}
}
java冒泡排序、插入排序、快速排序、选择排序、堆排序
最新推荐文章于 2021-02-28 14:45:39 发布