数据结构学习四:树

背景

         对于大量的数据,链表的线性访问时间太慢(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;
}

树节点关系数据如下





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值