1、冒泡排序
/*冒泡排序:
1、比较相邻的元素,如果第一个比第二个大,则交换顺序;
2、对每一对相邻的元素作相同的工作,从开始第一对到结尾的最后一对,直至最大元素在数组末尾;
3、重复以上步骤,除了最后一个;
4、重复以上步骤。*/
import java.util.Scanner;
public class bubbleSort {
public static int[] sort(int[] array) {
if(array.length == 0) {
return array;
}
int temp = 0;
for(int i = 0; i < array.length; i ++) {
for(int j = 0; j < array.length - i - 1; j ++) {
if(array[j] > array[j + 1]) {
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
}
}
}
return array;
}
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n ; i ++) {
arr[i] = sc.nextInt();
}
for(int j = 0; j < n ; j ++) {
System.out.print(sort(arr)[j] + ",");
}
}
}
2、选择排序
package paixu;
/*选择排序:
1、从无序区中选择最小值,与无序区的第一个数字交换;
2、n-1趟结束后,数组有序化。*/
public class selectionSort {
public static int[] sort(int[] array) {
if(array.length == 0) {
return array;
}
for(int i = 0; i < array.length; i ++) {
int minIndex = i;
for(int j = i; j < array.length ; j ++) {
if(array[minIndex] > array[j]) {
int temp = array[minIndex];
array[minIndex] = array[j];
array[j] = temp;
}
}
}
return array;
}
public static void main(String args[]) {
int[] arr = new int[] {7,1,5,9,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr)[i] + ",");
}
}
}
3、插入排序
package paixu;
/*插入排序:
对于未排序数据,将已排序数据从后向前扫描,找到相应位置插入。
1、第一个元素,认为已被排序;
2、从第二个元素开始从后向前扫描,将比它大的元素向后移一个位置,直到遇到比自身数值小的元素,将元素排在其后面;
3、重复步骤2。*/
public class insertionSort {
public static int[] sort(int[] array) {
if(array.length == 0) {
return array;
}
for(int i = 0; i < array.length - 1; i ++) {
int preIndex = i;
int current = array[i + 1];
while(preIndex >= 0 && current < array[preIndex]) {
array[preIndex + 1] = array[preIndex];
preIndex --;
}
array[preIndex + 1] = current;
}
return array;
}
public static void main(String args[]) {
int[] arr = new int[] {7,1,5,6,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr)[i] + ",");
}
}
}
4、希尔排序
package paixu;
/*希尔排序:
特殊的插入排序,间隔依次为gap=len/2,gap=len/2/2,...*/
public class shellSort {
public static int[] sort(int[] array) {
if(array.length == 0) {
return array;
}
int len = array.length;
int gap = len / 2;
while(gap > 0) {
for(int i = 0; i < len - gap; i ++) {
int current = array[i + gap];
int preIndex = i;
while(preIndex >= 0 && array[preIndex] > current) {
array[preIndex + gap] = array[preIndex];
preIndex -= gap;
}
array[preIndex + gap] = current;
}
gap = gap >> 1;
}
return array;
}
public static void main(String[] args) {
int[] arr = new int[] {7,1,5,6,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr)[i] + ",");
}
}
}
5、归并排序
package paixu;
import java.util.Arrays;
/*归并排序:
将两个有序数组归并成一个有序数组
*/
public class mergeSort {
public static int[] sort(int[] array) {
if(array.length < 2) {
return array;
}
int mid = array.length / 2;
int[] left = Arrays.copyOfRange(array, 0, mid);
int[] right = Arrays.copyOfRange(array, mid, array.length);
return merge(sort(left),sort(right));
}
public static int[] merge(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
int i = 0;
int j = 0;
for(int index = 0; index < result.length; index ++) {
if(i >= left.length) {//将另一边多出来的数组放到result数组中
result[index] = right[j];
j ++;
}else if(j >= right.length){
result[index] = left[i];
i ++;
}else if(left[i] > right[j]) {//小的数字放到result数组中
result[index] = right[j];
j ++;
}else {
result[index] = left[i];
i ++;
}
}
return result;
}
public static void main(String[] args) {
int[] arr = new int[] {7,1,5,6,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr)[i] + ",");
}
}
}
6、快速排序
package paixu;
import java.util.Arrays;
/*快速排序:
冒泡排序的升级,都属于交换类排序
每一趟排序将待排序数列分为两部分,再分别对这两部分继续排序,直到数列有序。
1、从数列中挑出一个元素,作为基准值;
2、对数列进行排序,比基准值大的放在基准值的后面,比基准值大的放在基准值的前面;
3、递归的对左右子序列进行步骤2,直至各区间只有一个数。
*/
public class quickSort {
public static int[] sort(int[] array, int start, int end) {
if(array.length == 0 || start >= end) {
return array;
}
int pivot = array[start];// 取数组的第一个元素作为基准值
int left = start; //左标记
int right = end;//右标记
while(left < right) {
//从右向左扫描,直到遇到比基准值小的元素
while(left < right && array[right] > pivot) {
right --;
}
if(left < right) {
array[left] = array[right];//交换右扫描第一个比基准值小的数
left ++;//左标记右移一位
}
//从左向右扫描,直到遇到比基准值大的元素
while(left < right && array[left] < pivot) {
left ++;
}
if(left < right) {
array[right] = array[left];//交换左扫描第一个比基准值大的数
right --;//右标记左移一位
}
}
array[left] = pivot;//此时left为中间位置
sort(array, start, left - 1);//递归,左侧排序
sort(array, left + 1, end);//递归,右侧排序
return array;
}
public static void main(String[] args) {
int[] arr = new int[] {8,1,5,6,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr, 0 , arr.length - 1)[i] + ",");
}
}
}
7、堆排序
package paixu;
/*堆排序:
选择排序的改进
将待排序的序列构成一个大顶堆(每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆),
此时整个序列的最大值就是堆顶的根节点。
将它移走(其实就是将其与堆数组的末尾元素交换,此时末尾元素就是最大值),
然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素中的次最大值。
如此反复执行,就能得到一个有序序列了。
*/
public class heapSort {
public static int[] sort(int[] array) {
if(array.length == 0) {
return array;
}
// 将待排序的序列构建成一个大顶堆
for(int i = array.length / 2; i >= 0; i --) {
heapAdjust(array, i, array.length);
}
// 逐步将每个最大值的根节点与末尾元素交换,并且再调整二叉树,使其成为大顶堆
for(int i = array.length - 1; i > 0; i --) {
swap(array,0,i); //将堆顶记录和当前未经排序子序列的最后一个记录交换
heapAdjust(array, 0, i);//交换之后,需要重新检查堆是否符合大顶堆,不符合则要调整
}
return array;
}
//检查堆是否为大顶堆,若不符合则进行调整
public static void heapAdjust(int[] array, int i, int n) {
int child;
int father;
for(father = array[i]; leftChild(i) < n; i = child) {
child = leftChild(i);
//如果左子树小于右子树,则需要比较右子树和父节点
if(child != n -1 && array[child] < array[child + 1]) {
child ++;//序号增1,指向右子树
}
//如果父节点小于孩子结点,则需要交换
if(father < array[child]) {
array[i] = array[child];
}else {
break;//大顶堆结构未被破坏,不需要调整
}
}
array[i] = father;
}
//获取到左孩子结点
public static int leftChild(int i) {
return 2 * i + 1;
}
//交换元素位置
public static void swap(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
public static void main(String[] args) {
int[] arr = new int[] {8,1,5,6,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr)[i] + ",");
}
}
}
8、计数排序
package paixu;
/*计数排序:
1、找出待排序数组A中的最大值和最小值;
2、统计数组A中每个值为i的元素出现的次数,存入数组C中的第i项;
3、将C中的每个i位置的元素大小改成C数组前i项和;
4、初始化一个跟A同样大小的数组B,倒序遍历A中元素,通过查找C,将元素放到B相应位置中,
同时将C中对应的元素大小-1(表明已经放置了一个这样大小的元素,下次再放同样大小的元素,
就要往前挤一个位置)。
*/
public class countingSort {
public static int[] sort(int[] array, int k) {
if(array.length == 0) {
return array;
}
int sum = 0;
int[] B = new int[array.length];
int[] C = new int[k + 1];
for(int i = 0; i < array.length; i ++) {
C[array[i]] += 1;//统计数组A中个元素的个数,存入数组C中
}
for(int i = 0; i < k+1; i ++) {//修改数组C
sum += C[i];
C[i] = sum;
}
for(int i = array.length - 1; i >= 0; i--) {//遍历数组A,构造数组B
B[C[array[i]]- 1] = array[i];//将A中该元素放到排序后数组B中指定的位置
C[array[i]] --;//将C中该元素-1,方便存放下一个同样大小的元素
}
return B;
}
public static void main(String[] args) {
int[] arr = new int[] {8,1,5,6,3,2};
for(int i = 0; i < arr.length; i ++) {
System.out.print(sort(arr, 8)[i] + ",");
}
}
}
参考:
https://www.cnblogs.com/guoyaohua/p/8600214.html
https://segmentfault.com/a/1190000014105591
https://tryenough.com/arithmetic-quitsort
https://www.cnblogs.com/developerY/p/3166462.html
https://blog.csdn.net/zdp072/article/details/44227317