二叉树链式存储的建立,遍历等
#include<stdio.h> #include<malloc.h> struct BTNode{ char data;//数据域 struct BTNode * pLchild;//p是指针,L是左,child是孩子;即为左子树指针 struct BTNode * pRchild//右子树指针 } //函数声明 struct BTNode * CreateBTree();//生成根节点地址和二叉树 PreTraverseBTree();//先序遍历 InTraverseBTree();//中序遍历 PostTraverseBTree();//后序遍历 int main(){ struct BTNode * pT = CreateBTree();//获取根节点地址 PreTraverseBTree(pT);//先序遍历 InTraverseBTree(pT);//中序遍历 PostTraverseBTree(pT);//后序遍历 return 0; } struct BTNode * CreateBTree(){ //静态声明结点,动态分配内存 struct BTNode pA = (struct BTNode *)malloc(sizeof(struct BTNode)); struct BTNode pB = (struct BTNode *)malloc(sizeof(struct BTNode)); struct BTNode pC = (struct BTNode *)malloc(sizeof(struct BTNode)); struct BTNode pD = (struct BTNode *)malloc(sizeof(struct BTNode)); struct BTNode pE = (struct BTNode *)malloc(sizeof(struct BTNode)); //各个结点数据域存值 pA->data = 'A'; pB->data = 'B'; pC->data = 'C'; pD->data = 'D'; pE->data = 'E'; //每个结点的左右指针域都要指向一个地址,注:为空就写NULL pA->pLchild = pB;//根节点A的左指针域指向B结点的地址 pA->pRchild = pC;//根节点A的右指针域指向C结点的地址 pB->pLchild = pB->pRchild = NULL;//结点B的左右指针域都为空 pC->pLchild = pD;//节点C的左指针域指向D结点的地址 pC->pRchild = NULL;//结点C的右指针域为空 pD->pLchild = NULL;//结点D的左指针域为空 pD->pRchild = pE;//结点D的右指针域指向E结点的地址 pE->pLchild = pE->pRchild = NULL;//结点E的左右指针域都为空 return pA;//返回根节点A的地址 } //先序遍历 PreTraverseBTree(struct BTNode * pT){ //每次递归加判断,若先遍历左子树全部为空就结束递归,才能遍历右子树 if(pT!=NULL){ printf("%c\n",pT->data);//先访问根节点 if(pT->pLchild!=NULL){ PreTraverseBTree(pT->pLchild);//pT->pLchild可以代表整个左子树 }//再访问左子树 if((pT->pRchild!=NULL){ PreTraverseBTree(pT->pRchild);//pT->pRchild可以代表整个右子树 }//最后访问右子树 } } //中序遍历 InTraverseBTree(struct BTNode * pT){ if(pT!=NULL){ if(pT->pLchild!=NULL){ PreTraverseBTree(pT->pLchild);//pT->pLchild可以代表整个左子树 }//先访问左子树 printf("%c\n",pT->data);//再访问根节点 if((pT->pRchild!=NULL){ PreTraverseBTree(pT->pRchild);//pT->pRchild可以代表整个右子树 }//最后访问右子树 } } //后序遍历 PostTraverseBTree(struct BTNode * pT){ if(pT!=NULL){ if(pT->pLchild!=NULL){ PreTraverseBTree(pT->pLchild);//pT->pLchild可以代表整个左子树 }//先访问左子树 if((pT->pRchild!=NULL){ PreTraverseBTree(pT->pRchild);//pT->pRchild可以代表整个右子树 }//再访问右子树 printf("%c\n",pT->data);//最后访问根节点 } }
二叉树的两种遍历(迭代递归)
二叉树的前序遍历
示例:
输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3]
解答1(递归)
class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); helper(root,res); return res; } public void helper(TreeNode root,List<Integer> res){ if(root != null){ res.add(root.val);//先输出节点的值 if(root.left != null){ helper(root.left,res); } if(root.right != null){ helper(root.right,res); } } } }
解答2(DFS深度优先遍历)
class Solution { public List<Integer> preorderTraversal(TreeNode root) { LinkedList<TreeNode> stack = new LinkedList<>(); LinkedList<Integer> output = new LinkedList<>(); if (root == null) { return output; } stack.add(root); while (!stack.isEmpty()) {//因为开始就会放入根节点的左右字树节点,所以直到最后为空才完成遍历 TreeNode node = stack.pollLast();//返回栈顶的值并从栈中删除节点 output.add(node.val);//在***中加入这个值 if (node.right != null) { stack.add(node.right); } if (node.left != null) { stack.add(node.left); } } return output; } }