準備知識
バイナリツリーの基本:データ構造とアルゴリズム-データ構造の知識誘導
まず、幅優先アルゴリズム
アクセス・ノードを右へ(左から右であってもよい)左から、それぞれの層に、上部から順次アクセス各レイヤの下に、と呼ばれるレベルを横断する、一つの完全な次のレベルへのアクセス、無までノードは、これまでにアクセスすることができます。
トラバーサルのルール:
- 現在のすべての隣接頂点への最初の完全なアクセス。
- アクセスポイントの前に最初の訪問の頂点に隣接する点は、隣接する頂点をアクセスされます。
結果を通じて:
root-> A-> B-> C-> D-> E
プログラム:
/*二叉树结构*/
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
/*广度优先*/
void breadthFirstSearch(TreeNode* root){
queue<TreeNode*> nodeQueue; //使用队列
nodeQueue.push(root);
TreeNode* node;
while(!nodeQueue.empty()){
node = nodeQueue.front();
nodeQueue.pop();
printf(format, node->val);
if(node->left){
nodeQueue.push(node->left); //先将左子树入队
}
if(node->right){
nodeQueue.push(node->right); //再将右子树入队
}
}
}
第二に、深さ優先アルゴリズム
各可能なパスについてブランチに深いが、これまで先に進むことができず、各ノードは一度だけアクセスすることができます。バイナリツリーの行きがけ、前順、後順の深さに細分化することができる特別な注意を払ってください。
トラバーサルのルール:
連続的に深さ方向に沿って頂点を横切ります。それは、その隣人の頂点方向の深さ方向を指します。
- 任意のサブツリーについて、最初のrootアクセス、そして最後にその権利サブツリーを横断、左のサブツリーをトラバース:予約限定。
- 予約限定:すべてのサブツリーのため、左のサブツリーをトラバースする最初は、その後、根、その最後のトラバース右のサブツリーをご覧ください。
- 後順:すべてのサブツリーのため、左のサブツリーを横断する最初のは、その右部分木、根最後の訪問を横断します。
結果を通じて:
-
先序:root-> A-> C-> D-> B-> E
-
中序:C-> A-> D-> root-> B-> E
-
后序:C-> D-> A-> E-> B->ルート
プログラム:
/*二叉树结构*/
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
(1)予約限定!
/*递归*/
void preOrderTraverse(TreeNode*root) {
printf(format,root->val);
if (root->left)
preOrderTraverse(root->left);
if (root->right)
preOrderTraverse(root->right);
}
/*非递归*/
void preOrderTraverse(TreeNode* root){
stack<TreeNode*> nodeStack; //使用栈
nodeStack.push(root);
TreeNode* node;
while(!nodeStack.empty()){
node = nodeStack.top();
printf(format, node->val);
nodeStack.pop();
if(node->right){
nodeStack.push(node->right); //先将右子树压栈
}
if(node->left){
nodeStack.push(node->left); //再将左子树压栈
}
}
}
(2)予約限定!
/*递归*/
void inOrderTraverse(TreeNode* root) {
if (root->left)
inOrderTraverse(root->left);
printf(format,root->val);
if (root->right)
inOrderTraverse(root->right);
}
/*非递归*/
void inOrderTraverse(TreeNode* root){
stack<TreeNode*> nodeStack; //使用栈
TreeNode* currentNode = root;
while (currentNode || !nodeStack.empty()){
if (currentNode) {
nodeStack.push(currentNode);
currentNode = currentNode->left;
}
else
{
currentNode = nodeStack.top();
nodeStack.pop();
printf(format,root->val);
currentNode = currentNode->right;
}
}
}
前順後に(3)
/*递归*/
void postOrderTraverse(TreeNode* root) {
if (root->left)
postOrderTraverse(root->left);
if (root->right)
postOrderTraverse(root->right);
printf(format,root->val);
}
/*非递归*/
void postOrderTraverse(TreeNode* root) {
stack<TreeNode*node>nodeStack; //使用栈
TreeNode* currentNode = root;
TreeNode* rightNode = null;
while (currentNode|| !stack.empty()) {
// 一直循环到二叉排序树最左端的叶子结点
while (currentNode) {
nodeStack.push(currentNode);
currentNode = currentNode->left;
}
currentNode = stack.top();
stack.pop();
// 当前结点没有右结点或上一个结点(已经输出的结点)是当前结点的右结点,则输出当前结点
while (currentNode.right == null || currentNode.right == rightNode) {
printf(format,root->val);
rightNode = currentNode;
if (stack.isEmpty()) {
return; //root以输出,则遍历结束
}
currentNode = stack.top();
stack.pop();
}
stack.push(currentNode); //还有右结点没有遍历
currentNode = currentNode->right;
}
}
参照