一、基本概念
树:
一棵树由根节点(root)和0个或多个非空的子树组成,连接这些子树和根的叫做边(edge)。
子树与根的关系为儿子(child)和父亲(parent),以此可推出祖父,孙子之类的关系,父亲,祖父之类的都可以叫做(真)祖先,儿子,孙子都可以叫做(真)后裔,自己可以是自己的祖先或者后裔。
树的大部分操作的平均运行时间为O(log N),定义、理解、实现树用递归。
对于一棵树,N个节点对应N-1条边,因为除了根之外,其他节点都有一条连接至其父亲的边。
树叶(leaf):没有儿子的节点; 兄弟(sibling):具有相同的父亲。
路径(path):从节点1到节点2的一条通路,由经过的各个节点(K个)组成的序列,要求前面一个节点是后一个节点的父亲;路径的长(length)为这条路上边的条数,为K-1;节点到自己的路径长为0。
深度(depth):节点的深度为根到该节点的唯一路径的长,根的深度为0,一棵树的深度等于它最深的树叶的深度。
高(height):节点的高为从该节点到树叶的的最长路径的长,树叶的高都为0,一棵树的高等于它的根的高。可以知道,一棵树的深度与它的高度相等。
度(degree):一个节点的度为这个节点含有子树的个数,一棵树的度为各节点度的最大值。
二、树的实现
数据结构只是一种结构的概念,没有特定的实现代码,每个人有每个人的实现方式,针对不同的项目,可能具体的细节也会不同,所以我们不必把哪本书或者哪个博客看做是标准答案。实现当然有好有坏,但是没有标准,因此我们可以根据定义给出很多种实现方式。以下作为其中一种实现。
Tree.h
#pragma once
#include<iostream>
using namespace std;
struct TreeNode;
typedef char ElementType;
typedef TreeNode *PtrTreeNode;
typedef PtrTreeNode Tree;
Tree createTree(ElementType);
PtrTreeNode searchEle(Tree,ElementType);
PtrTreeNode addNode(PtrTreeNode, ElementType);
Tree deleteNode(Tree,ElementType);
void printTree(Tree);
void disposeTree(Tree);
struct TreeNode
{
ElementType element;
PtrTreeNode first;
PtrTreeNode next;
};
Tree.cpp
#include "stdafx.h"
#include "Tree.h"
Tree createTree(ElementType e)
{
Tree t = (Tree)malloc(sizeof(TreeNode));
if (t==nullptr)
{
return nullptr;
}
t->element = e;
t->first = nullptr;
t->next = nullptr;
return t;
}
PtrTreeNode addNode(PtrTreeNode ptr, ElementType e)
{
PtrTreeNode node = (PtrTreeNode)malloc(sizeof(TreeNode));
if (node == nullptr)
{
return nullptr;
}
node->element = e;
node->first = nullptr;
node->next = nullptr;
ptr = node;
return ptr;
}
Tree deleteNode(Tree t,ElementType e)
{
if (t==nullptr)
{
return nullptr;
}
if (t->element==e)
{
if (t->next)
{
t->element = t->next->element;
t->next = deleteNode(t->next, t->next->element);
}
else if (t->first)
{
t->element = t->first->element;
t->first = deleteNode(t->first, t->first->element);
}
else
{
free(t);
t=nullptr
}
}
else
{
t->next = deleteNode(t->next, e);
t->first = deleteNode(t->first, e);
}
return t;
}
PtrTreeNode searchEle(Tree t,ElementType e)
{
if (t==nullptr)
{
return nullptr;
}
if (t->element==e)
{
return t;
}
PtrTreeNode ptr = searchEle(t->first, e);
if (ptr)
{
return ptr;
}
else
{
return searchEle(t->next, e);
}
}
void disposeTree(Tree t)
{
if (t == nullptr)
{
return;
}
disposeTree(t->first);
disposeTree(t->next);
free(t);
}
void printTree(Tree t)
{
if (t==nullptr)
{
return;
}
cout << (t->element) << " ";
printTree(t->next);
cout << endl;
printTree(t->first);
}
main.cpp
#include "stdafx.h"
#include "Tree.h"
#include<vld.h>
int main()
{
Tree t = createTree('A');
t->first =addNode(t->first, 'B');
t->first->next=addNode(t->first->next, 'C');
t->first->next->next =addNode(t->first->next->next, 'D');
t->first->next->next->first =addNode(t->first->next->next->first, 'H');
t->first->next->next->next = addNode(t->first->next->next->next, 'E');
t->first->next->next->next->first = addNode(t->first->next->next->next->first, 'I');
t->first->next->next->next->first->next = addNode(t->first->next->next->next->first->next, 'J');
t->first->next->next->next->first->next->first = addNode(t->first->next->next->next->first->next->first, 'P');
t->first->next->next->next->first->next->first->next = addNode(t->first->next->next->next->first->next->first->next, 'Q');
t->first->next->next->next->next = addNode(t->first->next->next->next->next, 'F');
t->first->next->next->next->next->first = addNode(t->first->next->next->next->next->first, 'N');
printTree(t);
PtrTreeNode del = searchEle(t, 'H');
t=deleteNode(t,'H');
printTree(t);
disposeTree(t);
return 0;
}