排序算法:
例题1:排序数组
解法1:冒泡排序
时间复杂度:O(n^2)
class Solution {
public int[] sort(int[] nums){
//其实不需要返回int[],因为是在原地进行修改
if(nums==null){
//边界条件null
return null;
}
for(int i=0;i<nums.length-1;++i){
//进行nums.length-1轮
boolean isSwap=false; //优化:如果已经有序了,就直接跳出
for(int j=0;j<nums.length-i-1;++j){
if(nums[j]>nums[j+1]){
int temp=nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
isSwap=true;
}
}
if(isSwap==false){
break;
}
}
return nums;
}
}
解法2:选择排序
时间复杂度:O(n^2)
public void chooseSort(int[] array){
if(array==null){
//边界条件null
return null;
}
for(int i=0; i<length-1; i++){
int minIndex = i;
for(int j=minIndex+1;j<length;j++){
if(array[j]<array[minIndex]){
minIndex = j;
}
}
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
解法3:插入排序
时间复杂度:O(n^2)
public void doInsertSort(int[] array){
if(array==null){
//边界条件null
return null;
}
for(int index = 1; index<length; index++){
//外层向右的index,即作为比较对象的数据的index
int temp = array[index];//用作比较的数据
int leftindex = index-1;
while(leftindex>=0 && array[leftindex]>temp){
//当比到最左边或者遇到比temp小的数据时,结束循环
array[leftindex+1] = array[leftindex];
leftindex--;
}
array[leftindex+1] = temp;//把temp放到空位上
}
}
解法4:快速排序
最坏时间复杂度:O(n^2)
平均时间复杂度:O(n*log2n),且系数很小
如果每次规模为 n的问题我们都划分成 1和 n - 1,每次递归的时候又向 n - 1的集合中递归,这种情况是最坏的,时间代价是 O(n ^ 2)。我们可以引入随机化来加速这个过程,它的时间代价的期望是 O(n)
class Solution {
Random random=new Random();
public int[] sortArray(int[] nums) {
quickSort(nums,0,(nums.length-1));
return nums;
}
public void quickSort(int[] nums,int start,int end){
if(start>=end){
return;
}
//随机化,防止最坏情况(即找一个数组中随机数交换到a[start])
int ran=random.nextInt(end-start+1)+start;
swap(nums,ran,start);
//将nums[start]数字放到正确的位置,返回此位置的下标i
int i=partition(nums,start,end);
quickSort(nums,start,i-1);
quickSort(nums,i+1,end);
}
//将nums[start]的数字放到正确的位置
public int partition(int[] nums,int start,int end){
int temp=nums[start];
int i=start,j=end;
while(i<j){
while(temp<=nums[j]&&i<j){
//必须先动右边,否则输入[1,2]就错了
--j;
}
while(nums[i]<=temp&&i<j){
//一定是<=,而不是<。不然i就不动了
++i;
}
if(i<j){
swap(nums,i,j);
}
}
swap(nums,start,i);
return i;
}
public void swap(int[] nums,int index1,int index2){
int temp=nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
}
}
解法5:堆排序
用PriorityQueue实现:
class Solution {
Random random=new Random();
public int[] sortArray(int[] nums) {
Queue<Integer> pq=new PriorityQueue<>();
for(int i=0;i<nums.length;++i){
pq.offer(nums[i]);
}
// 返回堆中的元素
int[] res = new int[pq.size()];
int idx = 0;
for(int i=0;i<nums.length;++i) {
res[idx++] =pq.poll();
}
return res;
}
}
手工实现:
class Solution {
public int[] sortArray(int[] nums) {
int heapSize=nums.length;
buildMaxHeap(nums,heapSize);
for(int i=heapSize-1;i>=1;--i){
swap(nums,i,0);
//这里的i应该理解为当前节点下标碰巧为其前面所有节点的个数