冒泡排序
平均时间复杂度: o(n^2)
最好时间: o(n)
最坏时间: o(n^2)
空间复杂度: o(1)
是否稳定: 稳定
简单的冒泡排序
public int[] bubbleSort(int [] nums){
int len = nums.length;
if(len <= 1) return nums;
for(int i = 0;i < len;i++){
for(int j = 0;j < len-i-1;j++){
if(nums[j] > nums[j+1]){
int temp = nums[j+1];
nums[j+1] = nums[j];
nums[j] = temp;
}
}
}
return nums;
}
冒泡排序的优化
设置标志位
设置一个标志位来标识这次遍历是否进行过交换
如果没有进行过交换则表示数组已经有序,直接退出
public int[] binarySort(int [] nums){
int len = nums.length;
if(len <= 1) return nums;
for(int i = 0;i < len-1;i++){
boolean isSort = true; //是否有序
for(int j = 0;j < len-i-1;j++){
if(nums[j] > nums[j+1]){
int temp = nums[j+1];
nums[j+1] = nums[j];
nums[j] = temp;
isSort = false;
}
}
if(isSort) break;
}
return nums;
}
设置结束位置
比如初始数组为[4,3,2,1,5,6]
经过第一次排序后数组变为[3,2,1,4,5,6]
如果按照普通冒泡排序下次需要遍历的下标范围为[0,4]
但是[3,4]是已经有序的,所以可以减少比较,保存上次交换的结束位置
public int[] bubbleSort(int [] nums){
int len = nums.length;
if(len <= 1) return nums;
int max_index = len-1;
int index = max_index;
for(int i = 0;i < len-1;i++){
boolean isSort = true; //是否有序
for(int j = 0;j < index;j++){
if(nums[j] > nums[j+1]){
int temp = nums[j+1];
nums[j+1] = nums[j];
nums[j] = temp;
isSort = false;
max_index=j;
}
}
if(isSort) break;
index = max_index;
}
return nums;
}
双向冒泡排序
与设置结束位置类似,这个是也设置了起始位置
使得在left之前的都是已经排好序的
public int[] bubbleSort(int [] nums){
int len = nums.length;
if(len <= 1) return nums;
int left = 0;
int right = len-1;
int tleft = 0,tright = 0;
while(left < right){
boolean isSort = true;
for(int i = left;i < right;i++){
if(nums[i+1] < nums[i]){
int temp = nums[i];
nums[i] = nums[i+1];
nums[i+1] = temp;
isSort = false;
tright = i;
}
}
if(isSort)break;
right = tright;
isSort = true;
for(int i = right;i > left;i--){
if(nums[i] < nums[i-1]){
int temp = nums[i];
nums[i] = nums[i-1];
nums[i-1] = temp;
isSort = false;
tleft = i;
}
}
if(isSort)break;
left = tleft;
}
return nums;
}
选择排序
平均时间复杂度: o(n^2)
最好时间: o(n^2)
最坏时间: o(n^2)
空间复杂度: o(1)
是否稳定: 不稳定
选择排序
public int[] selectSort(int [] nums){
int len = nums.length;
if(len <= 1) return nums;
for(int i = 0;i < len;i++){
int minIndex = i;
for(int j = i;j < len;j++){
if(nums[j] < nums[minIndex]){
minIndex = j;
}
}
int t = nums[minIndex];
nums[minIndex] = nums[i];
nums[i] = t;
}
return nums;
}
插入排序
平均时间复杂度: o(n^2)
最好时间: o(n)
最坏时间: o(n^2)
空间复杂度: o(1)
是否稳定: 稳定
插入排序
public int[] insertSort(int [] nums){
int len = nums.length;
if(len <= 1) return nums;
for(int i = 1;i < len;i++){
int cur = nums[i];
int preIndex = i - 1;
while(preIndex >= 0 && nums[preIndex] > cur){
nums[preIndex+1] = nums[preIndex];
preIndex--;
}
nums[preIndex+1] = cur;
}
return nums;
}
快速排序
平均时间复杂度: o(nlogn)
最好时间: o(nlogn)
最坏时间: o(n^2)
空间复杂度: o(logn)
是否稳定: 不稳定
快速排序
public void quickSort(int [] nums,int left,int right){
if(left >= right) return;
int l = left - 1;
int r = right + 1;
int t = nums[left];
while(l < r){
do l++;while(nums[l] < t);
do r--;while(nums[r] > t);
if(l < r){
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
}
quickSort(nums,left,r);
quickSort(nums,r+1,right);
}
归并排序
平均时间复杂度: o(nlogn)
最好时间: o(nlogn)
最坏时间: o(nlogn)
空间复杂度: o(n)
是否稳定: 稳定
public void mergeSort(int [] nums,int left,int right){
if(left >= right) return;
int mid = left + right >> 1;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
//需要合并 [left,mid] [mid+1,right]
int []temp = new int[right-left+1];
int l = left,r = mid+1,k = 0;
while(l <= mid && r <= right){
if(nums[l] < nums[r]) temp[k++] = nums[l++];
else temp[k++] = nums[r++];
}
while(l <= mid) temp[k++] = nums[l++];
while(r <= right) temp[k++] = nums[r++];
for(int i = right;i >= left;i--){
nums[i] = temp[--k];
}
}
堆排序
平均时间复杂度: o(nlogn)
最好时间: o(nlogn)
最坏时间: o(nlogn)
空间复杂度: o(1)
是否稳定: 不稳定
public void heapSort(int [] nums){
int len = nums.length;
if(len <= 1) return;
//构造大根堆
for(int i = (len-1)/2; i>=0 ;i--){
heap(nums,i,len);
}
//将根弄到最后
for(int i = len-1;i >=0; i--){
int t = nums[0];
nums[0] = nums[i];
nums[i] = t;
heap(nums,0,i);
}
}
//子树构建大顶堆
public void heap(int[] nums,int index,int size){
int max = index;
int left = 2 * index + 1;
int right = 2 * index + 2;
if(left < size && nums[left] > nums[max]) max = left;
if(right < size && nums[right] > nums[max]) max = right;
if(max != index){
int t = nums[index];
nums[index] = nums[max];
nums[max] = t;
heap(nums,max,size);
}
}