Maison Java javaDidacticiel Restaurer l'arbre binaire à travers la séquence après le parcours pré-commande et le parcours dans l'ordre

Restaurer l'arbre binaire à travers la séquence après le parcours pré-commande et le parcours dans l'ordre

Jun 23, 2017 pm 03:36 PM
序列 passer 遍历

Lorsque nous avons une

séquence de parcours en pré-ordre : 1,3,7,9,5,11

séquence de parcours en ordre : 9,7,3,1, 5, 11

On peut facilement écrire l'arbre binaire correspondant avec un stylo. Mais comment l’implémenter à l’aide de code ?

Parlons brièvement des idées de base.

Tout d'abord, l'ordre de parcours de pré-commande est basé sur l'ordre de enfant racine-gauche-enfant droit, puis la première chose que nous pouvons confirmer est la séquence de parcours en pré-ordre. Le premier numéro est le nœud racine, puis le parcours en ordre est parcouru dans l'ordre enfant gauche-racine-enfant droit. Nous avons confirmé le nœud racine via un parcours pré-commandé, il nous suffit alors de trouver l'emplacement du nœud racine lors du parcours dans l'ordre, puis nous pouvons facilement distinguer les nœuds qui appartiennent au sous-arbre gauche et ceux qui appartiennent au sous-arbre gauche. sous-arbre droit. Comme indiqué ci-dessous :

Nous déterminons le nombre 1 comme nœud racine, puis le déterminons en fonction de l'ordre de parcours du parcours dans l'ordre. Dans la séquence de parcours dans l'ordre, tout le côté gauche du. le numéro 1 sont des nœuds de sous-arbres de gauche, et tous les sous-arbres de droite sont des sous-arbres de droite. Grâce au nombre de nœuds du sous-arbre gauche, nous pouvons conclure que les trois nombres consécutifs du nœud racine dans la séquence de parcours de pré-ordre appartiennent au sous-arbre gauche et que les autres sont le sous-arbre droit. De cette manière, les étapes ci-dessus sont répétées dans la séquence des sous-arbres gauche et droit, jusqu'à ce qu'aucun nœud enfant ne soit finalement trouvé.

