188 堆排序和桶排序

本文详细介绍了Java中的堆排序算法,包括大顶堆的构建和pop操作,以及如何通过桶排序(包括barrelSort方法)对数组进行排序,同时提及了冒泡排序作为桶排序内部排序的一种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这一部分来分析一下堆排序,也可以理解为二叉树排序,这里的堆分为两种,一种的大顶堆,一种是小顶堆,我们所有的排序方法都以升序为主,其中倒序原理也都差不多,所以我们这里主要分析的是大顶堆,大顶堆就是根节点不小于他的两个子节点。

public void buildHeap(int []nums)
{
for(int i=1;i<nums.length;i++)
{
int parent=(i-1)>>1;
int index=i;
while(parent>>0&&nums[parent]<nums[index])
{
nums[parent]^=nums[index];
nums[index]^=nums[parent];
nums[parent]^=nums[index];
index=parent;
parent=(index-1)>>1;
}
}
}

public int pop(int[]nums)
{
int ret=nums[0];
nums[0]=nums[nums.length-1];
int index=0;
int childLeft=index*2+1;
int childRight=index*2+2;

while((childLeft<=nums.length-2)||childRight<<nums.length-2)
{
if(childLeft<=nums.length-2&&childRight<=nums.length-2)
{
if(nums[chidLeft]>nums[childRight])
{
if(nums[childLeft]>nums[index])
{
nums[index]^=nums[childLeft];
numd[childLeft]^=nums[index];
nums[index]^=nums[childLeft];
index=childLeft;
 childLeft=index*2+1;
 childRight=index*2+2;
}
}else
{
if(nums[childRight]>nums[index])
{
nums[index]^=nums[childRight];
numd[childLeft]^=nums[index];
nums[index]^=nums[childRight];
index=childRight;
 childLeft=index*2+1;
 childRight=index*2+2;
}
}
}else if(childLeft==nums.length-2&&childLeft==nums.length-1)
{
if(nums[childLeft]>nums[index])
{
nums[index]^=nums[childLeft];
numd[childLeft]^=nums[index];
nums[index]^=nums[childLeft];
}
}else
{
continue;
}
}
int res=new int[nums.length-1];
for(int i=0;i<nums.length-1;i++)
{
res[i]=nums[i];
}
nums=res;

}
public void HeapSort(int []nums)
{
buildHeap(nums);
int []res=new int[nums.length];
for(int i=0;i<nums.length;i++)
{
res[i]=pop(nums);
}
nums=res;
}

桶排序:桶排序是将数组分散到有限的桶中,然后每个桶再分别排序,而每个桶的排序又可以使用其他排序方法进行排序,可以使桶排序也可以是其他排序,桶的大小可以随意定,如果桶的数量足够多就会变成后面的计数排序,起始我们可以把桶固定在一个数量,根据数组的大小来确定,也可以自己定,比如3个或者5个7个不等,桶的大小确定之后,下一步需要把数组中的值一一存放在桶中,小的值会放在前面的桶里,大的值会放在后面的桶里,中间的值会放在中间的桶里,然后再分别对每个桶进行单独排序,最后再把所有的桶的数据合并在一起就得到排序好的数组。
//对链表进行冒泡排序
public void bubbleSort(List<Integer>list)
{
for(int i=0;i<list.size()-1;i++)
{
int nowIndex=i;
for(int j=1;j<list.size()-i;j++)
{
if(list.get(j)<list.get(j-1))
{
int temp=list.get(j);
list.set(j,list.get(j-1))
list.set(j,temp);
}
}
}
}

public void barrelSort(int []nums,int barrelNumber)
{
int maxNum=nums[0];
int minNum=nums[0];
for(int i=1;i<nums.length;i++)
{
maxNum=Math.max(maxNum,nums[i]);
minNum=Math.min(minNum,nums[i]);
}
int barrelSize=maxNum-minNum+1;
int barrelCount=barrelSize/barrelNumber+1;
List<List<Integer>>list=new LinkedList<>();
for(int i=0;i<barrelCount;i++)
{
list.add(new LinkedList<integer>());
}
for(int i=0;i<nums.length;i++)
{
list.get(nums[i]/barrelNumber).add(nums[i]);
}
for(int i=0;i<barrelCount;i++)
{
bubbleSort(list.get(i));
}
int indexRes=0;
for(int i=0;i<barrelCount;i++)
{
for(int j=0;j<list.get(i).size();j++)
{
nums[indexRes]=list.get(i).get(j);
indexRes++;
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值