java二叉树遍历算法
- 格式:docx
- 大小:36.94 KB
- 文档页数:1
java treemap 遍历方法全文共四篇示例,供读者参考第一篇示例:Java TreeMap 是Java 集合框架中的一个实现类,它实现了Map 接口,并基于红黑树实现了可排序的键值对集合。
TreeMap 是一个有序的键值对集合,根据键的自然顺序或者比较器进行排序。
在TreeMap 中,键值对是按照键的顺序存储的,而不是插入的顺序。
在Java 中,遍历TreeMap 可以使用多种方法,我们先来看看TreeMap 中常用的遍历方式:1. 使用entrySet() 方法遍历TreeMapentrySet() 方法返回一个包含Map.Entry 的Set 集合,其中每一个Map.Entry 对象都包含了键和值。
通过遍历entrySet() 方法返回的Set 集合,我们可以轻松地遍历TreeMap 中的所有键值对。
```javaTreeMap<String, Integer> treeMap = new TreeMap<>();treeMap.put("A", 1);treeMap.put("B", 2);treeMap.put("C", 3);for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {String key = entry.getKey();Integer value = entry.getValue();System.out.println("Key: " + key + ", Value: " + value);}```在上面的代码中,我们先创建了一个TreeMap 对象,并向其中添加了三组键值对。
然后通过keySet() 方法获取到包含所有键的Set 集合,然后通过foreach 循环遍历每个键,通过键获取对应的值并打印出来。
⼆叉树的遍历及常⽤算法⼆叉树的遍历及常⽤算法遍历的定义:按照某种次序访问⼆叉树上的所有结点,且每个节点仅被访问⼀次;遍历的重要性:当我们需要对⼀颗⼆叉树进⾏,插⼊,删除,查找等操作时,通常都需要先遍历⼆叉树,所有说:遍历是⼆叉树的基本操作;遍历思路:⼆叉树的数据结构是递归定义(每个节点都可能包含相同结构的⼦节点),所以遍历也可以使⽤递归,即结点不为空则继续递归调⽤每个节点都有三个域,数据与,左孩⼦指针和右孩⼦之指针,每次遍历只需要读取数据,递归左⼦树,递归右⼦树,这三个操作三种遍历次序:根据访问三个域的不同顺序,可以有多种不同的遍历次序,⽽通常对于⼦树的访问都按照从左往右的顺序;设:L为遍历左⼦树,D为访问根结点,R为遍历右⼦树,且L必须位于R的前⾯可以得出以下三种不同的遍历次序:先序遍历操作次序为DLR,⾸先访问根结点,其次遍历根的左⼦树,最后遍历根右⼦树,对每棵⼦树同样按这三步(先根、后左、再右)进⾏中序遍历操作次序为LDR,⾸先遍历根的左⼦树,其次访问根结点,最后遍历根右⼦树,对每棵⼦树同样按这三步(先左、后根、再右)进⾏后序遍历操作次序为LRD,⾸先遍历根的左⼦树,其次遍历根的右⼦树,最后访问根结点,对每棵⼦树同样按这三步(先左、后右、最后根)进⾏层次遍历层次遍历即按照从上到下从左到右的顺序依次遍历所有节点,实现层次遍历通常需要借助⼀个队列,将接下来要遍历的结点依次加⼊队列中;遍历的应⽤“遍历”是⼆叉树各种操作的基础,可以在遍历过程中对结点进⾏各种操作,如:对于⼀棵已知⼆叉树求⼆叉树中结点的个数求⼆叉树中叶⼦结点的个数;求⼆叉树中度为1的结点个数求⼆叉树中度为2的结点个数5求⼆叉树中⾮终端结点个数交换结点左右孩⼦判定结点所在层次等等...C语⾔实现:#include <stdio.h>//⼆叉链表数据结构定义typedef struct TNode {char data;struct TNode *lchild;struct TNode *rchild;} *BinTree, BinNode;//初始化//传⼊⼀个指针令指针指向NULLvoid initiate(BinTree *tree) {*tree = NULL;}//创建树void create(BinTree *BT) {printf("输⼊当前结点值: (0则创建空节点)\n");char data;scanf(" %c", &data);//连续输⼊整形和字符时.字符变量会接受到换⾏,所以加空格if (data == 48) {*BT = NULL;return;} else {//创建根结点//注意开辟的空间⼤⼩是结构体的⼤⼩⽽不是结构体指针⼤⼩,写错了不会⽴马产⽣问题,但是后续在其中存储数据时极有可能出现内存访问异常(飙泪....) *BT = malloc(sizeof(struct TNode));//数据域赋值(*BT)->data = data;printf("输⼊节点 %c 的左孩⼦ \n", data);create(&((*BT)->lchild));//递归创建左⼦树printf("输⼊节点 %c 的右孩⼦ \n", data);create(&((*BT)->rchild));//递归创建右⼦树}}//求双亲结点(⽗结点)BinNode *Parent(BinTree tree, char x) {if (tree == NULL)return NULL;else if ((tree->lchild != NULL && tree->lchild->data == x) || (tree->rchild != NULL && tree->rchild->data == x))return tree;else{BinNode *node1 = Parent(tree->lchild, x);BinNode *node2 = Parent(tree->rchild, x);return node1 != NULL ? node1 : node2;}}//先序遍历void PreOrder(BinTree tree) {if (tree) {//输出数据printf("%c ", tree->data);//不为空则按顺序继续递归判断该节点的两个⼦节点PreOrder(tree->lchild);PreOrder(tree->rchild);}}//中序void InOrder(BinTree tree) {if (tree) {InOrder(tree->lchild);printf("%c ", tree->data);InOrder(tree->rchild);}}//后序void PostOrder(BinTree tree) {if (tree) {PostOrder(tree->lchild);PostOrder(tree->rchild);printf("%c ", tree->data);}}//销毁结点递归free所有节点void DestroyTree(BinTree *tree) {if (*tree != NULL) {printf("free %c \n", (*tree)->data);if ((*tree)->lchild) {DestroyTree(&((*tree)->lchild));}if ((*tree)->rchild) {DestroyTree(&((*tree)->rchild));}free(*tree);*tree = NULL;}}// 查找元素为X的结点使⽤的是层次遍历BinNode *FindNode(BinTree tree, char x) {if (tree == NULL) {return NULL;}//队列BinNode *nodes[1000] = {};//队列头尾位置int front = 0, real = 0;//将根节点插⼊到队列尾nodes[real] = tree;real += 1;//若队列不为空则继续while (front != real) {//取出队列头结点输出数据BinNode *current = nodes[front];if (current->data == x) {return current;}front++;//若当前节点还有⼦(左/右)节点则将结点加⼊队列if (current->lchild != NULL) {nodes[real] = current->lchild;real++;}if (current->rchild != NULL) {nodes[real] = current->rchild;real++;}}return NULL;}//层次遍历// 查找元素为X的结点使⽤的是层次遍历void LevelOrder(BinTree tree) {if (tree == NULL) {return;}//队列BinNode *nodes[1000] = {};//队列头尾位置int front = 0, real = 0;//将根节点插⼊到队列尾nodes[real] = tree;real += 1;//若队列不为空则继续while (front != real) {//取出队列头结点输出数据BinNode *current = nodes[front];printf("%2c", current->data);front++;//若当前节点还有⼦(左/右)节点则将结点加⼊队列if (current->lchild != NULL) {nodes[real] = current->lchild;real++;}if (current->rchild != NULL) {nodes[real] = current->rchild;real++;}}}//查找x的左孩⼦BinNode *Lchild(BinTree tree, char x) {BinTree node = FindNode(tree, x);if (node != NULL) {return node->lchild;}return NULL;}//查找x的右孩⼦BinNode *Rchild(BinTree tree, char x) {BinTree node = FindNode(tree, x);if (node != NULL) {return node->rchild;}return NULL;}//求叶⼦结点数量int leafCount(BinTree *tree) {if (*tree == NULL)return 0;//若左右⼦树都为空则该节点为叶⼦,且后续不⽤接续递归了else if (!(*tree)->lchild && !(*tree)->rchild)return 1;else//若当前结点存在⼦树,则递归左右⼦树, 结果相加return leafCount(&((*tree)->lchild)) + leafCount(&((*tree)->rchild));}//求⾮叶⼦结点数量int NotLeafCount(BinTree *tree) {if (*tree == NULL)return 0;//若该结点左右⼦树均为空,则是叶⼦,且不⽤继续递归else if (!(*tree)->lchild && !(*tree)->rchild)return 0;else//若当前结点存在左右⼦树,则是⾮叶⼦结点(数量+1),在递归获取左右⼦树中的⾮叶⼦结点,结果相加 return NotLeafCount(&((*tree)->lchild)) + NotLeafCount(&((*tree)->rchild)) + 1;}//求树的⾼度(深度)int DepthCount(BinTree *tree) {if (*tree == NULL)return 0;else{//当前节点不为空则深度+1 在加上⼦树的⾼度,int lc = DepthCount(&((*tree)->lchild)) + 1;int rc = DepthCount(&((*tree)->rchild)) + 1;return lc > rc?lc:rc;// 取两⼦树深度的最⼤值 }}//删除左⼦树void RemoveLeft(BinNode *node){if (!node)return;if (node->lchild)DestroyTree(&(node->lchild));node->lchild = NULL;}//删除右⼦树void RemoveRight(BinNode *node){if (!node)return;if (node->rchild)DestroyTree(&(node->rchild));node->rchild = NULL;}int main() {BinTree tree;create(&tree);BinNode *node = Parent(tree, 'G');printf("G的⽗结点为%c\n",node->data);BinNode *node2 = Lchild(tree, 'D');printf("D的左孩⼦结点为%c\n",node2->data);BinNode *node3 = Rchild(tree, 'D');printf("D的右孩⼦结点为%c\n",node3->data);printf("先序遍历为:");PreOrder(tree);printf("\n");printf("中序遍历为:");InOrder(tree);printf("\n");printf("后序遍历为:");PostOrder(tree);printf("\n");printf("层次遍历为:");LevelOrder(tree);printf("\n");int a = leafCount(&tree);printf("叶⼦结点数为%d\n",a);int b = NotLeafCount(&tree);printf("⾮叶⼦结点数为%d\n",b);int c = DepthCount(&tree);printf("深度为%d\n",c);//查找F节点BinNode *node4 = FindNode(tree,'C');RemoveLeft(node4);printf("删除C的左孩⼦后遍历:");LevelOrder(tree);printf("\n");RemoveRight(node4);printf("删除C的右孩⼦后遍历:");LevelOrder(tree);printf("\n");//销毁树printf("销毁树 \n");DestroyTree(&tree);printf("销毁后后遍历:");LevelOrder(tree);printf("\n");printf("Hello, World!\n");return 0;}测试:测试数据为下列⼆叉树:运⾏程序复制粘贴下列内容:ABDGHECKFIJ特别感谢:iammomo。
c语言实现二叉树的四种遍历和求深度与叶子个数二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。
在C语言中,我们可以使用指针来实现二叉树的操作。
本文将介绍四种常见的二叉树遍历方式,以及如何求解二叉树的深度和叶子节点个数。
首先,我们需要定义一个二叉树节点的结构体,包含一个数据域和两个指针域,分别指向左子节点和右子节点。
代码如下:```cstruct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;};```接下来,我们可以实现二叉树的四种遍历方式:前序遍历、中序遍历、后序遍历和层序遍历。
前序遍历是指先访问根节点,然后递归地遍历左子树和右子树。
代码如下:```cvoid preorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}printf("%d ", root->data);preorderTraversal(root->left);preorderTraversal(root->right);}```中序遍历是指先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。
代码如下:```cvoid inorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}```后序遍历是指先递归地遍历左子树和右子树,最后访问根节点。
代码如下:```cvoid postorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}postorderTraversal(root->left);postorderTraversal(root->right);printf("%d ", root->data);}```层序遍历是按照树的层次逐层遍历节点。
二叉树的先序,中序,后序遍历c语言
二叉树是常见的数据结构,具有广泛的应用场景,例如搜索树、哈夫曼树等。
其中比较重要的一点就是对二叉树的遍历。
二叉树遍历有三种方式:先序遍历、中序遍历、后序遍历。
接下来,我将通过C语言来详细介绍这三种遍历方式。
一、先序遍历(Preorder Traversal)
先序遍历是指根节点->左子树->右子树的遍历方式。
C语言中的先序遍历算法如下:
```
void preorderTraversal(Node *node) {
if (node != NULL) {
printf("%d ", node->data); // 打印节点值
preorderTraversal(node->left); // 递归遍历左子树
preorderTraversal(node->right); // 递归遍历右子树
}
}
```
先序遍历的实现通过递归调用实现,当节点为空即遍历完成时返回。
总结:
以上三种遍历方式是二叉树遍历中最基本的方法,它们都是基于递归实现的。
通过学习这三种遍历方式,可以更好地理解二叉树的结构特点,提高数据结构算法的学习效果。
二叉树常用的三种遍历方法二叉树是一种常用的数据结构,它由一个根节点和两个子节点组成,其中左子节点小于根节点,右子节点大于根节点。
遍历二叉树是对所有节点进行访问的过程,常用的三种遍历方法是前序遍历、中序遍历和后序遍历。
下面将详细介绍这三种方法的实现步骤。
一、前序遍历前序遍历是指先访问根节点,然后按照左子树、右子树的顺序依次访问每个节点。
具体实现步骤如下:1. 如果当前节点为空,则返回。
2. 访问当前节点。
3. 递归进入左子树。
4. 递归进入右子树。
代码实现:void preorderTraversal(TreeNode* root) {if (root == NULL) return;cout << root->val << " ";preorderTraversal(root->left);preorderTraversal(root->right);}二、中序遍历中序遍历是指先访问左子树,然后访问根节点,最后访问右子树。
具体实现步骤如下:1. 如果当前节点为空,则返回。
2. 递归进入左子树。
3. 访问当前节点。
4. 递归进入右子树。
代码实现:void inorderTraversal(TreeNode* root) {if (root == NULL) return;inorderTraversal(root->left);cout << root->val << " ";inorderTraversal(root->right);}三、后序遍历后序遍历是指先访问左子树,然后访问右子树,最后访问根节点。
具体实现步骤如下:1. 如果当前节点为空,则返回。
2. 递归进入左子树。
3. 递归进入右子树。
4. 访问当前节点。
代码实现:void postorderTraversal(TreeNode* root) {if (root == NULL) return;postorderTraversal(root->left);postorderTraversal(root->right);cout << root->val << " ";}总结:以上就是二叉树常用的三种遍历方法的详细介绍和实现步骤。
java二叉树遍历算法
Java二叉树遍历是指通过沿着树的深度遍历每个节点来检索树中的所有节点的算法技术。
浅显地讲,它采用层次方式,从树根向下依次访问每个节点,直到抵达叶子节点。
它是一种非常有用的树检索算法,在不同的情况下可能用到不同的遍历策略,如前序遍历、中序遍历、后序遍历等。
通常情况下,Java二叉树遍历有三种常见的遍历模式,分别是前序遍历、中序遍历和后序遍历,每种遍历模式都有其特定的应用场景。
前序遍历的特性是对树的每个节点都按以下顺序访问:根节点、左子树节点和右子树节点,比较常用于树的克隆操作中;中序遍历是:左子树节点、根节点和右子树节点,很适合树形表示算法中的构建;后序遍历是:左子树节点、右子树节点和根节点,比较适合用于计算叶子节点的数量或者进行节点释放操作。
不论哪一种遍历模式,它们都具有共同的思想,即可以借助栈的数据结构,依次把当前的节点的右子树、节点本身和左子树依次放入栈中,以便进行下一轮的遍历,直到拿到一个空节点,就可以访问另一个节点。
因此,对于二叉树遍历,其实无论何种遍历策略,都是采用深度优先搜索作为基础,针对特定的需求采用某种访问策略,这样才能达到最佳的效果。
另外,Java 二叉树遍历 imooc 价值课程更是让构造Java树的难题变得更加容易,对于对Java 数据结构有兴趣的同学津津乐道!
本文介绍了Java二叉树遍历技术的知识背景,以及它的三种核心遍历模式,前序遍历、中序遍历和后序遍历。
作为一种有效的数据结构技术,Java二叉树遍历能方便地检索树中的所有节点,可以为树形算法的构建提供方便,受到许多技术人员的青睐,在日常的工作中也有着良好的应用前景。