2019-07-01 堆

作者: DreamNeverDie | 来源:发表于2019-07-03 13:22 被阅读0次

普通堆

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <script>
        class MaxHeap{
            constructor(arr){
                this._data = []
                if(arguments.length==1){
                    for(let i=0;i<arr.length;i++){
                        this._data[i+1]=arr[i];
                    }
                    this._count= arr.length;
                    for(let i=Math.floor(this._count/2);i>=1;i--){
                        this.shiftDown(i)
                    }
                }else{                   
                    this._count = 0
                }
                
            }
             swap(arr, a, b) {
                    var tmp = arr[b];
                    arr[b] = arr[a];
                    arr[a] = tmp;
                }

            size(){
                return this._count;
            }

            isEmpty(){
                return this._count==0;
            }

            insert(item){
                this._data[this._count+1]=item;
                this._count ++;
                this.shiftUp(this._count);
            }

            shiftUp(k){
                while(k>1 && this._data[Math.floor(k / 2)] < this._data[k]){
                    this.swap(this._data,Math.floor(k/2),k);
                    k=Math.floor(k / 2);
                }
            }

            extractMax(){
                let ret=this._data[1];
                this.swap(this._data,1,this._count)
                this._count --;
                this.shiftDown(1)
                return ret;
            }

            shiftDown(k){
                while(2*k<= this._count){
                    let j=2*k;
                    if(j+1<= this._count&& this._data[j+1]> this._data[j])
                        j+=1;
                    if(this._data[k]>= this._data[j])
                        break;
                    this.swap(this._data,k,j)
                    k=j
                }
            }
        }

     function swap(arr,a,b){
           var tmp=arr[b];
           arr[b]=arr[a];
           arr[a]=tmp;
       }
        function generateRandomArray(n, rangeL, rangeR) {
            var arr = [];
            for (var i = 0; i < n; i++) {
                arr.push(Math.floor(Math.random() * (rangeR - rangeL + 1)) + rangeL)
            }
            return arr;
        }

        function heapSort1(arr){
          let maxheap=new MaxHeap()
          for(let i=0;i<arr.length;i++)
            maxheap.insert(arr[i])
          while(!maxheap.isEmpty())
            arr[i]=maxheap.extractMax(); 
        }

        function heapSort2(arr){
          let maxheap=new MaxHeap(arr)
          while(!maxheap.isEmpty())
            arr[i]=maxheap.extractMax();  
        }

        function heapSort(arr){
          function __shiftDown(arr,n,k){
            while(2*k+1<n){
                    let j=2*k+1;
                    if(j+1<n&& arr[j+1]> arr[j])
                        j+=1;
                    if(arr[k]>= arr[j])
                        break;
                    swap(arr,k,j)
                    k=j
                }
          }
            for(let i=Math.floor(arr.length-1/2);i>=0;i--)
                __shiftDown(arr,arr.length,i)
            
            for(let i=arr.length-1;i>0;i--){
              swap(arr,0,i)
              __shiftDown(arr,i,0)
            }         
        }

        heapSort(generateRandomArray(50,0,100))
    </script>
</body>
</html>

