《算法五》(N叉树定义+增删改查)

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
", data);
    
    //向右走 
    while(pTempChild){
    	pTempBrother = pTempChild;
    	while(pTempBrother){
    		printf("%d  ", pTempBrother->data);//如果没有兄弟就打印自身一次 
    		pTempBrother = pTempBrother->brother;//如果有兄弟就继续
		}
    
    //向下走 
		printf("
");
		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("
");
	tree.deteleNode(6);//删除2这个结点 
	tree.printTree();//打印 
	
	return 0;
}
原文地址:https://www.cnblogs.com/Whgy/p/12288487.html