0x01 实验目的
掌握二叉树的基本概念,二叉树的存储结构使用链表。
0x02 实验内容
- 输入一个完全二叉树的层次遍历字符串,创建这个二叉树,输出这个二叉树的前序遍历字符串、中序遍历字符串、后序遍历字符串、结点数目、二叉树高度(上述每一个结果独立一行显示)。
- 输入二叉树前序序列和中序序列(各元素各不相同),创建这个二叉树,输出该二叉树的后序序列、层次遍历。
0x03 实验过程
层次遍历
判断队列是否为空的条件必须加上,因为队列为空时,有可能会通过q.front()
获取到一些非NULL的奇怪的东西,然后获取其element时会报错。
void levelOrder(binaryTreeNode<E>* node) {queue<binaryTreeNode<E>*> q;while (node != NULL) {if(Level == 0) {Level++;cout<<node->element;if(node->leftChild != NULL) q.push(node->leftChild);if(node->rightChild != NULL) q.push(node->rightChild);if(!q.empty()) {node = q.front();q.pop();}else node = NULL; } else {cout<<","<<node->element;if(node->leftChild != NULL) q.push(node->leftChild);if(node->rightChild != NULL) q.push(node->rightChild);if(!q.empty()) {node = q.front();q.pop();}else node = NULL; }}}
层次遍历构建二叉树
先将第一个节点放入队列,之后树上每添加一个节点就要将该节点入队列。先进先出的进行添加节点操作,直到node数组空了。
template <class E>
binaryTreeNode<E>* constructTreeByLevelOrder(binaryTreeNode<E> node[],int num) {queue<binaryTreeNode<E>*> q;q.push(&node[0]);int i = 1;while(i < num) {binaryTreeNode<E>* current = q.front();q.pop();if(i < num) {current->leftChild = &node[i];q.push(&node[i]);}i++;if(i < num) {current->rightChild = &node[i];q.push(&node[i]);}i++;}return &node[0];
}
前序遍历和中序遍历构建二叉树
采用递归地形式,依次构建左子树和右子树。利用前序遍历的的第一个节点是头节点,以及在中序遍历中头结点的两侧分别为左子树和右子树这两个性质。
template<class E>
binaryTreeNode<E>* create(binaryTreeNode<E> preorder[], int p, int q, binaryTreeNode<E> inorder[], int i, int j) {if (p > q) return nullptr;if (p == q) return &preorder[p];int k = i;// 找到根节点在中序遍历序列中的位置while (preorder[p].element != inorder[k].element) k++;preorder[p].leftChild = create(preorder, p+1, p+k, inorder, i, k-1);preorder[p].rightChild = create(preorder, p+k+1, q, inorder, k+1, j);return &preorder[p];
}
改BUG
0x04 实验源码
#include<bits/stdc++.h>
using namespace std;
int in = 0;
int post = 0;
int Level = 0;
template<class T>
class binaryTreeNode {public:T element;binaryTreeNode<T> *leftChild,*rightChild;binaryTreeNode() {leftChild = rightChild = NULL;}binaryTreeNode(const T& theElement) : element(theElement) {leftChild = rightChild = NULL;}binaryTreeNode(const T& theElement, binaryTreeNode *theLeftChild, binaryTreeNode *theRightChild):element(theElement) {leftChild = theLeftChild;rightChild = theRightChild;}
};
template<class E>
class linkedBinaryTree {public:linkedBinaryTree() {root = NULL;treeSize = 0;}bool empty() const {return treeSize == 0;}int size() const {return treeSize;}void setSize(int size) {treeSize = size;}void preOrder(binaryTreeNode<E>* node,int level) {if(node != NULL) {if(level == 0) {cout<<node->element;preOrder(node->leftChild, ++level);preOrder(node->rightChild, ++level);} else {cout<<","<<node->element;preOrder(node->leftChild, ++level);preOrder(node->rightChild, ++level);}}}void inOrder(binaryTreeNode<E>* node) {if(node != NULL) {if(node->leftChild == NULL && in == 0) {cout<<node->element;in++;} else {inOrder(node->leftChild);cout<<","<<node->element;inOrder(node->rightChild);}}}void postOrder(binaryTreeNode<E>* node) {if(node != NULL) {if(node->leftChild == NULL && post == 0) {cout<<node->element;post++;} else {postOrder(node->leftChild);postOrder(node->rightChild);cout<<","<<node->element;}}}void levelOrder(binaryTreeNode<E>* node) {queue<binaryTreeNode<E>*> q;while (node != NULL) {if(Level == 0) {Level++;cout<<node->element;if(node->leftChild != NULL) q.push(node->leftChild);if(node->rightChild != NULL) q.push(node->rightChild);if(!q.empty()) {node = q.front();q.pop();}else node = NULL; } else {cout<<","<<node->element;if(node->leftChild != NULL) q.push(node->leftChild);if(node->rightChild != NULL) q.push(node->rightChild);if(!q.empty()) {node = q.front();q.pop();}else node = NULL; }}}int getHeight(binaryTreeNode<E>* node) {if(node == NULL) return 0;int h1 = getHeight(node->leftChild);int h2 = getHeight(node->rightChild);if(h1 > h2) {return ++h1;} else {return ++h2;}}private:binaryTreeNode<E> *root;int treeSize;
};
template <class E>
binaryTreeNode<E>* constructTreeByLevelOrder(binaryTreeNode<E> node[],int num) {queue<binaryTreeNode<E>*> q;q.push(&node[0]);int i = 1;while(i < num) {
// cout<<"q.front()"<<q.front()<<endl;
// cout<<"&q.front()"<<&q.front()<<endl;
// cout<<"node[0]"<<&node[0]<<endl;
// cout<<"node[0]"<<&node<<endl;binaryTreeNode<E>* current = q.front();q.pop();if(i < num) {current->leftChild = &node[i];
// cout<<current->leftChild->element<<endl;
// cout<<node[0].leftChild->element<<endl;q.push(&node[i]);}i++;if(i < num) {current->rightChild = &node[i];q.push(&node[i]);}i++;}return &node[0];
}
template<class E>
binaryTreeNode<E>* create(binaryTreeNode<E> preorder[], int p, int q, binaryTreeNode<E> inorder[], int i, int j) {if (p > q) return nullptr;if (p == q) return &preorder[p];int k = i;// 找到根节点在中序遍历序列中的位置while (preorder[p].element != inorder[k].element) k++;preorder[p].leftChild = create(preorder, p+1, p+k, inorder, i, k-1);preorder[p].rightChild = create(preorder, p+k+1, q, inorder, k+1, j);return &preorder[p];
}
int main() {//两种写法都可以。//binaryTreeNode<char> *node = new binaryTreeNode<char>[100];binaryTreeNode<char> node[100];string s;cout<<"Input1"<<endl;cin>>s;for(int i = 0; i < s.length(); i++) {binaryTreeNode<char> n(s.at(i));node[i] = n;}linkedBinaryTree<char> tree;constructTreeByLevelOrder(node,s.length());tree.setSize(s.length());
// node[0].leftChild = &node[1];
// node[0].rightChild = &node[2];
// cout<<"preOrder"<<endl;
// 记录层数,方便输出逗号int level = 0;cout<<"Output1"<<endl;
// cout<<node[0].element<<endl;
// cout<<node[0].leftChild<<endl;tree.preOrder(&node[0],level);cout<<endl;tree.inOrder(&node[0]);in = 0;cout<<endl;tree.postOrder(&node[0]);post = 0;cout<<endl;cout<<tree.size()<<endl;cout<<tree.getHeight(&node[0])<<endl;// tree.constructTreeByLevelOrder(node,length);
// tree.inOrder();
// cout<<2<<node[0].element<<node[0].leftChild->element;cout<<"Input2"<<endl;string s1,s2;cin>>s1>>s2;binaryTreeNode<char> node1[100];binaryTreeNode<char> node2[100];for(int i = 0; i < s1.length(); i++) {binaryTreeNode<char> n(s1.at(i));node1[i] = n;}int noting;for(int i = 0; i < s2.length(); i++) {binaryTreeNode<char> n(s2.at(i));node2[i] = n;if(s2.at(i) == s1.at(0)) noting = i;}//constructTreeByPreOrderAndInOrder(node1, node2, s1.length(), s2.length(), noting);cout<<"Output2"<<endl;create(node1, 0, s1.length()-1, node2, 0, s2.length()-1);
// tree.preOrder(&node1[0],level);
// cout<<endl;
// tree.inOrder(&node1[0]);
// cout<<endl;tree.postOrder(&node1[0]);cout<<endl;tree.levelOrder(&node1[0]);cout<<endl;cout<<"End"<<endl;return 0;
}
0x05 错误代码
#include<bits/stdc++.h>
using namespace std;
int in = 0;
int post = 0;
int Level = 0;
template<class T>
class binaryTreeNode {public:T element;binaryTreeNode<T> *leftChild,*rightChild;binaryTreeNode() {leftChild = rightChild = NULL;}binaryTreeNode(const T& theElement) : element(theElement) {leftChild = rightChild = NULL;}binaryTreeNode(const T& theElement, binaryTreeNode *theLeftChild, binaryTreeNode *theRightChild):element(theElement) {leftChild = theLeftChild;rightChild = theRightChild;}
};
template<class E>
class linkedBinaryTree {public:linkedBinaryTree() {root = NULL;treeSize = 0;}bool empty() const {return treeSize == 0;}int size() const {return treeSize;}void setSize(int size) {treeSize = size;}void preOrder(binaryTreeNode<E>* node,int level) {if(node != NULL) {if(level == 0) {cout<<node->element;preOrder(node->leftChild, ++level);preOrder(node->rightChild, ++level);} else {cout<<","<<node->element;preOrder(node->leftChild, ++level);preOrder(node->rightChild, ++level);}}}void inOrder(binaryTreeNode<E>* node) {if(node != NULL) {if(node->leftChild == NULL && in == 0) {cout<<node->element;in++;} else {inOrder(node->leftChild);cout<<","<<node->element;inOrder(node->rightChild);}}}void postOrder(binaryTreeNode<E>* node) {if(node != NULL) {if(node->leftChild == NULL && post == 0) {cout<<node->element;post++;} else {postOrder(node->leftChild);postOrder(node->rightChild);cout<<","<<node->element;}}}void levelOrder(binaryTreeNode<E>* node) {queue<binaryTreeNode<E>*> q;while (node != NULL) {if(Level == 0) {Level++;cout<<node->element;if(node->leftChild != NULL) q.push(node->leftChild);if(node->rightChild != NULL) q.push(node->rightChild);node = q.front();q.pop();} else {cout<<","<<node->element;if(node->leftChild != NULL) q.push(node->leftChild);if(node->rightChild != NULL) q.push(node->rightChild);node = q.front();q.pop();}}}int getHeight(binaryTreeNode<E>* node) {if(node == NULL) return 0;int h1 = getHeight(node->leftChild);int h2 = getHeight(node->rightChild);if(h1 > h2) {return ++h1;} else {return ++h2;}}private:binaryTreeNode<E> *root;int treeSize;
};
template <class E>
binaryTreeNode<E>* constructTreeByLevelOrder(binaryTreeNode<E> node[],int num) {queue<binaryTreeNode<E>*> q;q.push(&node[0]);int i = 1;while(i < num) {
// cout<<"q.front()"<<q.front()<<endl;
// cout<<"&q.front()"<<&q.front()<<endl;
// cout<<"node[0]"<<&node[0]<<endl;
// cout<<"node[0]"<<&node<<endl;binaryTreeNode<E>* current = q.front();q.pop();if(i < num) {current->leftChild = &node[i];
// cout<<current->leftChild->element<<endl;
// cout<<node[0].leftChild->element<<endl;q.push(&node[i]);}i++;if(i < num) {current->rightChild = &node[i];q.push(&node[i]);}i++;}return &node[0];
}
template <class E>
//左子树的实现
binaryTreeNode<E>* soul(int noting, binaryTreeNode<E> node1[], binaryTreeNode<E> node2[]) {int index1 = 100;int index2 = 100;for(int i = 1; i <= noting; i++) {for(int j = noting; j >= 0; j--) {if(node1[i].element == node2[j].element) {index1 = index2;index2 = j;cout<<"index1"<<index1<<endl;cout<<"index2"<<index2<<endl;}}if(index1 > index2) {node1[i-1].leftChild = &node1[i];} else {
// cout<<"Yes"<<endl;for(int j = noting; j >= 0; j--) {if(node1[i].element == node2[j].element) {for(int k = noting; k >= 0; k--) {if(node2[j-1].element == node1[k].element) {node1[k].rightChild = &node1[i];}}}}}}return &node1[0];
}
template <class E>
binaryTreeNode<E>* constructTreeByPreOrderAndInOrder(binaryTreeNode<E> node1[], binaryTreeNode<E> node2[], int num1, int num2, int noting) {soul(noting, node1, node2);int temp;//获取下一个左子树区间 for(int i = noting + 1; i < num1; i++) {if(node2[i].element == node1[noting+1].element) {temp = noting;noting = i;}}do {//重复操作,直到剩下最后一个元素,或者不剩下元素,退出循环 int num = 0;binaryTreeNode<char> node3[100];binaryTreeNode<char> node4[100];for(int i = temp + 1; i <= noting; i++) {node3[num] = node1[i];node4[num] = node2[i];num++;}soul(noting, node3, node4);for(int i = noting + 1; i < num1; i++) {if(node2[i].element == node1[noting+1].element) {temp = noting;noting = i;}}} while(noting + 1 != num1 - 1 && noting + 1 != num1);//如果剩一个元素 if(noting + 1 == num1 - 1) node2[num1 - 1].rightChild = &node2[num1];return &node1[0];
}
int main() {//binaryTreeNode<char> *node = new binaryTreeNode<char>[100];binaryTreeNode<char> node[100];string s;cout<<"Input"<<endl;cin>>s;for(int i = 0; i < s.length(); i++) {binaryTreeNode<char> n(s.at(i));node[i] = n;}linkedBinaryTree<char> tree;constructTreeByLevelOrder(node,s.length());tree.setSize(s.length());
// node[0].leftChild = &node[1];
// node[0].rightChild = &node[2];
// cout<<"preOrder"<<endl;
// 记录层数,方便输出逗号int level = 0;cout<<"Output"<<endl;
// cout<<node[0].element<<endl;
// cout<<node[0].leftChild<<endl;tree.preOrder(&node[0],level);cout<<endl;tree.inOrder(&node[0]);in = 0;cout<<endl;tree.postOrder(&node[0]);post = 0;cout<<endl;cout<<tree.size()<<endl;cout<<tree.getHeight(&node[0])<<endl;// tree.constructTreeByLevelOrder(node,length);
// tree.inOrder();
// cout<<2<<node[0].element<<node[0].leftChild->element;cout<<"Input2"<<endl;string s1,s2;cin>>s1>>s2;binaryTreeNode<char> node1[100];binaryTreeNode<char> node2[100];for(int i = 0; i < s1.length(); i++) {binaryTreeNode<char> n(s1.at(i));node1[i] = n;}int noting;for(int i = 0; i < s2.length(); i++) {binaryTreeNode<char> n(s2.at(i));node2[i] = n;if(s2.at(i) == s1.at(0)) noting = i;}constructTreeByPreOrderAndInOrder(node1, node2, s1.length(), s2.length(), noting);cout<<"Output2"<<endl;tree.preOrder(&node1[0],level);cout<<endl;tree.inOrder(&node1[0]);cout<<endl;tree.postOrder(&node1[0]);cout<<endl;tree.levelOrder(&node1[0]);cout<<endl;return 0;
}