#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; } }