Le code d'implémentation est le suivant :

  1 package com.tree.traverse;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 /**  7  * @author Caijh  8  *  9  * 2017年6月2日 下午7:21:10 10  */ 11  12 public class BuildTreePreOrderInOrder { 13  14     /**  15      *              1 
 16      *             / \ 17      *            3   5 
 18      *           /     \ 19      *          7       11 20      *       /  
 21      *      9       
 22      */   23     public static int treeNode = 0;//记录先序遍历节点的个数 24     private List<Node> nodeList = new ArrayList<>();//层次遍历节点的队列 25     public static void main(String[] args) { 26         BuildTreePreOrderInOrder build = new BuildTreePreOrderInOrder(); 27         int[] preOrder = { 1, 3, 7, 9, 5, 11}; 28         int[] inOrder = { 9, 7, 3, 1, 5, 11}; 29          30         treeNode = preOrder.length;//初始化二叉树的节点数 31         Node root = build.buildTreePreOrderInOrder(preOrder, 0, preOrder.length - 1, inOrder, 0, preOrder.length - 1); 32         System.out.print("先序遍历:"); 33         build.preOrder(root); 34         System.out.print("\n中序遍历:"); 35         build.inOrder(root); 36         System.out.print("\n原二叉树:\n"); 37         build.prototypeTree(root); 38     } 39  40     /** 41      * 分治法 42      * 通过先序遍历结果和中序遍历结果还原二叉树 43      * @param preOrder    先序遍历结果序列 44      * @param preOrderBegin     先序遍历起始位置下标 45      * @param preOrderEnd    先序遍历末尾位置下标 46      * @param inOrder    中序遍历结果序列 47      * @param inOrderBegin    中序遍历起始位置下标 48      * @param inOrderEnd     中序遍历末尾位置下标 49      * @return 50      */ 51     public Node buildTreePreOrderInOrder(int[] preOrder, int preOrderBegin, int preOrderEnd, int[] inOrder, int inOrderBegin, int inOrderEnd) { 52         if (preOrderBegin > preOrderEnd || inOrderBegin > inOrderEnd) { 53             return null; 54         } 55         int rootData = preOrder[preOrderBegin];//先序遍历的第一个字符为当前序列根节点 56         Node head = new Node(rootData); 57         int divider = findIndexInArray(inOrder, rootData, inOrderBegin, inOrderEnd);//找打中序遍历结果集中根节点的位置 58         int offSet = divider - inOrderBegin - 1;//计算左子树共有几个节点,节点数减一,为数组偏移量 59         Node left = buildTreePreOrderInOrder(preOrder, preOrderBegin + 1, preOrderBegin + 1 + offSet, inOrder, inOrderBegin,inOrderBegin + offSet); 60         Node right = buildTreePreOrderInOrder(preOrder, preOrderBegin + offSet + 2, preOrderEnd, inOrder, divider + 1, inOrderEnd); 61         head.left = left; 62         head.right = right; 63         return head; 64     } 65     /** 66      * 通过先序遍历找到的rootData根节点,在中序遍历结果中区分出:中左子树和右子树 67      * @param inOrder    中序遍历的结果数组 68      * @param rootData    根节点位置 69      * @param begin    中序遍历结果数组起始位置下标 70      * @param end    中序遍历结果数组末尾位置下标 71      * @return return中序遍历结果数组中根节点的位置 72      */ 73     public int findIndexInArray(int[] inOrder, int rootData, int begin, int end) { 74         for (int i = begin; i <= end; i++) { 75             if (inOrder[i] == rootData) 76                 return i; 77         } 78         return -1; 79     } 80     /** 81      * 二叉树先序遍历结果 82      * @param n 83      */ 84     public void preOrder(Node n) { 85         if (n != null) { 86             System.out.print(n.val + ","); 87             preOrder(n.left); 88             preOrder(n.right); 89         } 90     } 91     /** 92      * 二叉树中序遍历结果 93      * @param n 94      */ 95     public void inOrder(Node n) { 96         if (n != null) { 97             inOrder(n.left); 98             System.out.print(n.val + ","); 99             inOrder(n.right);100         }101     }102     /**103      * 还原后的二叉树104      * 二叉数层次遍历105      * 基本思想:106      *     1.因为推导出来的二叉树是保存在Node类对象的子对象里面的,(类似于c语言的结构体)如果通过递归实现层次遍历的话,不容易实现107      *     2.这里采用List队列逐层保存Node对象节点的方式实现对二叉树的层次遍历输出108      *     3.如果父节点的位置为i,那么子节点的位置为,2i 和 2i+1;依据这个规律逐层遍历,通过保存的父节点,找到子节点。并保存,不断向下遍历保存。109      * @param tree110      */111     public void prototypeTree(Node tree){112         //用list存储层次遍历的节点113         if(tree !=null){114             if(tree!=null)115                 nodeList.add(tree);116             nodeList.add(tree.left);117             nodeList.add(tree.right);118             int count=3;119             //从第三层开始120             for(int i=3;count<treeNode;i++){121                 //第i层第一个子节点的父节点的位置下标122                 int index = (int) Math.pow(2, i-1-1)-1;123                 /**124                  * 二叉树的每一层节点数遍历125                  * 因为第i层的最大节点数为2的i-1次方个,126                  */127                 for(int j=1;j<=Math.pow(2, i-1);){128                     //计算有效的节点的个数,和遍历序列的总数做比较,作为判断循环结束的标志129                     if(nodeList.get(index).left!=null)130                         count++;131                     if(nodeList.get(index).right!=null)132                         count++;133                     nodeList.add(nodeList.get(index).left);134                     nodeList.add(nodeList.get(index).right);135                     index++;136                     if(count>=treeNode)//当所有有效节点都遍历到了就结束遍历137                         break;138                     j+=2;//每次存储两个子节点,所以每次加2139                 }140             }141             int flag=0,floor=1;142             for(Node node:nodeList){143                 if(node!=null)144                     System.out.print(node.val+" ");145                 else146                     System.out.print("# ");//#号表示空节点147                 flag++;148                 /**149                  * 逐层遍历输出二叉树150                  * 
151                  */152                 if(flag>=Math.pow(2, floor-1)){153                     flag=0;154                     floor++;155                     System.out.println();156                 }157             }158         }159     }160     /**161      * 内部类162      * 1.每个Node类对象为一个节点,163      * 2.每个节点包含根节点,左子节点和右子节点164      */165     class Node {166         Node left;167         Node right;168         int val;169         public Node(int val) {170             this.val = val;171         }172     }173 }
Copier après la connexion

