冒泡排序
public class BubbleSort {
//最简洁的冒泡排序写法
//每次比较相邻的两个元素,如果后方元素比前方元素小,则进行交换
//每次循环确定一个最大的的元素,放在最后一位
//平均时间复杂度 N²
//空间复杂度 1
//稳定性 稳定
public static void main(String[] args) {
int[] number = {233, 666, 1, 6, 648, 328, 128, 999};
//冒泡排序算法,由小到大排序
for (int i = 0; i < number.length - 1; i++)
for (int j = 0; j < number.length - 1 - i; j++)
if (number[j] > number[j + 1]) {
int temp = number[j];
number[j] = number[j + 1];
number[j + 1] = temp;
}
for (int array : number)
System.out.print(array + " ");
}
}
选择排序
public class SelectionSort {
//选择排序
//不同于冒泡排序进行两两比较元素,然后交换!
//每次只找出最小数所在数组的索引,然后将其放在第一位
//每次比较只交换一次
//平均时间复杂度 N²
//空间复杂度 1
//稳定性 不稳定
public static void main(String[] args) {
int[] array = {233, 666, 1, 6, 648, 328, 128, 999};
for (int i = 0; i < array.length - 1; i++) {
//最小数在数组的索引
int minIndex = i;
for (int j = i; j < array.length; j++)
if (array[j] < array[minIndex])
minIndex = j;
//若minIndex值有变化,则进行交换,使得数组头的元素为最小的
if (minIndex != i) {
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
for (int sort : array)
System.out.print(sort + " ");
}
}
快速排序
public class Quicksort {
//快速排序
//将数组中的一个数当做基准数,然后从左右两边进行检索,检索到了则进行交换
//(如果将最左边的当做基准数,则先从右边检索,再从左边检索,反之亦然)
//传入的数组 最左边的索引,最右边的索引
public static void quickSort(int[] array,int left,int right){
//如果左边的索引比右边大,则是不合法的,必须结束该方法
//right可以大于left,可以等于left,但万万不能小于left!
if (left>right)
return;
//定义一个基准数,用以比较
int base = array[left];
//保存左右索引
int i = left;
int j = right;
//无法确定循环次数,所以选择while循环
//当 左右两个索引,同时指向一个元素时,停止循环,然后交换索引元素和 i or j指向的元素的值
while (i != j){
//已选择最左边的元素做基准数,则必须先从最右边开始找小于索引值的
while (array[j] >= base && i < j){
//进入循环的原因是没找到,所以索引向左移动
j--;
}//出循环则意味着找到了
//右边的找到了,再从左边开始向右找大于基准数的
while (array[i] <= base && i < j){
i++;
}
//如果程序走到这里,这已经找到了这两个数,进行交换
int temp = array[i];
array[i] = array[j];
array[j] = temp;
//交换完成
}
//如果跳出了这个循环,那么 i 和 j 的值一定相等了,则将 i or j 所指的元素与 基准数进行交换
//只是交换了索引所指向的值,但是索引本身并没有变化!
array[left] = array[i];
array[i] = base;
//进行递归,先排列基准数左侧的元素
quickSort(array,left,i-1);
//再排列右边的元素
quickSort(array,j+1,right);
}
public static void main(String[] args) {
int[] array = {23,6,99,1,52,88,34,999,666};
quickSort(array,0,array.length-1);
for (int a:array)
System.out.print(a+" ");
}
}
归并排序
public class MyMegreSort {
//归并排序
public static void sort(int[] array, int left, int right) {
//求中间元素的索引,int型会自动去除小数部分
if (left < right) {
int mid = (left + right) / 2;
//对左边的采用归并排序,使得左边有序
sort(array, left, mid);
//对右边的采用归并排序,使得右边有序
sort(array, mid + 1, right);
//前两个函数通过不断的递归,让分界线左边的子队列变得有序,再让分界线右边的子队列变得有序
//最后将两个有序的子队列进行一次普通的比较久可以
//mid的值动态变化,一定是(left+right)/2的值
megre(array, left, right, mid);
}
}
//合并两个子序列的自定义函数
// 传入的数组 最左索引 最右索引 分界线索引
public static void megre(int[] array, int left, int right, int mid) {
//对于已经分好的两个数组,设定两个指针,将这两个子序列当做队列一样处理
//每次比较后,移动指针
//创建一个暂存数组
//最左边的数组长度是right,但是有右边的数组传进来,rigth-left+1才能算出右边的长度
int[] temp = new int[right - left + 1];
//左队列指针
int i = left;
//右队列指针
int j = mid + 1;
//指向暂存数组的指针
int k = 0;
//开始实验吧
while (i <= mid && j <= right) {
if (array[i] < array[j])
temp[k++] = array[i++];
else
temp[k++] = array[j++];
}
//走出这个while循环,一定有一个子队列所有的元素都已放进temp数组,而另一个子队列还有残余
//但不知道是哪个子队列,所以对两边都执行一次
//左
while (i <= mid) {
temp[k++] = array[i++];
}
//右
while (j <= right) {
temp[k++] = array[j++];
}
//此时元素都已完美的按照从小到大放入了temp数组,使用temp数组覆盖原数组
//最左边的元素放入array中直接从索引0 开始,但是会有右边的数组放进来,如果从0开始就破坏了以前所排序的
for (int x = 0; x < temp.length; x++)
array[x + left] = temp[x];
}
public static void main(String[] args) {
int[] array = {9, 2, 6, 3, 5, 7};
sort(array, 0, array.length - 1);
for (int a : array)
System.out.print(a + " ");
}
}
堆排序
public class MyHeapSort {
//公式 带入第i个节点
//parent = (i-1)/2
//c1 = 2i+1
//c2 = 2i+2
public static void main(String[] args) {
int[] array = {23, 9, 85, 75, 32, 99, 574, 21, 23};
//对顶节点进行一次heapify所希望得到的结果
//85 9 23 75 32
for (int maxIndex = array.length - 1; maxIndex >= 0; maxIndex--) {
//求倒数第一个父节点
int parent = (maxIndex - 1) / 2;
for (int i = parent; i >= 0; i--) {
heapifyTest(array, i, maxIndex);
}
//574 75 99 23 32 23 85 21 9
int temp = array[0];
array[0] = array[maxIndex];
array[maxIndex] = temp;
}
for (int i : array)
System.out.print(i + " ");
}
//heapify
public static void heapifyTest(int[] array, int parent, int maxIndex) {
//max变量存放最大值的索引,假设parent节点的值最大,将索引保存至max
//parent = (length-1)/2;
int max = parent;
//利用公式算出左右孩子节点的索引值
int leftChild = 2 * parent + 1;
int rightChild = 2 * parent + 2;
if (leftChild <= maxIndex && array[leftChild] > array[max])
max = leftChild;
if (rightChild <= maxIndex && array[rightChild] > array[max])
max = rightChild;
//如果max所代表的的索引值和parent不一样了,才会进行交换
if (max != parent) {
int temp = array[parent];
array[parent] = array[max];
array[max] = temp;
}
}
}
来源:CSDN
作者:命运零点
链接:https://blog.csdn.net/qq_43742634/article/details/103810360