二叉树的创建和遍历——指针链表方式

结构体定义:

struct node{
    int data;        //数据内容
    node* lchild;    //左孩子指针
    node* rchild;    //右孩子指针
};

二叉树的创建:

//通过后序序列和中序序列创建二叉树

//当前二叉树的后序序列区间为[postL, postR],中序序列为[inL, inR]
node* create(int postL,int postR,int inL,int inR){
    if(postL > postR) return NULL;    //若后序序列长度小于0,直接返回
    node* root = new node;            //创建一个新结点,用来存放当前二叉树的根结点
    root->data = postOrder[postR];    //新结点的数据域为根结点的值,也就是当前后序序列的最后一个
    int k;
    for(k=inL; k<=inR; k++){          //找到中序序列中第一个与根结点值相同的位置k
        if(inOrder[k] == postOrder[postR]) break;
    }
    int numLeft = k-inL;              //从k往左一直到当前中序序列的最左边

    //当前创建的结点root左孩子部分的中序序列为[inL,k-1],后序序列为[postL, postL+numLeft-1]
    root->lchild = create(postL, postL+numLeft-1, inL, k-1);

    //当前创建的结点root右孩子部分的中序序列为[k+1,inR],后序序列为[postL+numLeft,postR-1]
    root->rchild = create(postL+numLeft, postR-1, k+1, inR);
    return root;
}
//通过先序序列和中序序列创建二叉树
//当前二叉树的先序序列区间为[preL, preR],中序序列为[inL, inR]
Node* creat(int inL, int inR, int preL, int preR){
	if(preL > preR) return NULL;
	Node* root = new Node;
	root->data = preArr[preL];
	int k;
	for(k=inL; k<=inR; k++){
		if(inArr[k] == preArr[preL]) break;
	}
	int numLeft = k-inL;
	root->left = creat(inL,k-1,preL+1, preL+numLeft);
	root->right = creat(k+1, inR, preL+numLeft+1, preR);
	return root;
}

二叉树的遍历

//层序遍历
queue<Node*> qu;
void layerTraversal(Node* root){
	while(!qu.empty()) qu.pop();
	qu.push(root);
	while(!qu.empty()){
		Node* node = qu.front();
		qu.pop();
		printf("%d ",node->data);
		if(node->left) qu.push(node->left);
		if(node->right) qu.push(node->right);
	}
}
//先序遍历、中序遍历和后序遍历——递归方式
void postTraversal(Node* root){
	if(!root) return;
	postTraversal(root->left);
	postTraversal(root->right);
	printf("%d",root->data);        //输出语句的位置相对应为遍历顺序
}
//先序序列的遍历——非递归方式
void preTraversal(Node* root){
	stack<Node* > stack;
	while(!stack.empty()) stack.pop();
	Node* p = root;
	while(p || !stack.empty()){
		if(p){
			printf("%d ",p->data);
			stack.push(p);        //访问结点后入栈
			p = p->left;          //往左子树继续访问
		}else{
			p = stack.top();      //没有左子树了,取栈顶元素
                        p = p->right;         //往栈顶元素的右子树继续访问
			stack.pop();	      //将栈顶元素出栈
		}
	}
}
//中序序列的遍历——非递归方式
void inTraversal(Node* root){
	stack<Node* > stack;
	while(!stack.empty()) stack.pop();
	Node* p = root;
	while(p || !stack.empty()){
		if(p){
			stack.push(p);    //将结点入栈
			p = p->left;      //往当前结点的左子树继续遍历
		}else{
			p = stack.top();  //取栈顶结点
			stack.pop();      //弹出栈顶结点
			printf("%d ",p->data);    //输出结点
			p = p->right;     //往结点右子树继续遍历
		}
	}
}
//后序遍历的非递归方式
void postTraversal(Node* root){
	stack<Node* > stack;
        while(!stack.empty()) stack.pop();
	Node* p = root;
	Node* r = NULL;
	while(p || !stack.empty()){
		if(p){
			stack.push(p);        //将结点入栈
			p = p->left;          //继续访问结点的左子树
		}else{
			p = stack.top();      //没有左子树了,取栈顶结点
			if(p->right && p->right != r){    //如果结点有右子树并且未被访问过
				p = p->right;     //继续访问结点的右结点
				stack.push(p);    //将右结点入栈
				p = p->left;      //继续访问结点的左子树
			}else{//要么就是没有右子树(表示这个结点是叶节点),要么就是右子树已经被访问过
				stack.pop();      //弹出栈顶元素
				printf("%d ",p->data);    //输出元素
				r = p;            //标记当前节点已经被访问过
				p = NULL;         //将访问指针置空
			}
		}
	}
}
​

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值