Java常⽤的⼋种排序算法与代码实现⽬录
1.直接插⼊排序
2.希尔排序
3.简单选择排序
4.堆排序
5.冒泡排序
6.快速排序
7.归并排序
8.基数排序
1.直接插⼊排序
经常碰到这样⼀类排序问题:把新的数据插⼊到已经排好的数据列中。
将第⼀个数和第⼆个数排序,然后构成⼀个有序序列
将第三个数插⼊进去,构成⼀个新的有序序列。
对第四个数、第五个数……直到最后⼀个数,重复第⼆步。
如何写写成代码:
⾸先设定插⼊次数,即循环次数,for(int i=1;i<length;i++),1个数的那次不⽤插⼊。
设定插⼊数和得到已经排好序列的最后⼀个数的位数。insertNum和j=i-1。
从最后⼀个数开始向前循环,如果插⼊数⼩于当前数,就将当前数向后移动⼀位。
将当前数放置到空着的位置,即j+1。
代码实现如下:
public void insertSort(int[] a){
int length=a.length;//数组长度,将这个提取出来是为了提⾼速度。
int insertNum;//要插⼊的数
for(int i=1;i<length;i++){//插⼊的次数
insertNum=a[i];//要插⼊的数
int j=i-1;//已经排序好的序列元素个数
while(j>=0&&a[j]>insertNum){//序列从后到前循环,将⼤于insertNum的数向后移动⼀格
a[j+1]=a[j];//元素移动⼀格
j--;
}
a[j+1]=insertNum;//将需要插⼊的数放在要插⼊的位置。
}
}
2.希尔排序
对于直接插⼊排序问题,数据量巨⼤时。
将数的个数设为n,取奇数k=n/2,将下标差值为k的书分为⼀组,构成有序序列。
再取k=k/2 ,将下标差值为k的书分为⼀组,构成有序序列。
重复第⼆步,直到k=1执⾏简单插⼊排序。
如何写成代码:
⾸先确定分的组数。
然后对组中元素进⾏插⼊排序。
然后将length/2,重复1,2步,直到length=0为⽌。
代码实现如下:
public  void sheelSort(int[] a){
int d  = a.length;
while (d!=0) {
d=d/2;
for (int x = 0; x < d; x++) {//分的组数
for (int i = x + d; i < a.length; i += d) {//组中的元素,从第⼆个数开始
int j = i - d;//j为有序序列最后⼀位的位数
int temp = a[i];//要插⼊的元素
for (; j >= 0 && temp < a[j]; j -= d) {//从后往前遍历。
a[j + d] = a[j];//向后移动d位
}
a[j + d] = temp;
}
}
}
}
3.简单选择排序
常⽤于取序列中最⼤最⼩的⼏个数时。
(如果每次⽐较都交换,那么就是交换排序;如果每次⽐较完⼀个循环再交换,就是简单选择排序。)
遍历整个序列,将最⼩的数放在最前⾯。
遍历剩下的序列,将最⼩的数放在最前⾯。
重复第⼆步,直到只剩下⼀个数。
如何写成代码:
⾸先确定循环次数,并且记住当前数字和当前位置。
将当前位置后⾯所有的数与当前数字进⾏对⽐,⼩数赋值给key,并记住⼩数的位置。
⽐对完成后,将最⼩的值与第⼀个数的值交换。
重复2、3步。
代码实现如下:
public void selectSort(int[] a) {
int length = a.length;
for (int i = 0; i < length; i++) {//循环次数
int key = a[i];
int position=i;
for (int j = i + 1; j < length; j++) {//选出最⼩的值和位置
if (a[j] < key) {
key = a[j];
position = j;
}
}
a[position]=a[i];//交换位置
a[i]=key;
}
}
4.堆排序
对简单选择排序的优化。
将序列构建成⼤顶堆。
将根节点与最后⼀个节点交换,然后断开最后⼀个节点。
重复第⼀、⼆步,直到所有节点断开。
代码实现如下:
public  void heapSort(int[] a){
System.out.println("开始排序");
int arrayLength=a.length;
//循环建堆
for(int i=0;i<arrayLength-1;i++){
//建堆
冒泡排序java代码详解buildMaxHeap(a,arrayLength-1-i);
//交换堆顶和最后⼀个元素
swap(a,0,arrayLength-1-i);
System.out.String(a));
}
}
private  void swap(int[] data, int i, int j) {
int tmp=data[i];
data[i]=data[j];
data[j]=tmp;
}
//对data数组从0到lastIndex建⼤顶堆
private void buildMaxHeap(int[] data, int lastIndex) {
//从lastIndex处节点(最后⼀个节点)的⽗节点开始
for(int i=(lastIndex-1)/2;i>=0;i--){
/
/k保存正在判断的节点
int k=i;
//如果当前k节点的⼦节点存在
while(k*2+1<=lastIndex){
//k节点的左⼦节点的索引
int biggerIndex=2*k+1;
//如果biggerIndex⼩于lastIndex,即biggerIndex+1代表的k节点的右⼦节点存在
if(biggerIndex<lastIndex){
//若果右⼦节点的值较⼤
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex总是记录较⼤⼦节点的索引
biggerIndex++;
}
}
//如果k节点的值⼩于其较⼤的⼦节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下⼀次循环,重新保证k节点的值⼤于其左右⼦节点的值                    k=biggerIndex;
}else{
break;
}
}
}
}
5.冒泡排序
⼀般不⽤。
将序列中所有元素两两⽐较,将最⼤的放在最后⾯。
将剩余序列中所有元素两两⽐较,将最⼤的放在最后⾯。
重复第⼆步,直到只剩下⼀个数。