Минимальная проблема двоичной кучи - PullRequest
1 голос
/ 25 февраля 2010

Мне нужна помощь с этим кодом minheap:

#include < vector>

using namespace std;

class heap {

    vector <int> v;

    public:

        int hSize()
        {
            return v.size();
        }

        int rsize()
        {
            return  hSize() - 1;
        }    

        int parent(int i) 
        {
            return (i - 1) / 2;
        }

        int left(int i)
        {
            return i * 2 + 1;
        }

        int right(int i)
        {
            return i * 2 + 2;
        }

        void swap(int i, int j)
        {
            int temp = v[j];
            v[j] = v[i];
            v[i] = temp;
        }

        void push(int e)
        {

            v.push_back(e);
            int id = rsize(); 

            if (hSize() > 1)
                while (v[parent(id)] > v[id]) {               
                    swap(parent(id), id);
                    id = parent(id);
                }
        }

        int pop ()
        {

          int f = 0;  
          int p = v[0];

          v[0] = v[rsize()];

          if (hSize() > 1) {
              while (v[left(f)] < v[f] || v[right(f)] < v[f]) {
                    if (v[left(f)] < v[f] && v[right(f)] < v[f]) {
                        if (v[left(f)] < v[right(f)]) {
                            swap(left(f), f);
                            f = left(f);
                    }
                    else { 
                            swap(right(f), f);
                            f = right(f);
                    }
                }

                else {
                    if (v[left(f)] < v[f]){
                         swap(left(f), f);
                         f = left(f);
                    }
                    else {
                         swap(right(f), f);
                         f = right(f);
                        }
                    }
                } 
          }
          else { }

          v.resize(rsize());
          return p;
        }

        void show()
        {
            if (hSize() > 0) {
                cout << "Heap content: ";
                for (int i = 0; i < hSize(); i++) cout << v[i] << " ";
            }
            else cout << "\nHeap successfully emptied!";  
            cout << "\n";          
        }

        bool Empty()
        {
            return v.empty();
        }

        ~heap()
        {
            v.clear();
        }

    };         

Ну, код делает почти все правильно, за исключением того, что когда он выдает последний элемент на экране, он печатает случайное число Каково ваше мнение?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 25 февраля 2010

У вас есть две похожие проблемы: одна в push() и одна в pop(). В толчке нужно проверить, что id != 0, прежде чем смотреть на v[parent(id)]. Если id == 0, вы находитесь в корне, и вам следует остановиться. Аналогично, в pop() вы должны проверить, находится ли right(f) (или left(f)) в векторе, прежде чем получить доступ к v[right(f)] (или v[left(f)]). Если это не так, вы достигли дна кучи и должны остановиться.

1 голос
/ 25 февраля 2010

Debugging

  • Вы можете запустить код с помощью valgrind, чтобы увидеть, сообщает ли он об ошибках.
  • Вы можете запустить код в отладчике (отладка занимает больше времени, но больше вероятность успеха).

Кодирование Вы должны использовать утверждения. Например, первая строка функции swap может быть assert(i >= 0 && i < v.size()); и аналогично для j. Я подозреваю, что эти два утверждения скажут вам об ошибках. Когда вы закончите, если хотите, можете закомментировать утверждения (хотя некоторые люди любят оставлять некоторые утверждения всегда).

Обновление Ваш код был в порядке. Просто нужно добавить проверку границ внутри свопа и вернуться, если не выполняется. Вот код и контрольный пример (который прошел при запуске):

#include <vector>
#include <iostream>
#include <cassert>
#include <cstdlib>

using namespace std;

class heap {

    vector <int> v;

    public:

        int hSize()
        {
            return v.size();
        }

        int rsize()
        {
            return  hSize() - 1;
        }

        int parent(int i)
        {
            return (i - 1) / 2;
        }

        int left(int i)
        {
            return i * 2 + 1;
        }

        int right(int i)
        {
            return i * 2 + 2;
        }

        void swap(int i, int j)
        {
            //assert(i >= 0 && i < v.size()); 
            //assert(j >= 0 && j < v.size()); 
            if(i >= v.size() || j >= v.size()) return;
            int temp = v[j];
           v[j] = v[i];
            v[i] = temp;
        }

        void push(int e)
        {

            v.push_back(e);
            int id = rsize();

            if (hSize() > 1)
                while (v[parent(id)] > v[id]) {
                    swap(parent(id), id);
                    id = parent(id);
                }
        }

        int pop ()
        {

          int f = 0;
          int p = v[0];

          v[0] = v[rsize()];

          if (hSize() > 1) {
                  while (v[left(f)] < v[f] || v[right(f)] < v[f]) {
                          if (v[left(f)] < v[f] && v[right(f)] < v[f]) {
                                  if (v[left(f)] < v[right(f)]) {
                                          swap(left(f), f);
                                          f = left(f);
                                  }
                                  else {
                                          swap(right(f), f);
                                          f = right(f);
                                  }
                          }

                          else {
                                  if (v[left(f)] < v[f]){
                                          swap(left(f), f);
                                          f = left(f);
                                  }
                                  else {                                         swap(right(f), f);
                                          f = right(f);
                                  }
                          }
                  }
          }
          else { }

          v.resize(rsize());
          return p;
        }

        void show()
        {
                if (hSize() > 0) {
                        cout << "Heap content: ";
                        for (int i = 0; i < hSize(); i++) cout << v[i] << " ";
                }
                else cout << "\nHeap successfully emptied!";
                cout << "\n";
        }

        bool Empty()
        {
                return v.empty();
        }

        ~heap()
        {
                v.clear();
        }

};


int main()
{
        heap h;
        for(int i = 0; i < 10; i++) {
        h.push(rand()%10);
        h.push(4);
        h.push(3);
        h.push(2);
        h.push(1);
        h.push(0);
        h.push(5);
        h.push(-6);
        h.push(7);
        h.show();
        h.pop();
        h.pop();
        h.pop();
        h.pop();
        h.pop();
        h.pop();
        h.pop();
        h.pop();
        h.pop();
        h.show();
        }
}

После ввода утверждения я запустил код в отладчике и обнаружил, что сбой произошел в строке swap(right(f), f); и right(f) выходит за пределы.

...