Résultat d'exécution :

Enfin, l'idée de base de la sortie de l'arbre binaire couche par couche :
* 1. Parce que l'arbre binaire dérivé est stocké dans le sous-objet de l'objet de classe Node , (similaire à la structure du langage c) s'il n'est pas facile d'implémenter un parcours hiérarchique par récursion
* 2. Ici, la file d'attente List est utilisée pour enregistrer les nœuds d'objet Node couche par couche afin de réaliser la sortie de parcours hiérarchique de l'arbre binaire
* 3. Si la position du nœud parent est i, alors les positions des nœuds enfants sont 2i et 2i+1 selon cette règle, parcourez couche par couche et trouvez les nœuds enfants à travers les fichiers enregistrés ; nœud parent. Et enregistrez, continuez à descendre pour enregistrer.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
2 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Java comment parcourir un dossier et obtenir tous les noms de fichiers Java comment parcourir un dossier et obtenir tous les noms de fichiers Mar 29, 2024 pm 01:24 PM

Java est un langage de programmation populaire doté de puissantes capacités de gestion de fichiers. En Java, parcourir un dossier et obtenir tous les noms de fichiers est une opération courante, qui peut nous aider à localiser et traiter rapidement les fichiers dans un répertoire spécifique. Cet article explique comment implémenter une méthode permettant de parcourir un dossier et d'obtenir tous les noms de fichiers en Java, et fournit des exemples de code spécifiques. 1. Utilisez la méthode récursive pour parcourir le dossier. Nous pouvons utiliser la méthode récursive pour parcourir le dossier. La méthode récursive est un moyen de s'appeler, qui peut parcourir efficacement le dossier.

Exemple d'utilisation de la fonction PHP glob() : parcourir tous les fichiers d'un dossier spécifié Exemple d'utilisation de la fonction PHP glob() : parcourir tous les fichiers d'un dossier spécifié Jun 27, 2023 am 09:16 AM

Exemple d'utilisation de la fonction PHPglob() : Parcourir tous les fichiers d'un dossier spécifié Dans le développement PHP, il est souvent nécessaire de parcourir tous les fichiers d'un dossier spécifié pour implémenter une opération par lots ou une lecture de fichiers. La fonction glob() de PHP est utilisée pour répondre à cette exigence. La fonction glob() peut obtenir les informations de chemin de tous les fichiers qui remplissent les conditions dans le dossier spécifié en spécifiant un modèle de correspondance générique. Dans cet article, nous allons montrer comment utiliser la fonction glob() pour parcourir tous les fichiers d'un dossier spécifié.

Comparaison approfondie de Java Iterator et Iterable : analyse des avantages et des inconvénients Comparaison approfondie de Java Iterator et Iterable : analyse des avantages et des inconvénients Feb 19, 2024 pm 04:20 PM

Différences conceptuelles : Itérateur : Iterator est une interface qui représente un itérateur qui obtient les valeurs d'une collection. Il fournit des méthodes telles que MoveNext(), Current() et Reset(), vous permettant de parcourir les éléments de la collection et d'opérer sur l'élément actuel. Iterable : Iterable est également une interface, représentant un objet itérable. Il fournit la méthode Iterator(), qui renvoie un objet Iterator pour faciliter la traversée des éléments de la collection. Utilisation : Iterator : Pour utiliser Iterator, vous devez d'abord obtenir un objet Iterator, puis appeler la méthode MoveNext() pour passer au suivant.