索引堆

        class IndexMaxHeap{
            constructor(arr){
                this._data = []
                this._indexes=[]
                if(arguments.length==1){
                    for(let i=0;i<arr.length;i++){
                        this._data[i+1]=arr[i];
                    }
                    this._count= arr.length;
                    for(let i=Math.floor(this._count/2);i>=1;i--){
                        this.shiftDown(i)
                    }
                }else{                   
                    this._count = 0
                }
                
            }
             swap(arr, a, b) {
                    var tmp = arr[b];
                    arr[b] = arr[a];
                    arr[a] = tmp;
                }

            size(){
                return this._count;
            }

            isEmpty(){
                return this._count==0;
            }

            //传入的i对用户而言,是从0开始索引的
            insert(i,item){
                i+=1;
                this._data[i]=item;
                this._indexes[this._count+1]=i
                this._count ++;
                this.shiftUp(this._count);
            }

            shiftUp(k){
                while(k>1 && this._data[this._indexes[Math.floor(k / 2)]] < this._data[this._indexes[k]]){
                    this.swap(this._indexes,Math.floor(k/2),k);
                    k=Math.floor(k / 2);
                }
            }

            extractMax(){
                let ret=this._data[this._indexes[1]];
                this.swap(this._indexes,1,this._count)
                this._count --;
                this.shiftDown(1)
                return ret;
            }
            extractMaxIndex(){
                let ret=this._indexes[1]-1;
                this.swap(this._indexes,1,this._count)
                this._count --;
                this.shiftDown(1)
                return ret;
            }
            
            getItem(i){
                return this._data[i+1]
            }

            change(i,newItem){
                i+=1;
                this._data[i]=newItem;
                for(let j=1;j<=count;j++){
                    if(this._indexes[j]==i){
                        shiftUp(j);
                        shiftDown(j);
                    }
                }
            }
            shiftDown(k){
                while(2*k<= this._count){
                    let j=2*k;
                    if(j+1<= this._count&& this._data[this._indexes[j+1]]> this._data[this._indexes[j]])
                        j+=1;
                    if(this._data[this._indexes[k]]>= this._data[this._indexes[j]])
                        break;
                    this.swap(this._indexes,k,j)
                    k=j
                }
            }
        }

用reverse优化过的索引堆

class IndexMaxHeap {
    constructor(arr) {
      this._data = []
      this._indexes = []
      this._reverse = []
      for(let i=0;i<=arr.length;i++)
        this._reverse[i]=0;
      if (arguments.length == 1) {
        for (let i = 0; i < arr.length; i++) {
          this._data[i + 1] = arr[i];
        }
        this._count = arr.length;
        for (let i = Math.floor(this._count / 2); i >= 1; i--) {
          this.shiftDown(i)
        }
      } else {
        this._count = 0
      }

    }
    swap(arr, a, b) {
      var tmp = arr[b];
      arr[b] = arr[a];
      arr[a] = tmp;
    }

    size() {
      return this._count;
    }

    isEmpty() {
      return this._count == 0;
    }

    //传入的i对用户而言,是从0开始索引的
    insert(i, item) {
      i += 1;
      this._data[i] = item;
      this._indexes[this._count + 1] = i
      this._reverse[i] = this._count + 1
      this._count++;
      this.shiftUp(this._count);
    }

    shiftUp(k) {
      while (k > 1 && this._data[this._indexes[Math.floor(k / 2)]] < this._data[this._indexes[k]]) {
        this.swap(this._indexes, Math.floor(k / 2), k);
        this._reverse[this._indexes[Math.floor(k / 2)]]= Math.floor(k / 2)
        this._reverse[this._indexes[k]] = k

        k = Math.floor(k / 2);
      }
    }

    extractMax() {
      let ret = this._data[this._indexes[1]];
      this.swap(this._indexes, 1, this._count)
      this._reverse[this._indexes[1]]=1
      this._reverse[this._indexes[this._count]] = 0
      this._count--;
      this.shiftDown(1)
      return ret;
    }
    extractMaxIndex() {
      let ret = this._indexes[1] - 1;
      this.swap(this._indexes, 1, this._count)
      this._reverse[this._indexes[1]] = 1
      this._reverse[this._indexes[this._count]] = 0
      this._count--;
      this.shiftDown(1)
      return ret;
    }

    getItem(i) {
      return this._data[i + 1]
    }

    change(i, newItem) {
      i += 1;
      this._data[i] = newItem;
/*       for (let j = 1; j <= count; j++) {
        if (this._indexes[j] == i) {
          shiftUp(j);
          shiftDown(j);
        }
      } */

      let j=this._reverse[i]
      this.shiftUp(j)
      this.shiftDown(j)
    }
    shiftDown(k) {
      while (2 * k <= this._count) {
        let j = 2 * k;
        if (j + 1 <= this._count && this._data[this._indexes[j + 1]] > this._data[this._indexes[j]])
          j += 1;
        if (this._data[this._indexes[k]] >= this._data[this._indexes[j]])
          break;
        this.swap(this._indexes, k, j)
        this._reverse[this._index[k]] = k
        this._reverse[this._index[j]] = j

        k = j
      }
    }
  }

相关文章

网友评论

    本文标题:2019-07-01 堆

    本文链接:https://www.haomeiwen.com/subject/pgoncctx.html