-树的创建,遍历(先序、中序,后序、层次、深度优先遍历、广度优先遍历)(递归、非递归)

目录

1结构体:

2创建二叉树

3遍历二叉树

        3.1先序遍历:

        3.2中序遍历

        3.3后序遍历

        3.4层次遍历


输入示例:

依次输入: AB.D..CE.F...来先序创建二叉树

1结构体:

typedef struct tree{
	char data;
	struct tree *leftc,*rightc;
}tree;

2创建二叉树

void create_tree(tree *&x){
	char ch;
	ch=getchar();
	if(ch=='#'){
		x=NULL;
	}else{
		x=new tree;
		x->data=ch;
		create_tree(x->leftc);
		create_tree(x->rightc);
	}
}

关于*、&之间的浅显认识:

 

3遍历二叉树

        3.1先序遍历:

//先序遍历 (递归)
void  print(tree *t){
	if(t==NULL)
		return;
	else{
		cout<<t->data<<"->";
		print(t->leftc);
		print(t->rightc);
	}
}
//非递归
void print2(tree *n){
	tree *stack[100];
	int top=0;
	tree *p=n;
	if(n==NULL)
		return;
	else{
		while(p!=NULL||top!=0){
			if(p!=NULL){
				stack[++top]=p;
				cout<<p->data<<"->";
				p=p->leftc;	
			}else{
				p=stack[top--];
				p=p->rightc;
			}
		}
		
	}
} 

        3.2中序遍历

//中序遍历
void middle_print(tree *t){
	if(t==NULL)
		return;
	else{
		middle_print(t->leftc);
		cout<<t->data<<"->";
		middle_print(t->rightc);
	}
} 
//中序遍历非递归
void middle_print2(tree *t){
	tree *stack[50];
	int top=0,flag=1;
	tree *p=t;
	if(p==NULL){
		return;
	}else{
		do{
			while(p!=NULL){
				stack[++top]=p;
				p=p->leftc;
			}
			if(top==0) flag=0;
			else{
				p=stack[top];top--;
				cout<<p->data<<"->";
				p=p->rightc;
			}	
		}while(flag!=0);
	}
} 

        3.3后序遍历

此处步骤只有一部分,请自己思考动手,在草稿纸上进行步骤的演变。

后序遍历

1.创建s1指针数组,用来存取节点。s2用来标记是否访问(0:未访问、1:访问,为什么要标记呢?为了在左右孩子出栈后方便父结点也出栈)

2.先do while()循环使其根节点以及左孩子节点入s1数组(栈),同时s2数组标记为0

01234
ABD
 
01234
00->10
 

2.if   else  语句判断,条件正确的进入,s2[top]==0(此节点未访问)条件正确进入,进入s1[top]的右孩子节点,将此节点赋值给p,使得s1[top]=1,标记为访问(刷新s2表)。

3.继续do   while()循环,使得s1[top]的右孩子入栈。

4.继续2的步骤判断分别进入语句中操作。

//后序遍历非递归
void back_print2(tree *t){
	tree *s1[100];
	int flag=1,s2[100],top=0;
	tree *p=t;
	if(p==NULL)
	    return;
	else{
		do{
			while(p!=NULL){
				s1[++top]=p;s2[top]=0;p=p->leftc;
			}
			if(top==0) flag=0;
			else if(s2[top]==0){
				p=s1[top]->rightc;s2[top]=1;
			}else{
				p=s1[top];top--;
				cout<<p->data<<"->";
				p=NULL;//防止死循环
			}
		}while(flag!=0);
	}	
}

        3.4层次遍历

思想:

1.根节点A入队

2.A出队,在出队的同时,孩子节点B、C入队

3.队头节点B出队,出队的同时孩子节点D入队。

4..队头节点C出队,同时其孩子节点E入队。

5.以此循环到节点为空,结束循环。

