#include<cstdio>
void swap(int *arr, int i, int j) {
if (i == j) return;
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
void heapify(int *arr, int index, int *heapSize) {
int left = 2 * index + 1;
while (left < *heapSize) {
int largest = 2 * index + 2 < *heapSize && arr[left + 1] > arr[left] ? left + 1 : left;
largest = arr[largest] > arr[index] ? largest : index;
if (largest == index) break;
swap(arr, largest, index);
index = largest;
left = 2 * index + 1;
}
}
void heapSort(int *arr, int *heapSize) {
while (*heapSize > 0) {
swap(arr, 0, *heapSize - 1);
--(*heapSize);
heapify(arr, 0, heapSize);
}
}
void heapInsert(int *arr, int *heapSize) {
scanf("%d", &arr[*heapSize]);
int cur = *heapSize, parent = (*heapSize - 1) / 2;
while (arr[cur] > arr[parent]) {
swap(arr, cur, parent);
cur = parent;
parent = (cur - 1) / 2;
}
++(*heapSize);
}
int main() {
int n, heapSize = 0;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; ++i) heapInsert(arr, &heapSize);
heapSort(arr, &heapSize);
for (int i = 0; i < n; ++i) printf("%d ", arr[i]);
return 0;
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] array = new int[n];
for(int i=0;i<n;i++){
array[i] = sc.nextInt();
}
heapSort(array);
for(int a:array){
System.out.print(a+" ");
}
}
public static void heapSort(int[] array){
creatMaxHeap(array);
int end = array.length-1;
while(end>0){
int tmp = array[0];
array[0] = array[end];
array[end] = tmp;
adjustDown(array,0,end);
end--;
}
}
public static void creatMaxHeap(int[] array){
for(int i=(array.length/2)-1;i>=0;i--){
adjustDown(array,i,array.length);
}
}
public static void adjustDown(int[] array,int root,int len){
int parent = root;
int child = 2*parent+1;
while(child<len){
if(child+1<len && array[child]<array[child+1]){
child++;
}
if(array[parent]<array[child]){
int tmp = array[parent];
array[parent] = array[child];
array[child] = tmp;
parent = child;
child = 2*parent+1;
}else{
break;
}
}
}
} import java.io.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
static int MAXN = 1001;
static int[] nums = new int[MAXN];
static int n;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while(in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
for(int i = 0; i < n ; i ++) {
in.nextToken();
nums[i] = (int) in.nval;
}
// heapSort1();
heapSort2();
out.print(nums[0]);
for(int i = 1; i < n; i ++)
out.print(" " + nums[i]);
out.println();
}
out.flush();
out.close();
br.close();
}
public static void heapSort1() {
// 从顶到底建立大根堆
for(int i = 0; i < n; i ++) {
heapInsert(i);
}
int size = n;
while(size > 1) {
swap(0, -- size);
heapify(0, size);
}
}
public static void heapSort2() {
for(int i = n - 1; i >= 0; i --) {
heapify(i, n);
}
int size = n;
while(size > 1) {
swap(0, -- size);
heapify(0, size);
}
}
public static void heapInsert(int i) {
// 孩子比父节点大,上浮,交换
while(nums[i] > nums[(i - 1) / 2]) {
swap(i, (i - 1) / 2);
i = (i - 1) / 2;
}
}
public static void heapify(int root, int size) {
int child = 2 * root + 1;
while(child < size) {
if(child + 1 < size && nums[child] < nums[child + 1]) child ++;
if(nums[root] > nums[child]) break; // 无需交换
swap(root, child);
root = child;
child = 2 * root + 1;
}
}
public static void swap(int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
} import sys
for line in sys.stdin:
line = line.strip()
if len(line)<=0:break
n = int(line)
nums = input().strip().split(' ')
nums = [int(x) for x in nums]
def heapify(arr,n,i):
largest = i
lson = i*2+1
rson = i*2+2
if lson<n and arr[largest]<arr[lson]:
largest = lson
if rson<n and arr[largest]<arr[rson]:
largest = rson
if largest!=i:
arr[largest],arr[i] = arr[i],arr[largest]
heapify(arr,n,largest)
def heap_sort(arr,n):
for i in range(int(n/2)-1,-1,-1):
heapify(arr,n,i)
for i in range(n-1,0,-1):
arr[i],arr[0] = arr[0],arr[i]
heapify(arr,i,0)
return arr
nums = heap_sort(nums,len(nums))
ans = ''
for i in range(len(nums)):
ans+=(str(nums[i]))
if i!=len(nums)-1:ans+=' '
print(ans)
面试常见手撕堆排序,主要分为两个函数:①调整堆函数 heapify 和 ②排序函数heap_sort,其中heapify是用递归的思路,逐渐往子结点调整直到不能再调整,heap_sort的思路则是:先调用heapify调整成堆,然后从后往前遍历,并且每一次交换尾部结点和头部结点,只调整无序的部分,有序的部分逐渐增加直到覆盖整个数组。
package heapSort; import java.util.Arrays; import java.util.Scanner; public class heapSort { public static void main(String args[]){ Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] arr = new int[n]; for(int i = 0 ; i < n ; i++){ arr[i] = scanner.nextInt(); } HeapSort(arr); System.out.println(Arrays.toString(arr)); } public static void HeapSort(int[] arr){ /* 将待排序序列构造成一个大顶堆 此时,整个序列的最大值就是堆顶的根节点。*/ /*adjustHeap( arr,1,arr.length); adjustHeap( arr,0,arr.length);*/ for(int i = arr.length / 2 - 1 ; i >= 0 ; i--){ adjustHeap(arr,i,arr.length); } int tmp = 0; for(int i = arr.length - 1 ; i > 0 ; i--){ tmp = arr[i]; arr[i] = arr[0]; arr[0] = tmp; adjustHeap(arr,0,i); } } public static void adjustHeap(int[] arr, int start , int end){ int tmp = arr[start]; for(int i = start * 2 + 1 ; i < end ; i = i * 2 + 1){ if(i + 1 < end && arr[i] < arr[i + 1]){ i++; } if(arr[i] > tmp){ arr[start] = arr[i]; start = i; }else{ break; } } arr[start] = tmp; } }
#include<iostream>
using namespace std;
const int N = 100010;
int n, h[N], size1;
void down(int u) {
int t = u;
if (u * 2 <= size1 && h[u * 2] < h[t]) t = u * 2;
if (u * 2 + 1 <= size1 && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
if (u != t) {
swap(h[u], h[t]);
down(t);
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
size1 = n;
for (int i = n / 2; i; i--) down(i);
while( n --){
printf("%d ", h[1]);
h[1] = h[size1];
size1--;
down(1);
}
return 0;
} #include<iostream>
#include<vector>
using namespace std;
void heap_adjust(vector<int>&nums,int cur,int n)//调整大顶堆
{
int tmp=nums[cur];
while(cur<n)
{
int l=2*cur+1;
int r=2*cur+2;
if(l<n&&nums[cur]<nums[l])
nums[cur]=nums[l];
if(r<n&&nums[cur]<nums[r])
nums[cur]=nums[r];
if(nums[cur]==tmp)
break;
if(nums[cur]==nums[l])
cur=l;
else
cur=r;
nums[cur]=tmp;
}
}
void heap_sort(vector<int>&nums,int n)
{
for(int i=n/2-1;i>=0;--i)//构建大顶堆
{
heap_adjust(nums,i,n);
}
for(int i=n-1;i>0;--i)
{
int temp=nums[0];
nums[0]=nums[i];
nums[i]=temp;
heap_adjust(nums,0,i);
}
}
int main()
{
int count;
cin>>count;
vector<int>nums(count);
for(int i=0;i<count;++i)
{
cin>>nums[i];
}
heap_sort(nums,count);
for(int i=0;i<count;++i)
{
cout<<nums[i]<<" ";
}
} import java.util.Scanner;
public class Main {
private static final Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
heapSort(arr);
for (int i = 0; i < n; i++) {
System.out.print(arr[i]+" ");
}
}
public static void heapSort(int[]arr) {
if (arr==null || arr.length<2) return;
buildMaxHeap(arr);
for (int i = arr.length-1; i>0 ; i--) {
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
maxHeapAdjust(arr,0,i);
}
}
private static void buildMaxHeap(int[]arr) {
if (arr==null || arr.length<2) return;
int bottomRowLastNodeIndex = (arr.length - 1) / 2;
for (int i = bottomRowLastNodeIndex; i >=0 ; i--) {
maxHeapAdjust(arr,i,arr.length);
}
}
private static void maxHeapAdjust(int[]arr,int index,int heapSize) {
if (index>=heapSize) return;
int left = index * 2 + 1;
int right = index * 2 + 2;
int maxValIndex = index;
if (left<heapSize && arr[left]>arr[maxValIndex]) {
maxValIndex = left;
}
if (right<heapSize && arr[right]>arr[maxValIndex]) {
maxValIndex = right;
}
if (maxValIndex==index) {
return;
}
int tmp = arr[index];
arr[index] = arr[maxValIndex];
arr[maxValIndex] = tmp;
maxHeapAdjust(arr,maxValIndex,heapSize);
}
}
import java.util.*;
public class Main {
public static void main(String[] arg){
Scanner in =new Scanner(System.in);
int n=in.nextInt();
int[] nums=new int[n];
for(int i=0;i<n;i++){
nums[i]=in.nextInt();
}
heapSort(nums);
}
public static void heapSort(int[] nums){
int n=nums.length;
for(int i=n/2-1;i>=0;i--){
//从最后一个非叶子节点开始调整
heapAdjust(nums,i,n);
}
for(int i=n-1;i>0;i--){
swap(nums,0,i);
heapAdjust(nums,0,i);
}
for(int i=0;i<n;i++){
System.out.print(nums[i]+" ");
}
}
//将根节点沉入已构建的大顶堆
public static void heapAdjust(int[] nums,int i,int n){
for(int k=2*i+1;k<n;k=2*k+1){//找左节点
if(k+1<n&&nums[k+1]>nums[k]){
//右节点更大则换为右节点 更大的往上浮
k++;
}
if(nums[k]>nums[i]){
swap(nums,i,k);
i=k;
}else
break;
}
}
public static void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
return;
}
}