最近在刷leetcode,所以就同步更新几篇算法的文章了。首先就是排序篇,之前在大学已经把排序熟悉的炉火纯青了,现在突然发现忘了。我去……重新捡起来。
这篇主要是写堆排序,冒泡很经典,就顺便写一下。
冒泡的思路就是双重循环,第一遍循环找出其中最大或者最小的数放在最后一位,第二遍找出其中第二大或者第二小的数放在第二位,以此类推……到循环结束排序完成。
//例子为正序
void sort(int[] nums){
int temp=0;
for(int i=0;i<nums.length;i++){
for(int j=0;j<nums.length-1;j++){
if(nums[j]>nums[j+1]){
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
}
时间复杂度O(n2)
堆排序:
这里介绍大顶堆,小顶堆类似。
利用了二叉树的结构,每次都将最大的数放到根节点位置,然后把最后一位的数字和根节点位置的数字互换,然后把最后一位的位置向前移一位。
void adjustHeap(int[] nums,int parent,int length){
int child = parent*2+1;//左孩子
while (child < length){
if(child+1<length && nums[child]<nums[child+1]){//若右孩子存在且大于左孩子,否则对比对象还为左孩子
child++;//要对比的对象换成右孩子
}
if(nums[parent]<nums[child]){//子节点大于父节点,交换两节点
int temp = nums[parent];
nums[parent] = nums[child];
nums[child] = temp;
parent = child;
child = parent*2+1;
}else{//父节点大于等于子节点,无需调整
break;
}
}
}
void heapSort(int[] nums){
for(int i = nums.length/2;i>=0;i--){
//第一次构建大顶堆结构
adjustHeap(nums,i,nums.length);
}
for(int i = nums.length-1;i>0;i--){
//循环nums.length-1次,将全部的数字都排序
//交换最后一个元素和根元素
int temp = nums[i];
nums[i] = nums[0];
nums[0] = temp;
//调整结构
adjustHeap(nums,0,i);
}
}
手写了二个排序,突然感觉其实堆排序和冒泡有点像啊,只是堆排序利用了二叉树的结构,使得每次对比的只有log2n次,然后一共执行了n次,使得时间复杂度为n*log2n,空间复杂度二个都是n。