//层次遍历
void cengci(tree *t){
	if(t==NULL)
		return; 
	queue<tree *>que;//创建一个树节点指针的队列
	que.push(t);
	while(!que.empty()){
		tree *p=que.front();
		cout<<p->data<<"->";
		que.pop();
		if(p->leftc!=NULL){
			que.push(p->leftc);
		}
		if(p->rightc!=NULL){
			que.push(p->rightc);
		}
	}
} 

4.深度优先搜遍历

A 是第一个访问的,然后顺序是 B、D,然后是 E。接着再是 C、F、G。
那么,怎么样才能来保证这个访问的顺序呢?
分析一下,在遍历了根结点后,就开始遍历左子树,最后才是右子树。
因此可以借助堆栈的数据结构,由于堆栈是后进先出的顺序,由此可以先将右子树压栈,然后再对左子树压栈,
这样一来,左子树结点就存在了栈顶上,因此某结点的左子树能在它的右子树遍历之前被遍历。

深度优先搜索遍历是与栈结合:

1.根节点入栈

2.进入while循环

3.然后将栈顶元素赋值给q,根节点(栈顶节点)输出,再出栈

4.继续判断左右子节点是否为空:不空—入栈、为空—继续while循环(步骤2)。

5.直到栈为空。

//深度优先搜索
void def(tree *t){
	stack<tree *>p;
	p.push(t);
	tree *q;
	while(!p.empty()){
		q=p.top();
		cout<<q->data<<"->";
		p.pop();
		if(q->rightc!=NULL){
			p.push(q->rightc);
		} 
		if(q->leftc!=NULL){
			p.push(q->leftc);
		}
	} 
}

5.广度优先搜索遍历

广度遍历又可称为宽度遍历:在一定程度上也是层次遍历。

如图遍历顺序为a,b,c,d,e,f

1.首先根节点入队

2.进入while循环

3.将队首元素赋值给p,出栈输出p->data,根节点出队,然后进行判断左右孩子节点是否为空:不空—孩子入队、空—继续while循环(步骤2)。

4.直到队列为空。

void bfs(tree *t)
{
	queue<tree *>q;
	q.push(t);
	tree *p;
	while(!q.empty()){
		p=q.front();
		q.pop();
		cout<<p->data<<"->"; 
		if(p->rightc!=NULL){
			q.push(p->rightc);
		}
		if(p->leftc!=NULL){
			q.push(p->leftc);
		}
	}
} 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以为你提供二叉的建立和遍历代码以及注释。以下是示例代码: ```python # 定义二叉节点类 class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right # 二叉建立 def buildTree(preorder, inorder): # 利用前序遍历中序遍历序列构造二叉 if not preorder or not inorder: return None root = TreeNode(preorder[0]) idx = inorder.index(preorder[0]) root.left = buildTree(preorder[1:idx+1], inorder[:idx]) root.right = buildTree(preorder[idx+1:], inorder[idx+1:]) return root # 二叉前序遍历 def preorderTraversal(root): res = [] if root: res.append(root.val) res += preorderTraversal(root.left) res += preorderTraversal(root.right) return res # 二叉中序遍历 def inorderTraversal(root): res = [] if root: res += inorderTraversal(root.left) res.append(root.val) res += inorderTraversal(root.right) return res # 二叉后序遍历 def postorderTraversal(root): res = [] if root: res += postorderTraversal(root.left) res += postorderTraversal(root.right) res.append(root.val) return res ``` 注释说明: 1. `TreeNode` 类表示二叉的节点,包括节点值 `val`,左子 `left` 和右子 `right`。 2. `buildTree` 函数利用前序遍历序列和中序遍历序列构造二叉,返回根节点。 3. `preorderTraversal` 函数实现二叉的前序遍历,返回遍历结果。 4. `inorderTraversal` 函数实现二叉中序遍历,返回遍历结果。 5. `postorderTraversal` 函数实现二叉后序遍历,返回遍历结果。 以上代码适用于 Python 语言,其他语言的实现方式类似。希望能够对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值