C++数据结构-实验2-二叉树的操作与实现

数据结构 实验二 二叉树的操作与实现

利用二叉树的二叉链式存储结构设计并实现各种操作算法。
1、二叉树的基本操作算法实现
(1) 利用二叉树字符串“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”创建二叉树的二叉链式存储结构;
(2) 输出该二叉树;
(3) 输出‘H’节点的左、右孩子结点值;
(4) 输出该二叉树的结点个数、叶子结点个数、二叉树的度和高度。
2、二叉树的各种遍历算法实现
实现上述二叉树的先序、中序和后序遍历的递归和非递归算法。
3、线索二叉树的遍历
中序线索化上述二叉树并找出根结点的前驱和后继。

#include<iostream>
#include<iomanip>
#include<stack>
#include<queue>
using namespace std;
struct Node {
	char vlaue;
	int ltag, rtag;
	Node* lchild, * rchild;
	Node() {
		vlaue = '#'; lchild = NULL; rchild = NULL;
		ltag = rtag = 0;
	}
};
struct Tree {
	Node* Head;
	Tree() {
		Head = new Node();
	}
	void initTree(string s) {
		Node* tmpNode, * &root=Head->lchild;
		stack<Node*>st;
		int l = 0, flag = 0, len = s.size();
		while (l < len ) {
			if (s[l] == '(') {
				flag = 1; 
				st.push(tmpNode);
			}
			else if (s[l] == ',') {
				flag = 2;
			}
			else if (s[l] == ')') {
				st.pop();
			}
			else {
				tmpNode = new Node();
				tmpNode->vlaue = s[l];
				if (root == NULL)root = tmpNode;
				else {
					Node*tmproot = st.top();
					if (flag == 1)
						tmproot->lchild = tmpNode;
					else if (flag == 2)
						tmproot->rchild = tmpNode;
				}
				
			}
			l++;
		}
	}

}*tree;
//输出创建二叉树的字符串
void showTree(Node* root) {
	if (root != NULL) {
		cout << root->vlaue;
		if (root->lchild == NULL && root->rchild == NULL)return;
		cout << "(";
		showTree(root->lchild);
		if (root->rchild != NULL)cout << ",";
		showTree(root->rchild);
		cout << ")";
	}
}
//递归的先序遍历
void Preorder(Node *root) {
	if (root != NULL) {
		cout << root->vlaue << " ";
		Preorder(root->lchild);
		Preorder(root->rchild);
	}
}
//递归的中序遍历
void Inorder(Node* root) {
	if (root != NULL) {
		Inorder(root->lchild);
		cout << root->vlaue << " ";
		Inorder(root->rchild);
	}
}
//递归的后序遍历 
void Postorder(Node* root) {
	if (root != NULL) {
		Postorder(root->lchild);
		Postorder(root->rchild);
		cout << root->vlaue << " ";
	}
}
//非递归的先序遍历
void NoRecursivePreorder(Node* root) {
	if (root != NULL) {
		stack<Node*>st;
		while (root != NULL || !st.empty()) {
			if (root != NULL) {
				cout << root->vlaue << " ";
				st.push(root);
				root = root->lchild;
			}
			else {
				root = st.top();
				st.pop();
				root = root->rchild;
			}
		}
	}
}
//非递归的中序遍历
void NoRecursiveInorder(Node* root) {
	if (root != NULL) {
		stack<Node*>st;
		while (root != NULL || !st.empty()) {
			if (root != NULL) {
				st.push(root);
				root = root->lchild;
			}
			else {
				root = st.top();
				st.pop();
				cout << root->vlaue << " ";
				root = root->rchild;
			}
		}
	}
}
//非递归的后序遍历 
void NoRecursivePostorder(Node* root) {
	if (root != NULL) {
		stack<Node*>st;
		Node* tempNode = root, *lastNode = NULL;
		//存左子树直到根
		while (tempNode != NULL) {
			st.push(tempNode);
			tempNode = tempNode->lchild;
		}
		while (!st.empty()) {
			tempNode = st.top();
			st.pop();
			//无右子树
			if (tempNode->rchild == NULL || lastNode == tempNode->rchild) {
				cout << tempNode->vlaue << " ";
				lastNode = tempNode;
			}
			else {
			//存右子树直到根
				st.push(tempNode);
				tempNode = tempNode->rchild;
				while (tempNode) {
					st.push(tempNode);
					tempNode = tempNode->lchild;
				}
			}
		}
	}
}
// 非递归的层次遍历
void layerorder(Node* root) {
	queue<Node*>que;
	que.push(root);
	while (!que.empty()) {
		Node *tempNode = que.front();
		que.pop();
		cout << tempNode->vlaue << " ";
		if (tempNode->lchild != NULL)que.push(tempNode->lchild);
		if (tempNode->rchild != NULL)que.push(tempNode->rchild);
	}
}
//中序线索化上述二叉树并找出根结点的前驱和后继。
Node* pre = NULL;
void ThreadBinaryTree(Node* root) {
	if (root!=NULL) {
		//处理节点的前驱
		ThreadBinaryTree(root->lchild);  //找到最左的节点
		if (root->lchild == NULL) {
			root->lchild = pre;
			root->ltag = 1;
		}
		//处理节点的后继
		if (pre != NULL && pre->rchild == NULL) {
			pre->rchild = root;
			pre->rtag = 1;
		}
		pre = root;
		ThreadBinaryTree(root->rchild);
	}


}
//输出‘H’节点的左、右孩子结点值
void  FindNode(Node* root, char ch,Node *&tempNode) {
	if (tempNode != NULL)return;
	else if (root->vlaue == ch)tempNode = root;
	else {
		if (root->lchild != NULL)FindNode(root->lchild, ch, tempNode);
		if (root->rchild != NULL)FindNode(root->rchild, ch, tempNode);
	}
}
void Findlrchild(Node* root,char ch) {
	Node* tempNode=NULL;
	FindNode(root, ch, tempNode);
	cout << tempNode->lchild->vlaue << " " << tempNode->rchild->vlaue;
}
//输出该二叉树的结点个数
int NodeNum(Node* root) {
	if (root->lchild == NULL && root->rchild == NULL)return 1;
	int tmp = 1;
	if (root->lchild != NULL)tmp += NodeNum(root->lchild);
	if (root->rchild != NULL)tmp += NodeNum(root->rchild);
	return tmp;
}
//叶子结点个数
int EndNodeNum(Node*root) {
	if (root->lchild == NULL && root->rchild == NULL)return 1;
	int tmp = 0;
	if (root->lchild != NULL)tmp += EndNodeNum(root->lchild);
	if (root->rchild != NULL)tmp += EndNodeNum(root->rchild);
	return tmp;
}
//二叉树的高度。
int TreeHeight(Node* root) {
	if (root == NULL)return 0;
	return TreeHeight(root->lchild) > TreeHeight(root->rchild) ? TreeHeight(root->lchild) + 1 : TreeHeight(root->rchild) + 1;
}
//二叉树的度
int GetBitTHight(Node* root) {
	if (root == NULL)return 0;
	int tmp = 0;
	if ((root->lchild == NULL && root->rchild != NULL))tmp = max(1, GetBitTHight(root->rchild));
	if ((root->lchild != NULL && root->rchild == NULL))tmp = max(1, GetBitTHight(root->lchild));
	if (root->lchild != NULL && root->rchild != NULL)return 2;
	return tmp;
}
int main() {
	tree = new Tree();
	// A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))
	string s; cin >> s;
	tree->initTree(s);
	cout << "输出创建二叉树的字符串" << endl;
	showTree(tree->Head->lchild);
	cout << endl;
	cout << "输出该二叉树的结点个数:" << NodeNum(tree->Head->lchild) << endl;
	cout << "叶子结点个数:" << EndNodeNum(tree->Head->lchild) << endl;
	cout << "二叉树的高度:" << TreeHeight(tree->Head->lchild) << endl;
	cout << "二叉树的度:" << GetBitTHight(tree->Head->lchild) << endl;
	cout << "输出‘H’节点的左、右孩子结点值;";
	Findlrchild(tree->Head->lchild, 'H');
	cout << endl;
	cout << "递归前序遍历:";
	Preorder(tree->Head->lchild);
	cout << endl;
	cout << "递归中序遍历:";
	Inorder(tree->Head->lchild);
	cout << endl;
	cout << "递归后序遍历:";
	Postorder(tree->Head->lchild);
	cout << endl;
	cout << "非递归前序遍历:";
	NoRecursivePreorder(tree->Head->lchild);
	cout << endl;
	cout << "非递归中序遍历:";
	NoRecursiveInorder(tree->Head->lchild);
	cout << endl;
	cout << "非递归后序遍历:";
	NoRecursivePostorder(tree->Head->lchild);
	cout << endl;
	cout << "中序线索化二叉树";
	ThreadBinaryTree(tree->Head->lchild);
	cout << tree->Head->lchild->lchild->vlaue << " " << tree->Head->lchild->rchild->vlaue << endl;
	return 0;
}
  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值