快速排序
快速排序的基本思想:
通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。
一趟排序的过程:
用例 test:{49,38,65,97,76,13,27}
在首位定两个指针 int l=0 , int r=7
选择一个 值作为枢纽。比枢纽小的放左边,大于等于枢纽的放右边
i r temp
49 38 65 97 76 13 27 49
从r指针开始找到比枢纽temp小的 27放左边
i r temp
27 38 65 97 76 13 27 49
从l指针开始找到比枢纽temp大的 65放右边
i r temp
27 38 65 97 76 13 65 49
从r指针开始找到比枢纽temp小的 13放左边
i r temp
27 38 13 97 76 13 65 49
从l指针开始找到比枢纽temp大的 97放右边
i r temp
27 38 13 97 76 97 65 49
从r指针开始找到比枢纽temp小的放左边 此次并不能找到符合条件的值
i r temp
27 38 13 97 76 97 65 49
一趟结束 左指针等于枢纽值返回枢纽坐在位置 i
i r temp
27 38 13 49 76 97 65 49
此时就达到了一部分记录的关键字均比另一部分关键字小的目的
快速排序代码
public void quick(int []array){
quickSort(array,0,array.length-1);
}
/**将整个数组排序相当于先把整个数组用quicksort排一遍
* 然后把数组的各个部分排一遍先是粒度大的然后粒度越来越细直到排序成功
*
* @param res
* @param s
* @param e
*/
private void quickSort(int [] res,int s,int e)
{
if(s>=e)//如果排序部分个数在2个以下就直接返回没必要排了
{
return;
}
int mid=getMiddle(res,s,e);//先排整个
quickSort(res,s,mid);//排左边
quickSort(res,mid+1,e);//排右边
}
private int getMiddle(int[] res, int s, int e) {
int temp=res[s];//枢纽
int left=s;//左指针
int right=e;//右指针
while(left<right)
{
while(left<right&&res[right]>=temp)//移动右指针找到一个比枢纽小的值
{
right--;
}
res[left]=res[right];//比枢纽小的移动到左边
while(left<right&&res[left]<temp)//移动左指针找到比枢纽大的值
{
left++;
}
res[right]=res[left];//比枢纽大的移动到右边
}
res[left]=temp;//把枢纽值放回去
return left;//返回枢纽位置
}
插入排序
原理假定前面n个元素有序将第n+1个元素在前n个元素中找到他的位置 这样从 1重复执行到n-1就能是数组有序
我们用数组arr来模拟这一趟的过程
index 0 1 2 3 4 5
value 38 49 65 97 100 50
现在要把这个数组用插入排序的思想排好
前5个值是有序的显然我们先用一个 变量记录 要插入前面有序数组的值 temp=50
从后往前遍历
指针 i
index 0 1 2 3 4 5 temp
value 38 49 65 97 100 70 70
arr[i-1]>temp 即arr[4]>temp 则将arr[4]后移
指针 i
index 0 1 2 3 4 5 temp
value 38 49 65 97 100 100 70
指针后移一位 arr[i-1]>temp 即arr[3]>temp 则将arr[3]后移
指针 i
index 0 1 2 3 4 5 temp
value 38 49 65 97 97 100 70
指针后移一位 arr[i-1]<temp 此时arr[2]<temp此时找到temp插入位置 则将temp移动到arr[3]位置
指针 i
index 0 1 2 3 4 5 temp
value 38 49 65 70 97 100 70
具体代码实现
public void directInsertSort(int []array){
int temp;
for(int i=1;i<array.length;i++)//从第1个位置开始往前插入数字
{
temp=array[i];//当前待插入数字
for(int j=i;j>0;j-- )//从后往前遍历有序数组找到插入位置
{
if(array[j-1]>=temp)//如果先一个数字比待插入数字大则把前一个数字移动到当前位置
{
array[j]=array[j-1];
}
else//如果前一个数字小于待插入数字则该位置为可插入位置
{
array[j]=temp;
break;
}
}
}
选择排序
基本思想:
第一趟比较找出1-n最小数字排第一位;
第二趟比较找出2-n最小数字排第二位;
重复执行最后数组排序完成
public void simpleSelectSort(int []array)
{
int min;
int index=0;
for(int i=0;i<array.length-1;i++)
{
min=array[i];
for(int j=i;j<array.length;j++)
{
if(array[j]<min)
{
min=array[j];
index=j;
}
}
swap(array,i,index);
}
}
冒泡排序:
public void bubSwapSort(int []array)
{
for(int i=0;i<array.length;i++)
{
for(int j=i;j<array.length-i-1;j++)
{
if(array[j]>array[j+1])
{
swap(array,j,j+1);
}
}
}
}
归并 归并
桶排序 桶排
基数排序
原理 测试数字 test{12,13,32,2,100}
创建 0,1,2,3四个桶 最大数字100的位数为3 所以要排三次
第一次比较个位 个位数字的值即为应放入桶的编号
桶0 桶1 桶2 桶3
100 12 13
32
2
把桶中的数字依次拿出来放回test
test{100,12,32,2,13}
第二次比较十位 十位数字的值即为应放入桶的编号
桶0 桶1 桶2 桶3
100 12 32
2 13
把桶中的数字依次拿出来放回test
test{100,2,12,13,32}
第三次比较百位 百位数字的值即为应放入桶的编号
桶0 桶1 桶2 桶3
2 100
12
13
32
把桶中的数字依次拿出来放回test
test{2,12,13,32,100} 排序完毕
代码实现
public void BasicSort(int[] array)
{
ArrayList<ArrayList<Integer>> bult = new ArrayList<>();
//初始化10个桶0-9
for(int i=0;i<=9;i++)
{
bult.add(new ArrayList<Integer>());
}
int max=array[0];//找到最大值
for(int i=0;i<array.length;i++)
{
if(array[i]>max)
{
max=array[i];
}
}
int times=0;//因为是从低位排到高位最大值位数决定了要排几次
while(max>0)
{
max/=10;
times++;
}
for(int i=0;i<times;i++)//最大数字的位数决定了要排几次
{
for(int j=0;j<array.length;j++)
{
int index= (array[j]%(int)Math.pow(10, i+1))/(int)Math.pow(10, i);//娶得对应位数的数字即为此时排序的桶位置
bult.get(index).add(array[j]);//把数字加到此次排序对应的桶中
}
//把桶中排好的数字放回数组
int count=0;
for(ArrayList<Integer> list:bult)
{
while(!list.isEmpty())
{
array[count++]=list.remove(0);
}
}
}//for
}
参考资料:https://www.cnblogs.com/Kevin-mao/p/5903234.html
https://www.cnblogs.com/hapjin/p/5517667.html
https://www.jianshu.com/p/8c915179fd02