• 《算法五》(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;
    }
    
  • 相关阅读:
    __attribute__ 总结
    linux文件夹打包命令
    学习ARM的一些基本知识,个人整理
    备忘录之 —— .bashrc(IC工具篇)
    GitHub的基本使用
    02: SocketServer服务
    01: socket模块
    08: python基础练习题
    07: 高阶函数&异常处理
    06: 面向对象
  • 原文地址:https://www.cnblogs.com/Whgy/p/12288487.html
Copyright © 2020-2023  润新知