冒泡排序
//定义一个数组
int[] arr = new int[]{8,5,7,6,1,3,9,4};
//共比较多少轮
for (int i = 0; i < arr.length-1; i++) {
//一轮比较多少次
for (int j = 0; j < arr.length-1-i; j++) {
//如果前面的大于后面的,那么前后交换
if (arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
快速排序
/**
*
* @param arr:传入的参数数组
* @param start:排序区间开始的下标
* @param end:排序区间结束的下标
*/
public static void quickSort(int[] arr,int start,int end){
//如果开始下标没有与结束下标重合,则一直循环
if (start < end){
//将当前排序区间的第一个数作为比较的标准数
int stard = arr[start];
//记录排序需要的下标
int low = start;
int high = end;
//如果开始坐标小于结束坐标,则开始循环
while (low<high){
//如果开始坐标小于结束坐标并且右边的数大于左边的标准数
while (low<high&&stard<=arr[high]){
//结尾坐标向前挪一位
high--;
}
//右边结束坐标的数替换掉左边开始坐标的数
arr[low] = arr[high];
//如果开始坐标小于结束坐标并且左边的数小于标准数
while (low<high&&arr[low]<=stard){
//左边数的下标向前挪一位
low++;
}
//左边开始坐标的数替换掉右边结束坐标的数
arr[high] = arr[low];
}
//当循环结束,即两坐标重叠时,将比较的标准数赋给当前坐标的值
arr[low] = stard;
//重新开始比较标准数左边的区间
quickSort(arr,start,low);
//重新开始比较标准数右边的区间
quickSort(arr,low+1,end);
}
}
插入排序
public static void insertSort(int[] arr){
int temp;
int j = 0;
//从第二个遍历整个数组
for (int i = 1; i < arr.length; i++) {
//如果当前数比前一个数小
if (arr[i]<arr[i-1]){
//把当前数存起来
temp = arr[i];
//遍历当前数之前的所有的数
for (j = i-1; j >=0&&temp<arr[j] ; j--) {
//如果遍历到的数大于temp,则向后挪一位
arr[j+1] = arr[j];
}
//当前的数小于等于temp,则把temp赋值给他后一位数
arr[j+1] = temp;
}
}
}
希尔排序
public static void shellSort(int[] arr){
//遍历所有的步长
for (int d = arr.length/2; d >0 ; d/=2) {
//遍历每一组中的第一个元素,与同一组的元素进行比较
for (int i = d; i < arr.length; i++) {
//遍历本组中的所有元素
for (int j = i-d; j >=0 ; j-=d) {
if (arr[j]>arr[j+d]){
int temp = arr[j];
arr[j] = arr[j+d];
arr[j+d] = temp;
}
}
}
}
}
选择排序
public static void chooseSort(int[] arr){
//遍历所有的数
for (int i = 0; i <arr.length ; i++) {
int minIndex = i;
//把当前的数与之后所有的数全都比较一遍。并记录下最小的数的下标
for (int j = i+1; j <arr.length ; j++) {
if (arr[j]<arr[minIndex]){
minIndex = j;
}
}
//将最小的数与当前遍历的数交换
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
归并排序
public static void MergeSort(int[] arr,int start,int end){
//取出中间下标
int middel = (start+end)/2;
//只要开始下标小于结束下标,就会一直递归
if (start<end){
//处理左边的数组
MergeSort(arr,0,middel);
//处理右边的数组
MergeSort(arr,middel+1,end);
//归并排序
merge(arr,0,middel,end);
}
}
public static void merge(int[] arr,int low,int middel,int high){
//用于储存归并后的临时数组
int[] temp = new int[high-low+1];
//记录第一个数组中需要遍历的下标
int i = low;
//记录第二个数组中需要遍历的下标
int j = middel+1;
//用于记录在临时数组中存放的下标
int index = 0;
//遍历两个数组中取出较小的数字,存放到新数组中
while (i<=middel&&j<=high){
//第一个数组的数字更小
if (arr[i]<=arr[j]){
temp[index] = arr[i];
//下标后移一位
i++;
//第二个数组的数字更小
}else {
temp[index] = arr[j];
j++;
}
index++;
}
//处理多余的数据
while (j<=high){
temp[index]=arr[j];
j++;
index++;
}
while (i<=middel){
temp[index]=arr[i];
i++;
index++;
}
//把临时数组中的数据重新存入原数组
for (int k = 0; k < temp.length; k++) {
arr[k+low] = temp[k];
}
}
基数排序
/**
* 采用数组形式
*/
public static void radixSort(int[] arr){
//定义一个最小值变量。Integer.MIN_VALUE:整形数中的最小值:-2147483648
int max = Integer.MIN_VALUE;
//遍历找出数组中最大值
for (int i = 0; i < arr.length; i++) {
if (arr[i]>max){
max = arr[i];
}
}
//计算最大数组是几位数
int maxLength = (max+"").length();
//定义一个临时存储数据的二维数组
int[][] temp = new int[10][arr.length];
//用于记录temp相对数组中数据的数量
int[] count = new int[10];
//根据最大长度决定比较次数,即最大数是几位数,则比较几次
for (int i = 0,n=1; i < maxLength; i++,n*=10) {
//把每一个数字分别计算余数,按余数分组
for (int j = 0; j < arr.length; j++) {
//计算余数
int ys = arr[j]/n%10;
//把当前遍历的数据放入指定的数组中
temp[ys][count[ys]] = arr[j];
//当前数组数据数量+1
count[ys]++;
}
//记录取的元素需要放的位置
int index = 0;
//再把分完组的数据重新放回原数组中
for (int k = 0; k <count.length ; k++) {
//判断当前分组是否为0
if (count[k]!=0)
//若不为0,则遍历取出当前分组的数据
for (int l = 0; l < count[k]; l++) {
//原数组从0开始,临时数组从有数据的分组开始
arr[index] = temp[k][l];
//原数组下标+1
index++;
}
//取完后把count数组清空以便记录下一次便利分组
count[k] = 0;
}
}
}
/**
* 采用队列形式
*/
public static void radixSort_for_queue(int[] arr){
//定义一个最小值变量。Integer.MIN_VALUE:整形数中的最小值:-2147483648
int max = Integer.MIN_VALUE;
//遍历找出数组中最大值
for (int i = 0; i < arr.length; i++) {
if (arr[i]>max){
max = arr[i];
}
}
//计算最大数组是几位数
int maxLength = (max+"").length();
//定义一个临时存储数据的队列的数组(即创建10个队列)
QueueUtil[] temp = new QueueUtil[10];
//为每一组队列赋值
for (int i = 0; i < temp.length; i++) {
temp[i] = new QueueUtil();
}
//根据最大长度决定比较次数,即最大数是几位数,则比较几次
for (int i = 0,n=1; i < maxLength; i++,n*=10) {
//把每一个数字分别计算余数,按余数分组
for (int j = 0; j < arr.length; j++) {
//计算余数
int ys = arr[j]/n%10;
//把当前遍历的数据放入指定的队列中
temp[ys].add(arr[j]);
}
//记录取的元素需要放的位置
int index = 0;
//再把分完组的数据重新放回原数组中
for (int k = 0; k <temp.length ; k++) {
//判断当前分组是否为0
while (!temp[k].isEmpty()){
//原数组从0开始,队列从有数据的开始
arr[index] = temp[k].pop();
//原数组下标+1
index++;
}
}
}
}
堆排序
/**
* 升序用大顶堆
* 降序用小顶堆
* */
public static void heapSort(int[] arr){
int start = (arr.length-1)/2;
//调整为大顶堆
for (int i = start; i >=0; i--) {
maxHeap(arr,arr.length,i);
}
//先把数组中前后交换,然后再把前面的处理成大顶堆
for (int i = arr.length-1; i >0 ; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
maxHeap(arr,i,0);
}
}
/**
* @param arr:传递的数组
* @param size:排序的范围
* @param index:初始父节点
*/
public static void maxHeap(int[] arr,int size,int index){
//左子结点
int leftNode = 2*index+1;
//右子结点
int rightNode = 2*index+2;
//父节点
int max = index;
//与两个子结点对比,找出最大节点
if (leftNode<size&&arr[leftNode]>arr[max]){
//如果左子结点大于父节点,那么二者交换
max = leftNode;
}
if (rightNode<size&&arr[rightNode]>arr[max]){
//如果右子结点大于父节点,那么二者交换
max = rightNode;
}
//交换位置
if (max != index){
int temp = arr[index];
arr[index] = arr[max];
arr[max] = temp;
maxHeap(arr,size,max);
}
//交换位置后,可能破坏之前排好的堆,所以需要重新调整之前排好的堆
}