使用堆的优先级队列 - JavaScript和C ++实现之间的区别

时间:2017-09-27 12:39:15

标签: javascript c++ heap priority-queue

我已经用JavaScript重写了基于用C ++编写的类似实现的堆的优先级队列实现。我完全不知道为什么C ++实现有效,而JS则不然。有人可以解释导致JS实现错误的差异吗?

C ++代码:

#include <iostream>
#include <iomanip>
#include <ctime>
#include <cstdlib>

using namespace std;

const int MAXINT = -2147483647;

 struct qelement
 {
   int prio, data;
 };

class queue
{
  private:
    qelement * T;  // kopiec dynamiczny
    int n;         // liczba elementów

  public:
    queue(int max_n);
    ~queue();
    bool empty();
    int  front();
    int  frontprio();
    void push(int prio, int v);
    void pop();
};

queue::queue(int max_n)
{
  T = new qelement[max_n];  // tworzymy tablicę dynamiczną
  n = 0;                    // kopiec jest pusty
}

queue::~queue()
{
  delete [] T;
}

bool queue::empty()
{
  return !n;
}

int queue::front()
{
  return n ? T[0].data : -MAXINT;
}

int queue::frontprio()
{
  return n ? T[0].prio : -MAXINT;
}

{
  int i,j;

  i = n++;
  j = (i - 1) / 2;

  while(i > 0 && T[j].prio < prio)
  {
    T[i] = T[j];
    i = j;
    j = (i - 1) / 2;
  }

  T[i].prio = prio;
  T[i].data = v;
}

void queue::pop()
{
  int i,j,v,p;

  if(n--)
  {
    p = T[n].prio;
    v = T[n].data;

    i = 0;
    j = 1;

    while(j < n)
    {
      if(j + 1 < n && T[j + 1].prio > T[j].prio) j++;
      if(p >= T[j].prio) break;
      T[i] = T[j];
      i = j;
      j = 2 * j + 1;
    }

    T[i].prio = p;
    T[i].data = v;
  }
}

int main()
{
  queue Q(10);   // kolejka 10-cio elementowa
  int i,p,v;

  srand(time(NULL));

  for(i = 0; i < 10; i++)
  {
     v = rand() % 100;
     p = rand() %  10;
     cout << setw(2) << v << ":" << p << endl;
     Q.push(p,v);
  }

  cout << "----\n";

  while(!Q.empty())
  {
    cout << setw(2) << Q.front() << ":" << Q.frontprio() << endl;
    Q.pop();
  }
}

这是不正确的JS代码:

var MAXINT = -2147483647;

function qelement(data, prio) {
  this.prio = prio;
  this.data = data;
}

function queue(l) {
  var T = new Array(l);
  var n = 0;

  for(var i = 0; i < l; i++) T[i] = new qelement(null, 0);

  this.empty = function() {
    return !n;
  }

  this.writeq = function() {
    var i = 0;

    console.log('This is the whole heap');
    while(i < l) {
      console.log(T[i].data + ' : ' + T[i].prio);
      i++;
    }
  }

  this.front = function() {
    return n ? T[0].data : -MAXINT;
  }

  this.frontPrio = function() {
    return n ? T[0].prio : -MAXINT;
  }

  this.push = function(prio, v) {
    var i, j;

    i = n++;
    j = parseInt((i - 1) / 2);

    while (i > 0 && T[j].prio < prio) {
      T[i].prio = T[j].prio;
      T[i].data = T[j].data;
      i = j;
      j = parseInt((i - 1) / 2);
    }

    T[i].prio = prio;
    T[i].data = v;

  }

  this.pop = function() {
    var i, j, v, p;

    if (n--) {
      p = T[n].prio;
      v = T[n].data;

      i = 0;
      j = 1;

      while (j < n) {
        if (j + 1 < n && T[j + 1].prio > T[j].prio) j++;
        if (p >= T[j].prio) break;
        T[i] = T[j];
        i = j;
        j = 2 * j + 1;
      }


      T[i].prio = p;
      T[i].data = v;
    }
  }
}

var test = new queue(10);
var i, p, v;


for(i = 0; i < 10; i++) {
  v = Math.round(Math.random() * 100);
  p = Math.round(Math.random() * 10);
  console.log(v + ' : ' + p);
  test.push(p, v);
}

console.log('-------');

test.writeq();

console.log('-------');

while(!test.empty()) {
  console.log(test.front() + ' : ' + test.frontPrio());
  test.pop();
}

例如输入值(对“值:优先级”):

32 : 6
88 : 3
40 : 1
99 : 8
70 : 8
24 : 7
4 : 6
3 : 9
40 : 1
30 : 5

队列如下所示:

JS:             C++:
3 : 9           3 : 9
99 : 8          99 : 8
24 : 7          70 : 8
70 : 8          24 : 7
32 : 6          32 : 6
40 : 1          4 : 6  
4 : 6           30 : 5 
88 : 3          88 : 3
40 : 1          40 : 1
30 : 5          40 : 1

2 个答案:

答案 0 :(得分:1)

您忘记更换

T[i] = T[j];

T[i].prio = T[j].prio;
T[i].data = T[j].data;

while方法中的pop()循环中。

干杯。

答案 1 :(得分:0)

问题在于push和pop方法。我重写了它们,优先级队列正常工作:

var MAXINT = -2147483647;

function qelement(data, prio) {
    this.prio = prio;
    this.data = data;
}

function queue(l) {
    var T = new Array(l);
    var n = 0;

    for (var i = 0; i < l; i++) T[i] = new qelement(null, 0);

    this.empty = function () {
        return !n;
    }

    this.writeq = function () {
        var i = 0;

        console.log('This is the whole heap');
        while (i < l) {
            console.log(T[i].data + ' : ' + T[i].prio);
            i++;
        }
    }

    this.front = function () {
        return n ? T[0].data : -MAXINT;
    }

    this.frontPrio = function () {
        return n ? T[0].prio : -MAXINT;
    }

    this.push = (prio, v) => {
        var i, j;

        i = n++;

        T[i].prio = prio;
        T[i].data = v;

        T.sort((qEl1, qEl2) => {
            if(qEl1.prio < qEl2.prio) return 1;
            else return 0;
        });
    }

    this.pop = () => {
        var i, j, v, p;

        if (n--) {
            T[0].prio = 0;
            T[0].data = null;

            T.sort((qEl1, qEl2) => {
                if(qEl1.prio < qEl2.prio) return 1;
                else return 0;
            });
        }
    }
}

var test = new queue(10);
var i, p, v;


for (i = 0; i < 10; i++) {
    v = Math.round(Math.random() * 100);
    p = Math.round(Math.random() * 10);
    console.log(v + ' : ' + p);
    test.push(p, v);
}

console.log('-------');

test.writeq();

console.log('-------');

while (!test.empty()) {
    console.log(test.front() + ' : ' + test.frontPrio());
    test.pop();
}