• 堆排序


    堆排序(heapsort)是一种原地(in place)排序算法, 它的时间复杂度是O(nlgn). 堆数据结构不只是在堆排序中有用,它还可以构成一个有效的优先队列。

    堆数据结构是一种数组对象,它可以被视为一颗完全二叉树。如图:

          A

    heap-size是放在A中堆的元素个数。根据数组节点的索引,我们可以分别推测节点i的父节点和孩子节点的索引位置

    PARENT(i)

      return low_round(i/2);

    LEFT(i)

      return 2i;

    RIGHT(i)

      return 2i+1;

    二叉堆有两种:大根堆和小根堆。大根堆是指除了根以外的每个节点i,有A[PARENT(i)]>=A[i]。也就是说父节点的大小大于其孩子节点的大小。同理可得小根堆:A[PARENT(i)]<=A[i].

    对于一种数据结构来说,向其内插入数据或者删除数据都要保持此数据结构的性质。堆数据结构也是这样的,为了保持堆的性质,下面介绍对最大堆进行操作的重要的子程序 MAX-HEAPIFY

    一、保持堆的性质  

    假定以LEFT(i) 和RIGHT(i)为根的两颗二叉树都是大根堆,但这时A[i]可能小于其子女,这样就违反了大根堆的性质。 MAX-HEAPIFY就是让A[i]在大根堆中“下降”,使得以i为根的子树满足大根

    堆的性质。

    下面贴出伪码:

    MAX-HEAPIFY(A, i)
     1 l ← LEFT(i)
     2 r ← RIGHT(i)
     3 if l ≤ heap-size[A] and A[l] > A[i]
     4    then largest ← l
     5    else largest ← i
     6 if r ≤ heap-size[A] and A[r] > A[largest]
     7    then largest ← r
     8 if largest ≠ i
     9    then exchange A[i] <-> A[largest]
    10         MAX-HEAPIFY(A, largest) 

    下图是把4调整到最底层,一趟操作。

     由上图,我们很容易看出,初始构造出一最大堆之后,在元素A[i],即16,大于它的俩个子结点4、10,满足最大堆性质。所以,i下调指向着4,小于,左子14,所以,调用MAX-HEAPIFY,4与其子,14交换位置。但4处在了14原来的位置之后,4小于其右子8,又违反了最大堆的性质,所以再递归调用MAX-HEAPIFY,将4与8,交换位置。于是,满足了最大堆性质,程序结束。

    二、建堆

      建堆可以使用MAX-HEAPIFY程序自底向上地来将一个数组A[1,...,n]变成一个大根堆。过程BUIDL-MAX-HEAP是对树中的每一个非叶子节点调用一次MAX-HEAPIFY。因为二叉堆是一颗完全二叉树,所以它的叶子节点索引是:A[(round(n/2)+1,... ..., n)]

    BUILD-MAX-HEAP(A)
    1  heap-size[A] ← length[A]
    2  for i ← |_length[A]/2_| downto 1
    3       do MAX-HEAPIFY(A, i)   

    下图是堆的构造过程,首先把数组初始化为一颗完全二叉树,然后调整树的性质。如图:

    三、堆排序算法

        堆排序算法是利用堆的性质,首先交换根节点和最后一个叶子节点的值,然后减小堆的大小,这样就挑选出来数组中最大的一个元素,然后迭代这个过程。

    HEAPSORT(A)   
    BUILD-MAX-HEAP(A)  
    2 for i ← length[A] downto 2
    3    do exchange A[1] <-> A[i]
    4       heap-size[A] ← heap-size[A] - 1
    5       MAX-HEAPIFY(A, 1) 

     n-1次调用MAX-HEAPIFY,所以,O(n*lgn)


    堆排序算法的演示过程(通过,顶端最大的元素与最后一个元素不断的交换,交换后又不断的调用MAX-HEAPIFY重新维持最大堆的性质,最后,一个一个的,从大到小的,把堆中的所有元素都清理掉,也就形成了一个有序的序列。这就是堆排序的全部过程。)

    四、下面列出堆排序的java代码:

    package heapSort;
    
    import java.util.Arrays;
    
    public class HeapSort {
        
        public HeapSort(){};
        private static int heap_size;
        
        
        public int LEFT(int i){
            return 2*i+1;
        }
        
        public int RIGHT(int i){
            return 2*i+2;
        }
        
        public int PARENT(int i){
            return (i-1)/2;
        }
        
        public void exchange(int[] A, int i, int j){
            
            int temp = A[i];
            A[i]=A[j];
            A[j]=temp;
        }
        public void MAX_HEAPIFY(int[] A, int i){
            int l= LEFT(i);
            int r= RIGHT(i);
            int largest;
            
            if(l< heap_size && A[l]>A[i])
                largest = l;
            else
                largest = i;
                    
            if(r < heap_size && A[r]>A[largest])
                largest=r;
            
            if(largest != i){
                exchange(A, i, largest);            
                MAX_HEAPIFY(A, largest);
            }
        
                    
        }
        
        public void BUILD_MAX_HEAP(int[] A){
            heap_size=A.length;
            for(int i = (A.length-1)/2; i>= 0; i--){
                MAX_HEAPIFY(A, i);            
            }
        }
        
        public void HEAPSORT(int[] A){
            BUILD_MAX_HEAP(A);
            System.out.println(Arrays.toString(A));
            for(int i = A.length-1; i>=0; i--){
                exchange(A, 0, i);
                
                heap_size= heap_size-1;
                if(heap_size>1){
                    MAX_HEAPIFY(A,0);
                }
    //            System.out.println(i);
    //            System.out.println(Arrays.toString(A));
            }
            
            System.out.println(Arrays.toString(A));
        }
        
        public int HEAP_MAXIMUM(int[] A){
            return A[0];
        }
        
    
        
        public static void main(String[] args){
            int A[]= new int[]{4,1,3,2,16,9,10,14,8,7};
            HeapSort arr = new HeapSort();        
            arr.HEAPSORT(A);
            
        }
    
    }
  • 相关阅读:
    Index(4.3)
    第七次会议(4.22)
    第六次会议(4.15)
    第五次会议(4.8)
    第四次会议(4.2)
    第三次会议(3.25)
    第二次扩大会议(3.19)
    第二次会议(3.25)
    第一次会议(3.11)
    牛客练习赛25A求1-x因数和(离散求和)
  • 原文地址:https://www.cnblogs.com/7899-89/p/3785413.html
Copyright © 2020-2023  润新知