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; }