N叉树:
一棵树有多个分叉
森林:多棵树
节点:树中的元素,子树
枝干,叶子节点,路径长度
层:根节点到某些结点的路径长度相同,同一层
N叉树的C++定义:
实现一颗N叉树至少需要三个指针:向上,向右,向下
代码实现N叉树定义:
template<class T>
class MyTree{
T data;//数据
MyTree* father;//指向父节点
MyTree* brother;//指向第一个兄弟节点
MyTree* child;//指向第一个孩子节点
public:
MyTree();//构造器
~MyTree();//析构器
//根节点赋值
void insertNodeRoot(const T& data);
//插入结点函数:如果成为孩子(成为最小孩子的最小孩子)如果成为兄弟(成为最小孩子的最小兄弟)
void insertNode(const T& data, bool isChild=true);
void printTree();//遍历打印整棵树
MyTree* getDataPos(const T& data); //查找某个数据,如果存在返回地址
void showData(){
printf("data=%d",data);
}
//按照值来删除结点
//定义规则:如果被删除结点pd有兄弟,那么pd的孩子由pd第一个兄弟领养,pd第一个兄弟作为pd的父亲的孩子
// 如果被删除结点pd没有兄弟,那么pd的孩子由pd的父亲领养,pd的孩子作为pd的父亲的孩子
bool deteleNode(const T& data);
};
并且定义方法:
根节点赋值:void insertNodeRoot(const T& data);
插入结点函数:如果成为孩子(成为最小孩子的最小孩子)如果成为兄弟(成为最小孩子的最小兄弟):void insertNode(const T& data, bool isChild=true);
遍历打印整棵树:void printTree();
查找某个数据,如果存在返回地址 :MyTree* getDataPos(const T& data);
按照值来删除结点:bool deteleNode(const T& data);
定义规则:如果被删除结点pd有兄弟,那么pd的孩子由pd第一个兄弟领养,pd第一个兄弟作为pd的父亲的孩子
如果被删除结点pd没有兄弟,那么pd的孩子由pd的父亲领养,pd的孩子作为pd的父亲的孩子
方法具体实现代码:
#include<iostream>
#include<vector>
#include<string.h>
template<class T>
class MyTree{
T data;//数据
MyTree* father;//指向父节点
MyTree* brother;//指向第一个兄弟节点
MyTree* child;//指向第一个孩子节点
public:
MyTree();//构造器
~MyTree();//析构器
//根节点赋值
void insertNodeRoot(const T& data);//根节点赋值
//插入结点函数:如果成为孩子(成为最小孩子的最小孩子)如果成为兄弟(成为最小孩子的最小兄弟)
void insertNode(const T& data, bool isChild=true);
void printTree();//遍历打印整棵树
MyTree* getDataPos(const T& data); //查找某个数据,如果存在返回地址
void showData(){//展示数据
printf("data=%d",data);
}
//按照值来删除结点
//定义规则:如果被删除结点pd有兄弟,那么pd的孩子由pd第一个兄弟领养,pd第一个兄弟作为pd的父亲的孩子
// 如果被删除结点pd没有兄弟,那么pd的孩子由pd的父亲领养,pd的孩子作为pd的父亲的孩子
bool deteleNode(const T& data);
};
//构造器
template<class T>
MyTree<T>::MyTree(){
father=brother=child=NULL;
}
//析构器
template<class T>
MyTree<T>::~MyTree(){
father=brother=child=NULL;
}
template<class T>
//按照值来删除结点
bool MyTree<T>::deteleNode(const T& data){
/*
MyTree* pTempChild = this;
MyTree* pTempBrother = NULL;
MyTree* pTempNode = NULL;
//如果要删除根节点
if(pTempChild->data == data && pTempChild->father == NULL){
if(pTempChild->brother!=NULL){
pTempChild = pTempChild->brother;
return true;
}else{
return false;//根节点无法删除
}
}
//如果不是删除根节点
while(pTempChild){
pTempBrother = pTempChild;
while(pTempBrother){
//被删除结点pd没有兄弟
if(pTempBrother->data == data && !pTempBrother->brother){
pTempNode = pTempBrother;
pTempBrother->child->father = pTempBrother->father;
pTempNode->father->child = pTempNode->child;
return true;
}
//被删除结点pd有兄弟
if(pTempBrother->data == data && pTempBrother->brother){
pTempNode = pTempBrother;
pTempBrother->child->father = pTempBrother->brother;
pTempNode->father->child = pTempNode->brother;
return true;
}
pTempBrother = pTempBrother->brother;//同一层,有兄弟就继续
}
pTempChild = pTempChild->child;//下一层
}
return false;//没有找到待删除结点
*/
MyTree* pDet = getDataPos(data);
MyTree* pTempNode = NULL;
if(pDet==NULL) return false;//没找到
MyTree* pDetFather = pDet->father;//要删除结点的父节点
if(NULL == pDetFather){//删除的结点是根节点
if(pDet->child==NULL){
return false;
}
if(pDet->brother != NULL){//根节点有兄弟
//this指向根节点
if(this->child){//根节点有兄弟也有孩子
this->data = pDet->brother->data;
this->brother = pDet->brother->brother;
this->child = pDet->child;
this->child->father = pDet->brother;
return true;
}else{//根节点有兄弟但没有孩子
this->data = pDet->brother->data;
this->brother = pDet->brother->brother;
this->child = pDet->brother->child;
return true;
}
}else{//根节点没有兄弟
if(this->child->brother){//根节点的孩子有兄弟
this->data = pDet->child->data;
this->brother = pDet->child->brother;
this->child = pDet->child->child;
return true;
}else{//根节点的孩子没有兄弟
this->data = pDet->child->data;
this->child = pDet->child->child;
this->child->father = pDet->child;
return true;
}
}
}else{//删除的结点不是根节点
pTempNode = pDet;//pTempNode指向pDet结点
if(pDet->brother){//删除的结点不是根节点并且有兄弟
if(pDet->child){//删除的结点不是根节点并且有兄弟也有孩子
pDet->data = pTempNode->brother->data;
pDet->father = pTempNode->brother->father;
pDet->brother = pTempNode->brother->brother;
pDet->child = pTempNode->child;
pDet->child->father = pTempNode->brother;
return true;
}else{//删除的结点不是根节点并且有兄弟但没有孩子
pDet->data = pTempNode->brother->data;
pDet->father = pTempNode->father;
pDet->brother = pTempNode->brother->brother;
pDet->child = pTempNode->brother->child;
return true;
}
}else{//删除的结点不是根节点并且没有兄弟
pTempNode = pDet;
if(pDet->child){
if(pDet->child->brother){//删除的结点的孩子有兄弟
pDet->data = pTempNode->child->data;
pDet->father = pTempNode->father;
pDet->brother = pTempNode->child->brother;
pDet->child = pTempNode->child->child;
return true;
}if(!pDet->child->brother){//删除的结点的孩子没有兄弟
pDet->data = pTempNode->child->data;
pDet->father = pTempNode->father;
pDet->child = pTempNode->child->child;
pDet->child->father = pTempNode->child;
return true;
}
}else{
pDet->father->child = NULL;
return true;
}
}
}
}
//查找某个数据,如果存在返回地址
template<class T>
MyTree<T>* MyTree<T>::getDataPos(const T& data){
MyTree* pTempChild = this;
MyTree* pTempBrother = NULL;
while(pTempChild){
pTempBrother = pTempChild;
while(pTempBrother){
if(pTempBrother->data == data){
return pTempBrother;
}//如果没有兄弟就打印自身一次
pTempBrother = pTempBrother->brother;//如果有兄弟就继续
}
pTempChild = pTempChild->child;
}
return NULL;
}
template<class T>
//根节点赋值
void MyTree<T>::insertNodeRoot(const T& data){
this->data = data;
}
template<class T>
//插入节点函数
void MyTree<T>::insertNode(const T& data, bool isChild){
//插入节点
//1.创造新节点
//2.创建临时指针指向根的最小孩子
//3.判断:成为 最小孩子的最小孩子 or 最小孩子的最小兄弟
MyTree* pNew = new MyTree;
memset(pNew, 0, sizeof(MyTree));
pNew->data = data;
MyTree* pTemp = this;
while(pTemp->child){
pTemp = pTemp->child;
}
if(isChild){//成为孩子(最小孩子的最小孩子)
pTemp->child = pNew;
pNew->father = pTemp;
}
else{//成为兄弟(最小孩子的最小兄弟)
while(pTemp->brother){//先找到最小孩子的最小兄弟
pTemp = pTemp->brother;
}
pTemp->brother = pNew;//成为最小兄弟
pNew->father = pTemp->father;
}
}
template<class T>
//遍历打印整棵树
void MyTree<T>::printTree(){
MyTree* pTempChild = this;
MyTree* pTempBrother = NULL;
//pTempChild = child;
//printf("%d\n", data);
//向右走
while(pTempChild){
pTempBrother = pTempChild;
while(pTempBrother){
printf("%d ", pTempBrother->data);//如果没有兄弟就打印自身一次
pTempBrother = pTempBrother->brother;//如果有兄弟就继续
}
//向下走
printf("\n");
pTempChild = pTempChild->child;
}
}
int main(){
MyTree<int> tree;
tree.insertNodeRoot(0);//添加根节点
tree.insertNode(1, false);
tree.insertNode(2);
tree.insertNode(3, false);
tree.insertNode(4);
tree.insertNode(5);
tree.insertNode(66, false);
tree.insertNode(6);
tree.insertNode(7);
tree.insertNode(8);
tree.printTree();
// MyTree<int>* p = tree.getDataPos(2);
// printf("查到data:");
// if(p){
// p->showData();
// }else{
// printf("找不到");
// }
printf("\n");
tree.deteleNode(6);//删除2这个结点
tree.printTree();//打印
return 0;
}