手记

《数据结构探险之树篇》代码修正【Van0512】

James老师的演示代码(链表实现)有一点瑕疵,自己做了点修正,同时也可作为树篇的复习材料。
/
树是节点的有限集合。
parent ancestor
child descendant
度degree:当前节点的直接孩子数目。
leaf:终端节点
root:非终端节点
深度depth
节点深度 1,2,3。。。
树的深度
森林
二叉树:所有节点的度都小于等于2
二叉树的遍历:根据访问根的顺序:前序、中序、后序。
/

/
二叉树数组实现:
左孩子下标 = 父节点下标
2 + 1;
右孩子下标 = 父节点下标2 + 2;
父节点下标 = (孩子节点下标 - 1) / 2;
/

各位学友,各自加油。代码如下:
Tree.h

#ifndef TREE_H
#define TREE_H
#include "Node.h"

class Tree {
public:
    Tree(); 
    ~Tree();
    Node* searchNode(int index);
    bool addNode(int index, bool isLeft, Node *pNode);
    bool deleteNode(int index, Node *pNode);
    void preOrderTraversal() const;
    void InOrderTraversal() const;
    void postOrderTraversal() const;
private:
    Node *pRoot;
};

#endif

Tree.cpp

#include "Tree.h"
#include <iostream>
using namespace std;

Tree::Tree() {
    pRoot = new Node;
}

Tree::~Tree() {
    pRoot->deleteNode();
}

Node* Tree::searchNode(int index) {
    return pRoot->searchNode(index);    //这是Node中的函数
}

bool Tree::addNode(int index, bool isLeft, Node *pNode) {
    Node *tmp = searchNode(index);
    if (NULL == tmp) return false;

    Node *node = new Node;
    node->index = pNode->index;
    node->data = pNode->data;
    node->pParent = tmp;

    if (isLeft) {
        if (tmp->pLeft != NULL) return false;
        tmp->pLeft = node;
    }
    else {
        if (tmp->pRight != NULL) return false;
        tmp->pRight = node;
    }

    return true;
}

bool Tree::deleteNode(int index, Node *pNode) {
    Node *tmp = searchNode(index);
    if (NULL == tmp) return false;

    if (NULL != pNode) {
        pNode->index = tmp->index;
        pNode->data = tmp->data;
    }
    tmp->deleteNode();

    return true;
}

void Tree::preOrderTraversal() const {
    pRoot->preOrderTraversal();
}

void Tree::InOrderTraversal() const {
    pRoot->InOrderTraversal();
}

void Tree::postOrderTraversal() const {
    pRoot->postOrderTraversal();
}

Node.h

#pragma once

class Node {
public:
    Node(int index = 0, int data = 0);
    Node* searchNode(int index);
    void deleteNode();
    void preOrderTraversal() const;
    void InOrderTraversal() const;
    void postOrderTraversal() const;
public:
    int index;
    int data;
    Node *pLeft;
    Node *pRight;
    Node *pParent;
};

Node.cpp

#include "Node.h"
#include <iostream>
using namespace std;

Node::Node(int index, int data) {
    this->index = index;
    this->data = data;
    pLeft = pRight = pParent = NULL;
}

void Node::deleteNode() {
    if (pLeft != NULL)
        pLeft->deleteNode();
    if (pRight != NULL)
        pRight->deleteNode();

    if (pParent != NULL) {
        if (pParent->pLeft == this)
            pParent->pLeft = NULL;
        else
            pParent->pRight = NULL;
    }
    delete this;
}

Node* Node::searchNode(int index) {
    if (this->index == index) return this;
    if (pLeft != NULL) {
        if (pLeft->index == index) return pLeft;
        Node *tmp = pLeft->searchNode(index);
        if (NULL != tmp) return tmp;
    }
    if (pRight != NULL) {
        if (pRight->index == index) return pRight;
        Node *tmp = pRight->searchNode(index);
        if (NULL != tmp) return tmp;
    }
    return NULL;
}

void Node::preOrderTraversal() const {
    cout << index << " " << data << endl;
    if (pLeft != NULL)
        pLeft->preOrderTraversal();
    if (pRight != NULL)
        pRight->preOrderTraversal();
}

void Node::InOrderTraversal() const {
    if (pLeft != NULL)
        pLeft->InOrderTraversal();
    cout << index << " " << data << endl;
    if (pRight != NULL)
        pRight->InOrderTraversal();
}

void Node::postOrderTraversal() const {
    if (pLeft != NULL)
        pLeft->postOrderTraversal();
    if (pRight != NULL)
        pRight->postOrderTraversal();
    cout << index << " " << data << endl;
}

demo.cpp

#include "Tree.h"
#include <iostream>
using namespace std;

int main(void) {
    Tree *tree = new Tree;
    Node *node1 = new Node(1, 5);
    Node *node2 = new Node(2, 8);
    Node *node3 = new Node(3, 2);
    Node *node4 = new Node(4, 6);
    Node *node5 = new Node(5, 9);
    Node *node6 = new Node(6, 7);

    tree->addNode(0, true, node1);
    tree->addNode(0, false, node2); 
    tree->addNode(1, true, node3);
    tree->addNode(1, false, node4);
    tree->addNode(2, true, node5);
    tree->addNode(2, false, node6);

    tree->deleteNode(1, NULL);

    tree->preOrderTraversal();
    cout << endl;
    tree->InOrderTraversal();
    cout << endl;
    tree->postOrderTraversal();

    delete tree;
    system("pause");
    return 0;
}
29人推荐
随时随地看视频
慕课网APP

热门评论

searchNode函数依然查询了两次,

Node * Node::SearchNode(int nodeIndex)
{
    if (this->index == nodeIndex) {
    return this;
}
    if (this->pLChild != nullptr) {
       Node *temp = this->pLChild->SearchNode(nodeIndex);
        if (temp != nullptr) {
           return temp;
        }
    }
    if (this->pRChild != nullptr) {
    temp = this->pRChild->SearchNode(nodeIndex);
    return temp;
    }
    return nullptr;
}

调用孩子的SearchNode本就是在孩子不是nodeIndex的情况下调用的,而在孩子调用SearchNode的时候就会判断index是否和他本身相等,这样就判断了两次。

不在该节点判断孩子是否是nodeIndex,直接在孩子的SearchNode中判断,就不会造成多次判断了

searchNode函数依然查询了两次,

Node * Node::SearchNode(int nodeIndex)
{
    if (this->index == nodeIndex) {
    return this;
}
    if (this->pLChild != nullptr) {
       Node *temp = this->pLChild->SearchNode(nodeIndex);
        if (temp != nullptr) {
           return temp;
        }
    }
    if (this->pRChild != nullptr) {
    temp = this->pRChild->SearchNode(nodeIndex);
    return temp;
    }
    return nullptr;
}

调用孩子的SearchNode本就是在孩子不是nodeIndex的情况下调用的,而在孩子调用SearchNode的时候就会判断index是否和他本身相等,这样就判断了两次。

不在该节点判断孩子是否是nodeIndex,直接在孩子的SearchNode中判断,就不会造成多次判断了

数组的二叉树用node不太好吧。。

查看全部评论