[자바 데이터 구조] 힙 정렬

1. 힙
개념

  • 힙은 논리적으로 완전한 이진 트리입니다.
  • 힙은 물리적으로 어레이에 저장됩니다.
  • 노드의 값이 하위 트리의 노드 값보다 크면이를 대형 힙, 대형 루트 힙 또는 최대 힙이라고합니다.
  • 반대로, 그것은 작은 말뚝, 작은 뿌리 말뚝 또는 최소한의 말뚝입니다
  • 힙의 기본 기능은 힙의 가장 중요한 요소를 찾는 것입니다.

작업-하향 조정
전제 조건 : 조정을 수행 하기 전에 왼쪽 및 오른쪽 하위 트리가 이미 더미 여야합니다.
조정 프로세스 (예 : 작은 더미) :

  • index : 조정할 위치를 나타내는 아래 첨자
  • array : 스토리지 힙을 나타내는 배열
  • 크기 : 배열의 힙 요소 수를 나타냅니다.
  • left : 인덱스의 왼쪽 자식의 아래 첨자를 나타냅니다.
  • right : 인덱스의 오른쪽 자식을 나타내는 첨자
  • minIndex : 인덱스의 가장 작은 하위 첨자를 저장합니다.

아이디어 :
(작은 힙 조정을 예로 들어)
1.
인덱스 가 리프 노드이면 조정이 종료됩니다. (1) 인덱스 위치에 자식이 있는지 확인합니다.
(2) 힙이 완전한 이진 트리이므로 왼쪽 자식이없는 오른쪽 자식이므로 왼쪽 자식이 있는지 확인합니다.
(3) 힙의 저장 구조가 배열이므로 왼쪽 자식이 있는지 확인하려면 왼쪽 자식의 첨자가 범위를 벗어 났는지 확인해야합니다. 즉, left> = 크기가 범위를 벗어
났습니다. 2. 인덱스 minIndex의 가장 어린 자식 인 left 또는 right를 결정 합니다 .
(1) 오른쪽 자식이 없으면 minIndex = left
(2) 그렇지 않으면 다음 값을 비교합니다. array [left]와 array [right], minIndex로 작은 것을 선택합니다.
3. array [index]의 값을 array [minIndex] Value와 비교합니다. array [index] <= array [minIndex]이면 다음의 특성을 충족합니다. 힙 및 조정 단부
그렇지 4. 배열 [인덱스] 어레이 [분]의 값을 바꿀
이어서 때문에 파괴 될 수도에는 minIndex 위치에서 힙의 특성 때문에 지표로서에는 minIndex 고려 5. , 위의 작업

계속 반복 하여 아이디어를 조정합니다.
1. 인덱스가 루트 노드인지 (인덱스 == 0) 확인하고
해당 노드 인 경우 종료 2. 인덱스의 부모 노드를 찾아 비교합니다. 그리고 부모 노드의 값은 array [Index] <= array [parentIndex]이면 종료되고, 그렇지 않으면 둘의 값을 교환합니다 .3.
index를 부모 노드 의 값으로 두고 루프를 계속합니다. .
전체적인 아이디어는 더 간단합니다. 부모 노드와 비교하면됩니다.
원자로
구축도 주기적 조정 과정인데, 먼저 논리적으로 이진 트리인지 확인하고 힙의 정의와 특성에 따라 판단하여 힙의 특성에 맞도록한다.

힙 애플리케이션 :
우선 순위 큐 (힙) :

public class MyPriorityQueue {
    
    
    private Integer[] array;
    private int size;
    
    public MyPriorityQueue(){
    
    
        array=new Integer[100];
        size=0;
        
    }
    //得到element下标的元素
    public Integer element(){
    
    
        if(size==0){
    
    
            throw new RuntimeException("空了");
        }
        return array[0];
    }

    //删除元素
    public Integer remove(){
    
    
        if(size==0){
    
    
            throw new RuntimeException("空的");
        }
        int e=array[0];
        array[0]=array[size-1];
        size--;
        adjustDown(0);
        return e;
    }
   public void adjustDown(int index){
    
    
        while(true){
    
    
            int leftIndex=2*index+1;
            if(array[leftIndex]>=size){
    
    
                break;
            }
            int minIndex=leftIndex;
            int rightIndex=leftIndex+1;
            if(rightIndex<size&&array[rightIndex]<array[leftIndex]){
    
    
                minIndex=rightIndex;
            }
            int t=array[index];
            array[index]=array[rightIndex];
            array[rightIndex]=t;

            index=minIndex;
        }
   }

    public void add(Integer e){
    
    
        array[size]=e;
        size++;
        adjustUp(size-1);
    }
    private void adjustUp(int index){
    
    
        while (true){
    
    
            if(index==0){
    
    
                break;
            }
            int parentIndex=(index-1)/2;
            if(array[parentIndex]<=array[index]){
    
    
                break;
            }
            int t=array[index];
            array[index]=array[parentIndex];
            array[parentIndex]=t;

            index=parentIndex;
        }

    }

    public static void main(String[] args) {
    
    
        MyPriorityQueue myPriorityQueue=new MyPriorityQueue();
        
        myPriorityQueue.add(1);
        myPriorityQueue.add(4);
        myPriorityQueue.add(3);
        myPriorityQueue.add(5);
        myPriorityQueue.add(6);
     }
 }

추천

출처blog.csdn.net/m0_46551861/article/details/109141622