java十大排序的实现和(时间、空间)复杂度的横向对比
文章目录
一、java十大排序的实现
冒泡排序
private static int[] bobbleSort(int[] arr){
int temp = 0;
boolean falg = false;
for (int i=0;i<arr.length-1;i++){
for (int k=0;k<arr.length-1-i;k++) {
if (arr[k] > arr[k + 1]) {
falg = true;
temp = arr[k];
arr[k] = arr[k + 1];
arr[k + 1] = temp;
}
}
if (!falg){
break;
}else {
falg = false;
}
}
return arr;
}
选择排序
private static void selectSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++) {
int min = arr[i];
int j=i;
for (int k=i+1;k<arr.length;k++){
if (arr[k]<min){
min = arr[k];
j = k;
}
}
if (i!=j) {
arr[j] = arr[i];
arr[i] = min;
}
}
}
插入排序
private static void insertSort2(int[] arr){
for (int i = 1; i < arr.length; i++) {
int insertVal = arr[i];
int insertIndex = i-1;
while (insertIndex>=0&&arr[insertIndex]>insertVal){
arr[insertIndex+1] = arr[insertIndex];
insertIndex--;
}
arr[insertIndex+1] = insertVal;
}
}
希尔排序
private static void shellSort2(int[] arr) {
for (int gap = arr.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < arr.length; i++) {
int index = i - gap;
int temp = arr[i];
while (index >= 0 && arr[index] > temp) {
arr[index + gap] = arr[index];
index -= gap;
}
arr[index + gap] = temp;
}
}
}
归并排序
public static void fenAndMerge(int[] arr,int left,int right,int[] temp){
if (left<right){
int mid = (left+right)/2;
//向左递归 拆分
fenAndMerge(arr,left,mid,temp);
//向右递归 拆分
fenAndMerge(arr,mid+1,right,temp);
//合并
merge(arr,left,mid,right,temp); //见下方merge()方法
}
}
/**
*
* @param arr 需要归并的数组
* @param left 数组的左边索引
* @param mid 数组的中间索引
* @param right 数组的右边索引
* @param temp 中间数组
*/
public static void merge(int[] arr,int left,int mid,int right,int[] temp){
int t = 0;
int j = mid+1;
int i = left;
//比较mid左右两边数据 按大小顺序放入temp中
//1.mid两边都有数据 就一直比较
while (i<=mid&&j<=right){
if (arr[i]<=arr[j]){
temp[t] = arr[i];
i+=1;
t+=1;
}else {
temp[t] = arr[j];
j+=1;
t+=1;
}
}
//2.如果只剩下一边有数据,将数据依次加入到temp中
while (i<=mid){
temp[t] = arr[i];
t+=1;
i+=1;
}
while (j<=right){
temp[t] = arr[j];
t+=1;
j+=1;
}
//3.arr数组中索引是固定的,只是逻辑上拆分,需要将排列后的数组中数据返回指定的位置。
t =0;
int tempLeft = left;
while (tempLeft<=right){
arr[tempLeft]=temp[t];
t+=1;
tempLeft+=1;
}
}
快速排序
public static int[] QuickSort(int[] array, int start, int end) {
if (array.length < 1 || start < 0 || end >= array.length || start > end) return null;
int smallIndex = partition(array, start, end);
if (smallIndex > start)
QuickSort(array, start, smallIndex - 1);
if (smallIndex < end)
QuickSort(array, smallIndex + 1, end);
return array;
}
public static int partition(int[] array, int start, int end) {
int pivot = (int) (start + Math.random() * (end - start + 1));
int smallIndex = start - 1;
swap(array, pivot, end);
for (int i = start; i <= end; i++)
if (array[i] <= array[end]) {
smallIndex++;
if (i > smallIndex)
swap(array, i, smallIndex);
}
return smallIndex;
}
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
堆排序
static int len;
public static int[] HeapSort(int[] array) {
len = array.length;
if (len < 1) return array;
buildMaxHeap(array);
while (len > 0) {
swap(array, 0, len - 1);
len--;
adjustHeap(array, 0);
}
return array;
}
public static void buildMaxHeap(int[] array) {
for (int i = (len/2- 1); i >= 0; i--) {
adjustHeap(array, i);
}
}
public static void adjustHeap(int[] array, int i) {
int maxIndex = i;
if (i * 2 < len && array[i * 2] > array[maxIndex])
maxIndex = i * 2;
if (i * 2 + 1 < len && array[i * 2 + 1] > array[maxIndex])
maxIndex = i * 2 + 1;
if (maxIndex != i) {
swap(array, maxIndex, i);
adjustHeap(array, maxIndex);
}
}
计数排序
public static int[] CountingSort(int[] array) {
if (array.length == 0) return array;
int bias, min = array[0], max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max)
max = array[i];
if (array[i] < min)
min = array[i];
}
bias = 0 - min;
int[] bucket = new int[max - min + 1];
Arrays.fill(bucket, 0);
for (int i = 0; i < array.length; i++) {
bucket[array[i] + bias]++;
}
int index = 0, i = 0;
while (index < array.length) {
if (bucket[i] != 0) {
array[index] = i - bias;
bucket[i]--;
index++;
} else
i++;
}
return array;
}
桶排序
public static ArrayList<Integer> BucketSort(ArrayList<Integer> array, int bucketSize) {
if (array == null || array.size() < 2)
return array;
int max = array.get(0), min = array.get(0);
for (int i = 0; i < array.size(); i++) {
if (array.get(i) > max)
max = array.get(i);
if (array.get(i) < min)
min = array.get(i);
}
int bucketCount = (max - min) / bucketSize + 1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
ArrayList<Integer> resultArr = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
bucketArr.add(new ArrayList<Integer>());
}
for (int i = 0; i < array.size(); i++) {
bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
}
for (int i = 0; i < bucketCount; i++) {
if (bucketSize == 1) {
for (int j = 0; j < bucketArr.get(i).size(); j++)
resultArr.add(bucketArr.get(i).get(j));
} else {
if (bucketCount == 1)
bucketSize--;
ArrayList<Integer> temp = BucketSort(bucketArr.get(i), bucketSize);
for (int j = 0; j < temp.size(); j++)
resultArr.add(temp.get(j));
}
}
return resultArr;
}
基数排序
public static void radixSort(int[] arr) {
//1.求出arr数组中的最大值
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
//2.求出最大值的位数
int length = String.valueOf(max).length();
//基数排序通过二维数组保存原数组中的数据
int[][] bucket = new int[10][arr.length];
//3.每个桶中的数据个数不固定,使用一维数组记录每个桶中的元素个数
int[] bucketElementCount = new int[10];
//5.由单轮规矩总结
for (int m=0,n=1;m<length;m++,n*=10){
//4.第一轮 按个位数数字放入到桶中
for (int i = 0; i < arr.length; i++) {
int elementIndex = arr[i] /n % 10;
bucket[elementIndex][bucketElementCount[elementIndex]] = arr[i];
bucketElementCount[elementIndex]++;
}
//5.取出桶中的数据放入原数组中
//遍历桶
int index = 0;
for (int j = 0; j < bucket.length; j++) {
//如果桶中有数据,取出并放入到原数组中
if (bucketElementCount[j] > 0) {
//遍历每个桶中的元素
for (int k = 0; k < bucketElementCount[j]; k++) {
arr[index] = bucket[j][k];
index++;
}
}
//每一轮处理结束需要将bucketElementCount置为0
bucketElementCount[j] = 0;
}
}
}
二、时间复杂度
定义:用来度量算法的运行时间,记作: T(n) = O(f(n))。它表示随着 输入大小n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述。
三、空间复杂度
定义:该算法所耗费的存储空间,它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。
四、java十大排序的横向对比
排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 空间复杂度 | 是否稳定 |
---|---|---|---|---|
冒泡排序 | O(n^2) | O(n^2) | O(1) | 是 |
选择排序 | O(n^2) | O(n^2) | O(1) | 不是 |
插入排序 | O(n^2) | O(n^2) | O(1) | 是 |
希尔排序 | O(n*log n) | O(n^s) | O(1) | 不是 |
归并排序 | O(n*log n) | O(n*log n) | O(n) | 是 |
快速排序 | O(n*log n) | O(n^2) | O(log n) | 不是 |
堆排序 | O(n*log n) | O(n*log n) | O(1) | 不是 |
计数排序 | O(n+k) | O(n+k) | O(n+k) | 是 |
桶排序 | O(n*k) | O(n^2) | O(n*k) | 是 |
基数排序 | O(n*k) | O(n*k) | O(n+k) | 是 |