题目7分析:(重建二叉树)
前序遍历的第一个元素是根节点,中序遍历对应元素的左侧序列是左子树,右侧序列是右子树,此时获得各子树的节点数,就可获得在前序遍历中的子树节点序列;继续在前序遍历和中序遍历的左子树和右子树中递归调用,直至遍历完毕
思路:
1.获得前序遍历的第一个节点的值,即为根节点
2.在中序遍历中获得根节点的位置,计算左右子树的序列长度
3.修改序列的起始地址和结束地址,在此序列范围内先递归构建左子树
4.修改序列的起始地址和结束地址,在此序列范围内再递归构建右子树
5.直到前序和中序序列都遍历完毕,返回根节点
#include <iostream> using namespace std; struct BTNode //二叉树节点类型 { int data; BTNode *lchild; BTNode *rchild; }; BTNode *construct_core(int *s_pre_order, int *e_pre_order, int *s_in_order, int *e_in_order) { //1.获得前序遍历的第一个节点的值,即为根节点 int root_data = s_pre_order[0]; BTNode *root = new BTNode;//创建父节点 root->data = root_data; root->lchild = root->rchild = NULL; if (s_pre_order == e_pre_order) { if (s_in_order == e_in_order&&*s_pre_order == *e_pre_order)//前序和中序序列都遍历完毕,返回根节点 { return root; } else throw exception("invalid input."); } //2.在中序遍历中获得根节点的位置,计算左右子树的序列长度 int *in_root = s_in_order; while (in_root<=e_in_order&&*in_root!=root_data) ++in_root; int l_length = in_root - s_in_order; cout << "当前递归中左子树的节点数量:" << l_length << endl; int *l_pre_order = s_pre_order + l_length; //3.修改序列的起始地址和结束地址,在此序列范围内先递归构建左子树 if (l_length > 0) { root->lchild = construct_core(s_pre_order + 1, l_pre_order, s_in_order, in_root - 1); } //4.修改序列的起始地址和结束地址,在此序列范围内再递归构建右子树 if (l_length < e_pre_order - s_pre_order) { root->rchild = construct_core(l_pre_order + 1, e_pre_order, in_root + 1, e_in_order); } return root; } BTNode *construct(int *pre_order, int *in_order, int length) { if (pre_order == NULL || in_order == NULL || length <= 0)//空数组 return NULL; return construct_core(pre_order, pre_order + length - 1, in_order, in_order + length - 1); } //前序遍历二叉树 void pre_order_tree(BTNode *root) { if (root == NULL) return; cout << "前序遍历:" << root->data << endl; pre_order_tree(root->lchild); pre_order_tree(root->rchild); } void main() { int pre_order[] = {1,2,4,7,3,5,6,8}; int in_order[] = { 4,7,2,1,5,3,8,6 }; int length = sizeof(pre_order) / sizeof(pre_order[0]); cout << "数组长度:"<< length << endl; BTNode *root; root = construct(pre_order, in_order, length); pre_order_tree(root); }
题目9分析:(用两个栈实现队列)
利用两个后进先出的栈实现一个先进先出的队列,将进入数据压入一个栈中,需要删除数据时则将数据从此栈压入另一个栈中,从另一个栈中删除
思路:
1.插入数据时,则将数据压入栈1
2.删除数据时,如果栈2为空,则将栈1数据压入栈2中,从栈2中删除
#include <iostream> #include <stack> using namespace std; template <typename T> class Queue { private: stack<T> stack1; stack<T> stack2; stack<T> temp; public: Queue(void); ~Queue(void); void append_data(const T &data); T delete_data(); }; template <typename T> Queue<T>::Queue(void)//构造函数 {} template <typename T> Queue<T>::~Queue(void)//析构函数 {} template <typename T> void Queue<T>::append_data(const T&data) { stack1.push(data);//1.插入数据时,则将数据压入栈1 } template <typename T> T Queue<T>::delete_data() { if (stack2.size() <= 0)//2.删除数据时,如果栈2为空,则将栈1数据压入栈2中,从栈2中删除 { while (stack1.size() > 0) { T &data = stack1.top(); stack1.pop(); stack2.push(data); } } T head = stack2.top(); stack2.pop(); return head; } void main() { Queue<int> queue; queue.append_data(1); queue.append_data(2); queue.append_data(3); int head = queue.delete_data(); cout << "删除队列数据:" << head << endl; }