背景
对于大量的数据,链表的线性访问时间太慢(O(n);当数据太大时不宜使用。因此出现了新的数据结构,树。树的大部分操作的运行时间平均为O(logN)。
定义
树的定义比较自然的方式是使用递归的方法。一棵树是一些节点的集合。这个集合可以为空,若非空,则一棵树由根(root)的节点以及0个或多个非空的子树T1,T2,T3...Tk组成,这些子树中每一棵树的根都被来自根root的一条有向边所连接。
每一棵子树的根叫做根root的孩子(child)。如下图所示的一个具体树
树的实现
实现树的一种方法,每个树节点除了数据外还有一些其他的指针,一个指针指向他的孩子一个指针指向他的兄弟。
如下
/*
* 树节点声明,针对多叉树
*/
struct MultiTreeNode
{
int Data;
MultiTreeNode* FirstChild;//第一个孩子节点
MultiTreeNode* NextSibling;//兄弟节点
};
MultiTreeNodeOperation.h
#pragma once
#include "TreeNode.h"
#include "common.h"
class MultiTreeNodeOperation
{
private:
int _rootID;
int _nodeCount;
MultiTreeNode* _root;
vector<ConnectRelation> _connectRelations;
public:
MultiTreeNodeOperation();
~MultiTreeNodeOperation();
public:
void CreateTreeNode(string filePath);
private:
bool ReadDataFromFile(string filePath);
RelatedNode FindRelatedNodeID(int currentID);
void RecurrenceCreateTree(MultiTreeNode* current);
};
MultiTreeNodeOperation.cpp
#include "stdafx.h"
#include "MultiTreeNodeOperation.h"
MultiTreeNodeOperation::MultiTreeNodeOperation()
{
}
MultiTreeNodeOperation::~MultiTreeNodeOperation()
{
}
void MultiTreeNodeOperation::CreateTreeNode(string filePath)
{
if (!ReadDataFromFile(filePath))
{
return;
}
_root = new MultiTreeNode();
_root->Data = _rootID;
RecurrenceCreateTree(_root);
}
void MultiTreeNodeOperation::RecurrenceCreateTree(MultiTreeNode* current)
{
RelatedNode related = FindRelatedNodeID(current->Data);
if (related.FirstChildID != -1)
{
current->FirstChild = new MultiTreeNode();
current->FirstChild->Data = related.FirstChildID;
RecurrenceCreateTree(current->FirstChild);
}
if (related.NextSiblingID != -1)
{
current->NextSibling = new MultiTreeNode;
current->NextSibling->Data = related.NextSiblingID;
RecurrenceCreateTree(current->NextSibling);
}
//return current;
}
bool MultiTreeNodeOperation::ReadDataFromFile(string filePath)
{
ifstream fin;
if (!fin)
{
return false;
}
fin.open(filePath);
const int LINE_LENGTH = 3;
char str[LINE_LENGTH];
const int BUFFER_SIZE = 3;
int inputBuffer[BUFFER_SIZE] = { 0,0,0 };
string line1,line2,line3;
if (!fin.eof())
{
fin >> line1 >> line2;
}
_rootID = atoi(line1.c_str());//头节点
_nodeCount = atoi(line2.c_str());//节点数
while (!fin.eof())
{
fin >> line1 >> line2 >> line3;
ConnectRelation connect;
connect.From = atoi(line1.c_str());
connect.To = atoi(line2.c_str());
connect.Relation = (NodeType)atoi(line3.c_str());
_connectRelations.push_back(connect);
}
fin.close();
return true;
}
RelatedNode MultiTreeNodeOperation::FindRelatedNodeID(int currentID)
{
int i = 0;
RelatedNode related;
related.FirstChildID = -1;
related.NextSiblingID = -1;
for (i = 0; i < _connectRelations.size(); i++)
{
if (_connectRelations[i].From == currentID)
{
if (_connectRelations[i].Relation == NodeType::Filiation)
{
related.FirstChildID = _connectRelations[i].To;
}
else
{
related.NextSiblingID = _connectRelations[i].To;
}
}
}
return related;
}
树节点关系数据如下