二叉树一些非递归算法总结

二叉树一些非递归算法总结

#include <bits/stdc++.h>
using namespace std;
#define MAXSIZE 10000
typedef char TElemType;
typedef struct BiTNode
{
    TElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
BiTree CreateNode(char* data)  //创建一个节点
{
	BiTree temp = (BiTree)malloc(sizeof(BiTNode));
	temp->data = *data;
	temp->lchild = NULL;
	temp->rchild = NULL;
	return temp;
}
BiTree CreateBiTreeNonRecur(char* str)
{
	BiTree stack[MAXSIZE];
	int top = 0;
	if(*str == '\0')
	{
		cout<<"创建一个空的二叉树";
		return NULL;
	}
	BiTree root = NULL;
	BiTree tempRoot  = NULL; //当前指向节点
	BiTree temp =NULL;
	root = CreateNode(str);
	tempRoot = root;
	while(*str != '\0')
	{	str++;
		if(*(str-1)!= '#')  //建树过程中如果一直未碰到@符号,则持续建立左子树
		{					//并将节点压入栈中
			stack[top++] = tempRoot;
			if(*str != '#')    //判断当前节点是不是@节点,如果是的左子树为空
			{
				temp = CreateNode(str);
				tempRoot->lchild = temp;
				tempRoot = temp;
			}
			else
			{
				tempRoot->lchild =NULL;
			}

		}
		if(*(str-1) =='#' && top >0)  //若前一个节点是@,则出栈,建立右子树
		{
			tempRoot = stack[--top];
			if(*str != '#')//判断当前节点是不是@节点,如果是的右子树为空
			{
				temp = CreateNode(str);
				tempRoot->rchild = temp;
				tempRoot = temp;
			}
			else
				tempRoot->rchild =NULL;
		}
	}
	return root;
}
void pre_traverse(BiTree pTree)
{
    stack<BiTree> s;  //创建一个空栈
	BiTree node_pop;                 //用来保存出栈节点
	BiTree pCur = pTree;             //定义用来指向当前访问的节点的指针

	//直到当前节点pCur为NULL且栈空时,循环结束
	while(pCur || !s.empty())
	{
		//从根节点开始,输出当前节点,并将其入栈,
		//同时置其左孩子为当前节点,直至其没有左孩子,及当前节点为NULL
		printf("%c ", pCur->data);
		s.push(pCur);
		pCur = pCur->lchild;
		//如果当前节点pCur为NULL且栈不空,则将栈顶节点出栈,
		//同时置其右孩子为当前节点,循环判断,直至pCur不为空
		while(!pCur && !s.empty())
		{
			pCur = s.top();
			node_pop=s.top();
			s.pop();
			pCur = pCur->rchild;
		}
	}
}
void in_traverse(BiTree pTree)
{
	stack<BiTree> s;  //创建一个空栈
	BiTree node_pop;                 //用来保存出栈节点
	BiTree pCur = pTree;             //定义指向当前访问的节点的指针

	//直到当前节点pCur为NULL且栈空时,循环结束
	while(pCur || !s.empty())
	{
		if(pCur->lchild)
		{
			//如果pCur的左孩子不为空,则将其入栈,并置其左孩子为当前节点
			s.push(pCur);
			pCur = pCur->lchild;
		}
		else
		{
			//如果pCur的左孩子为空,则输出pCur节点,并将其右孩子设为当前节点,看其是否为空
			printf("%c ", pCur->data);
			pCur = pCur->rchild;
			//如果为空,且栈不空,则将栈顶节点出栈,并输出该节点,
			//同时将它的右孩子设为当前节点,继续判断,直到当前节点不为空
			while(!pCur && !s.empty())
			{
				pCur = s.top();
				printf("%c ",pCur->data);
				node_pop=s.top();
				s.pop();
				pCur = pCur->rchild;
			}
		}
	}
}
void beh_traverse(BiTree pTree)
{
	stack<BiTree> s;  //创建一个空栈
	BiTree node_pop;          //用来保存出栈的节点
	BiTree pCur;              //定义指针,指向当前节点
	BiTree pPre = NULL;       //定义指针,指向上一各访问的节点

	//先将树的根节点入栈
	s.push(pTree);
	//直到栈空时,结束循环
	while(!s.empty())
	{
		pCur = s.top();   //当前节点置为栈顶节点
		if((pCur->lchild==NULL && pCur->rchild==NULL) ||
			(pPre!=NULL && (pCur->lchild==pPre || pCur->rchild==pPre)))
		{
			//如果当前节点没有左右孩子,或者有左孩子或有孩子,但已经被访问输出,
			//则直接输出该节点,将其出栈,将其设为上一个访问的节点
			printf("%c ", pCur->data);
			node_pop=s.top();
			s.pop();
			pPre = pCur;
		}
		else
		{
			//如果不满足上面两种情况,则将其右孩子左孩子依次入栈
			if(pCur->rchild != NULL)
				s.push(pCur->rchild);
			if(pCur->lchild != NULL)
				s.push(pCur->lchild);
		}
	}
}
int levelOrderTraverse(BiTree& T)
{
    queue<BiTree> q;
    BiTree p = NULL;int count1=0;

    if(T)//若根结点非空,则入队列
    {
        q.push(T);
    }
    while(!q.empty())//队列非空
    {
        p = q.front();
        q.pop();
        cout<<p->data<<" ";
        if(p->lchild)//左孩子不空,入队列
        {
            q.push(p->lchild);
        }
        if(p->rchild)//右孩子不空,入队列
        {
            q.push(p->rchild);
        }
        if(p->lchild||p->rchild)count1++;
    }
    return count1;
}
int preorder_get_leaf_number(BiTree proot)
{
    if(proot == NULL)
        return 0;
    int num = 0;
    stack <BiTree> st;
    while (proot != NULL || !st.empty())
    {
        while (proot != NULL)
        {
            st.push(proot);
            proot = proot->lchild;
        }

        if (!st.empty())
        {
            proot = st.top();
            st.pop();
            if(proot->lchild == NULL && proot->rchild == NULL)
                num++;
            proot = proot ->rchild;
        }
    }

    return num;
}
void ExchangeLeftRight2(BiTree node) {
        if(node == NULL)
            return ;
        BiTree p = node;//指针
        stack<BiTree> s;
        //Stack<Node> stack = new Stack<Node>();
        p = node;
        /**
         * 首先交换左右子树
         * 如果右子树不为空则入栈
         * 如果左子树不为空则将指针指向左子树,对左子树进行同样的操作
         * 否则,出栈
         */
        while(1){
            BiTree temp = p->lchild;
            p->lchild = p->rchild;
            p->rchild = temp;
            if(p->rchild !=NULL){//将右节点入栈
                s.push(p->rchild);
            }
            if(p->lchild !=NULL){//指向左节点
                p = p->lchild;
            }else{
                if(s.empty()){//栈为空时结束
                    break;
                }else{
                    p = s.top();
                    s.pop();
                }
            }

        }
    }
int main()
{
	BiTree root;char str[1000];
	//cout<<"请输入根节点的值: ";
	//root = CreateBiTree();
	cout<<"按先序输入二叉树:";
	cin>>str;
	root = CreateBiTreeNonRecur(str);
	if(root!=NULL)cout<<"创建成功"<<endl;
	cout<<"先序遍历:";
	pre_traverse(root);
	cout<<endl;
	cout<<"中序遍历:";
	in_traverse(root);
	cout<<endl;
	cout<<"后序遍历:";
	beh_traverse(root);
	cout<<endl;
	cout<<"层次遍历";
    int count1=levelOrderTraverse(root);
    cout<<endl;
    cout<<"深度为:"<<count1<<endl;
    int num=preorder_get_leaf_number(root);
    cout<<"叶子节点个数为:"<<num<<endl;
    cout<<"交换左右子树"<<endl;
    ExchangeLeftRight2(root);
    cout<<"先序遍历:";
    pre_traverse(root);
    cout<<endl;
	return 1;
}



猜你喜欢

转载自blog.csdn.net/qq_44537408/article/details/89354878