Comment utiliser le module os pour parcourir des fichiers dans un répertoire en Python 3.x Comment utiliser le module os pour parcourir des fichiers dans un répertoire en Python 3.x Jul 29, 2023 pm 02:57 PM

Comment utiliser le module os pour parcourir des fichiers dans un répertoire en Python3.x En Python, nous pouvons utiliser le module os pour faire fonctionner des fichiers et des répertoires. Le module os est un module important de la bibliothèque standard Python, fournissant de nombreuses fonctions liées au système d'exploitation. Dans cet article, nous expliquerons comment utiliser le module os pour parcourir tous les fichiers d'un répertoire. Tout d'abord, nous devons importer le module os : importos Ensuite, nous pouvons utiliser la fonction os.walk() pour parcourir le répertoire.

Insérer et parcourir de manière récursive une liste chaînée en C++ Insérer et parcourir de manière récursive une liste chaînée en C++ Sep 10, 2023 am 09:21 AM

Nous obtenons les valeurs entières utilisées pour former la liste chaînée. La tâche consiste d'abord à insérer puis à parcourir la liste à chaînage unique en utilisant la méthode récursive. Ajouter un nœud de manière récursive à la fin si la tête est NULL → ajouter un nœud à la tête sinon ajouter à la tête (tête → suivant) parcourir les nœuds de manière récursive si la tête est NULL → quitter sinon imprimer (tête → suivant) Exemple d'entrée −1-2-7-9 -10 sortie sortiestrong>− liste chaînée : 1→2→7→9→10→NULL entrée−12-21-17-94-18 sortie− liste chaînée : 12→21→17→94→18→NULL utilisé dans le programme suivant La méthode est la suivante Dans cette méthode, nous utiliserons la fonction pour ajouter des nœuds et parcourir la liste chaînée unique et passer

Fonction range() de Python : générer une séquence de nombres Fonction range() de Python : générer une séquence de nombres Nov 18, 2023 am 11:51 AM

Fonction range() de Python : génère une séquence de nombres, des exemples de code spécifiques sont nécessaires. Python est un langage de programmation puissant avec de nombreuses fonctions intégrées très utiles pour écrire des programmes. L’une d’elles est la fonction range(), qui est utilisée pour générer une séquence de nombres. Cet article présentera en détail l'utilisation de la fonction range() et l'illustrera à travers des exemples de code spécifiques. La syntaxe de base de la fonction range() est la suivante : range(start,stop,step) où, s

Java Iterator et Iterable : percer les mystères de la traversée des collections Java Java Iterator et Iterable : percer les mystères de la traversée des collections Java Feb 19, 2024 pm 11:50 PM

Interface Iterator L'interface Iterator est une interface définie dans le framework de collection Java. Elle fournit une série de méthodes pour parcourir les éléments de collection. L'interface Iterator définit les méthodes principales suivantes : hasNext() : renvoie une valeur booléenne indiquant si l'élément suivant existe. next() : renvoie l'élément suivant. S'il n'y a pas d'élément suivant, une NoSuchElementException est levée. Remove() : supprime l'élément actuellement pointé. Voici un exemple de code permettant de parcourir une collection à l'aide de l'interface Iterator : Listlist=newArrayList();list

Java Iterator et Iterable : la clé du parcours de collection, démystifiée Java Iterator et Iterable : la clé du parcours de collection, démystifiée Feb 20, 2024 am 10:27 AM

Introduction à IteratorIterator est une interface en Java permettant de parcourir des collections. Il fournit un ensemble de méthodes qui vous permettent d'accéder aux éléments d'une collection de manière séquentielle. Vous pouvez utiliser Iterator pour parcourir des types de collections tels que List, Set et Map. Code de démonstration : Listlist=newArrayList();list.add("one");list.add("two");list.add("trois");Iteratoriterator=list.iterator();while(iter

See all articles