繁体   English   中英

C ++数据结构通过向量实现二叉树

[英]c++ data structures implement binary tree with a vector

这是我的实现方式:

#include "binary_tree_with_vector.h"
#include <vector>
using namespace std;



template <typename T>
class BinaryTree {

public:
    class Position {
    private:
        int key;
    public:
        Position(int k) : key(k) {}
        friend class BinaryTree;
    };


protected:

    vector<T> *array;

public:
    BinaryTree() {
        array = new vector<T>;
        array->push_back(T());
    }

    int size() {
        return int(array->size()) - 1;
    }

    ~BinaryTree() {
        delete [] array;
    }

    BinaryTree<T>& operator=(const BinaryTree<T>& t) {
        if (this != &t) {
            copyFrom(t);
        }
        return *this;
    }

    BinaryTree(const BinaryTree<T>& t) {
        array = new vector<T>;
        copyFrom(t);
    }

    void print() {
        cout << "size is: " << size() << endl;
        for (int i = 1; i <= size(); i++) {
            cout << array->at(i) << "\t";
        }
        cout << endl;
    }

protected:
    void copyFrom(const BinaryTree& t) {
        for (int i = 1; i <= t.size(); i++) {
            array->push_back(t[i]);
        }
    }


public:

    void swapElements(const Position& p1, const Position& p2) {
        T element = array[p1.key];
        array[p2.key] = array[p1.key];
        array[p1.key] = element;
    }

    void replaceElement(const Position& p, const T& e) {
        array[p.key] = e;
    }

    Position root() {
        return Position(array[1]);
    }

    bool isRoot(const Position& p) {
        return p.key ==1;
    }

    bool isLeft(const Position& p) {
        return p.key % 2 == 0;
    }



    Position parent(const Position& p) {
        return Position(array->at(p.key / 2));

    }

    Position leftChild(const Position& p) {
        return Position(array->at(p.key * 2));
    }
    Position rightChild(const Position& p) {
        return Position(array->at(p.key * 2 + 1));
    }

    Position sibling(const Position& p) {
        if (isLeft(p)) {
            return Position(array->at(p.key + 1));
        }
        return Position(array->at(p.key - 1));
    }

    bool isExternal(const Position& p) {
        return p.key * 2 > size();
    }
    bool isInternal(const Position& p) {
        return !isExternal(p);
    }

    Position insert(const T& e) {
        array->push_back(e);
        return
        (size());
    }


    T elementOf(const Position& p) {
        return array->at(p.key);
    }

};



void binary_tree_with_vector() {


    typedef BinaryTree<int>::Position Position;

    BinaryTree<int> tree;

    Position root = tree.insert(1);
    tree.insert(2);
    tree.insert(3);
    tree.insert(4);
    tree.insert(5);
    tree.insert(6);
    tree.insert(7);
    tree.print();

    //1
    //2     3
    //4 5   6 7

    Position leftChild = tree.leftChild(root);
    cout << "left child of root is: " << tree.elementOf(leftChild) << endl;

    Position rightChild = tree.rightChild(leftChild);
    cout << "right child of left child of root is: " << tree.elementOf(rightChild) << endl;

    Position rightLeft = tree.leftChild(tree.rightChild(root));
    cout << "right left is: " << tree.elementOf(rightLeft) << endl;



}

由于树的实现细节应隐藏在外部,因此该位置只是围绕等级(键或索引)的封装包装。

当我运行它时,我在析构函数中得到了错误

size is: 5
chap6(607,0x7fff7bea6310) malloc: *** error for object 0x100103a88: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
1   2   3   4   5   (lldb) 

您在这里分配单个vector

array = new vector<T>;

但是试图在这里delete vector数组

delete [] array;

将最后一行更改为

delete array;

每当在c ++程序中调用“ new”或“ delete”时,就暗示着存在一种更好的(更安全的读取)方式。

如果您热衷于使用动态内存分配,请使成员变量“ array”成为以下之一:

std::unique_ptr< std::vector< T > > // use auto_ptr prior to c++11

另外,可以通过简单地封装一个向量而不是一个指向向量的指针,对该类进行稍微的修改,使其更有效,更安全,更容易维护。 注意,析构函数和复制运算符现在由编译器隐式正确地生成:

#include <vector>
#include <iostream>

using namespace std;

template <typename T>
class BinaryTree {

public:
    class Position {
    private:
        int key;
    public:
        Position(int k) : key(k) {}
        friend class BinaryTree;
    };


protected:

    vector<T> _array;

public:
    BinaryTree()
    : _array(1) {
    }

    int size() const {
        return int(_array.size() - 1);
    }

    BinaryTree& operator=(const BinaryTree& t) = default;

    BinaryTree(const BinaryTree& t) = default;

    void print() {
        cout << "size is: " << size() << endl;
        for (int i = 1; i <= size(); i++) {
            cout << _array.at(i) << "\t";
        }
    }

public:

    void swapElements(const Position& p1, const Position& p2) {
        swap(_array[p1.key], _array[p2.key]);
    }

    void replaceElement(const Position& p, const T& e) {
        _array[p.key] = e;
    }

    Position root() const {
        return Position(_array[1]);
    }

    static bool isRoot(const Position& p) {
        return p.key ==1;
    }

    static bool isLeft(const Position& p) {
        return p.key % 2 == 0;
    }

    Position parent(const Position& p) const {
        return Position(_array[p.key / 2]);

    }

    Position leftChild(const Position& p) const {
        return Position(_array[p.key * 2]);
    }

    Position rightChild(const Position& p) const {
        return Position(_array[p.key * 2 + 1]);
    }

    Position sibling(const Position& p) const {
        if (isLeft(p)) {
            return Position(_array[p.key + 1]);
        }
        return Position(_array[p.key - 1]);
    }

    bool isExternal(const Position& p) const {
        return p.key * 2 <= size();
    }
    bool isInternal(const Position& p) const {
        return !isExternal(p);
    }

    Position insert(const T& e) {
        _array.push_back(e);
        return
        (size());
    }

};



int main() {

    BinaryTree<int> tree;
    tree.insert(1);
    tree.insert(2);
    tree.insert(3);
    tree.insert(4);
    tree.insert(5);
    tree.print();


}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM