• 编码技巧之数据结构【笔记】


    编码技巧之数据结构【笔记】

    数据结构回顾

    列表中的数组,链表,队列,栈

    树中的二叉树,搜索树,堆/优先队列


    图中的无向图,有向图,有向无环图

    图的算法中的深度优先遍历,广度优先遍历,拓扑排序和最短路径/最小生成树

    树的遍历

    二叉树的遍历方法:

    前序遍历

    先遍历树根,然后前序遍历左子树,然后再前序遍历右子树

    中序遍历

    先中序遍历左子树,然后遍历树根,然后再中序遍历右子树

    后序遍历

    先后序遍历左子树,然后后序遍历右子树,然后遍历树根

    层次遍历

    一层一层的遍历下去,自左向右,自上而下

    树的基础代码:

    package interview.tree;
    
    public class TreeNode {
      private final char value;
      private TreeNode left;
      private TreeNode right;
      private TreeNode parent;
    
      public TreeNode(char value) {
        this.value = value;
        this.left = null;
        this.right = null;
        this.parent = null;
      }
    
      public char getValue() {
        return value;
      }
    
      public TreeNode getLeft() {
        return left;
      }
    
      public void setLeft(TreeNode left) {
        this.left = left;
        if (this.left != null) {
          this.left.setParent(this);
        }
      }
    
      public TreeNode getRight() {
        return right;
      }
    
      public void setRight(TreeNode right) {
        this.right = right;
        if (this.right != null) {
          this.right.setParent(this);
        }
      }
    
      public TreeNode getParent() {
        return parent;
      }
    
      private void setParent(TreeNode parent) {
        this.parent = parent;
      }
    }
    

    例题一:根据前序中序构造二叉树

    我们可以发现左子树前序为BDEG,左子树中序为DBGE

    具体代码如下:

    package interview.tree;
    
    public class TreeCreator {
      public TreeNode createSampleTree() {
        TreeNode root = new TreeNode('A');
        root.setLeft(new TreeNode('B'));
        root.getLeft().setLeft(new TreeNode('D'));
        root.getLeft().setRight(new TreeNode('E'));
        root.getLeft().getRight().setLeft(new TreeNode('G'));
        root.setRight(new TreeNode('C'));
        root.getRight().setRight(new TreeNode('F'));
        return root;
      }
    
      public TreeNode createTree(String preOrder, String inOrder) {
        if (preOrder.isEmpty()) {
          return null;
        }
    
        char rootValue = preOrder.charAt(0);
        int rootIndex = inOrder.indexOf(rootValue);
    
        TreeNode root = new TreeNode(rootValue);
        root.setLeft(
            createTree(
                preOrder.substring(1, 1 + rootIndex),
                inOrder.substring(0, rootIndex)));
        root.setRight(
            createTree(
                preOrder.substring(1 + rootIndex),
                inOrder.substring(1 + rootIndex)));
    
        return root;
      }
    }
    

    TreeTraversal.java

    	package interview.tree;
    	
    	public class TreeTraversal {
    	
    	  public void preOrder(TreeNode root) {
    	    if (root == null) {
    	      return;
    	    }
    	    System.out.print(root.getValue());
    	    preOrder(root.getLeft());
    	    preOrder(root.getRight());
    	  }
    	
    	  public void inOrder(TreeNode root) {
    	    if (root == null) {
    	      return;
    	    }
    	    inOrder(root.getLeft());
    	    System.out.print(root.getValue());
    	    inOrder(root.getRight());
    	  }
    	
    	  public void postOrder(TreeNode root) {
    	    if (root == null) {
    	      return;
    	    }
    	    postOrder(root.getLeft());
    	    postOrder(root.getRight());
    	    System.out.print(root.getValue());
    	  }
    	
    	  public String postOrder(String preOrder, String inOrder) {
    	    if (preOrder.isEmpty()) {
    	      return "";
    	    }
    	
    	    char rootValue = preOrder.charAt(0);
    	    int rootIndex = inOrder.indexOf(rootValue);
    	
    	    return
    	        postOrder(
    	            preOrder.substring(1, 1 + rootIndex),
    	            inOrder.substring(0, rootIndex)) +
    	        postOrder(
    	            preOrder.substring(1 + rootIndex),
    	            inOrder.substring(1 + rootIndex)) +
    	        rootValue;
    	  }
    	
    	  public static void main(String[] args) {
    	    TreeCreator creator = new TreeCreator();
    	    TreeTraversal traversal = new TreeTraversal();
    	
    	    System.out.println("Sample tree traversal");
    	    System.out.println("=====");
    	    TreeNode sampleTree = creator.createSampleTree();
    	    traversal.preOrder(sampleTree);
    	    System.out.println();
    	    traversal.inOrder(sampleTree);
    	    System.out.println();
    	    traversal.postOrder(sampleTree);
    	    System.out.println();
    	
    	    System.out.println("=====");
    	    System.out.println("Creating tree from preOrder and inOrder");
    	    System.out.println("=====");
    	    TreeNode tree = creator.createTree("ABDEGCF", "DBGEACF");
    	    traversal.postOrder(tree);
    	    System.out.println();
    	    traversal.postOrder(creator.createTree("", ""));
    	    System.out.println();
    	    traversal.postOrder(creator.createTree("A", "A"));
    	    System.out.println();
    	    traversal.postOrder(creator.createTree("AB", "BA"));
    	    System.out.println();
    	
    	    System.out.println("=====");
    	    System.out.println("Generating postOrder directly");
    	    System.out.println("=====");
    	    System.out.println(
    	        traversal.postOrder("ABDEGCF", "DBGEACF"));
    	    System.out.println(
    	        traversal.postOrder("", ""));
    	    System.out.println(
    	        traversal.postOrder("A", "A"));
    	    System.out.println(
    	        traversal.postOrder("AB", "BA"));
    	  }
    	}
    

    总结:

    在思考算法的时候,只要减小问题的规模即可

    对于初始值的确定,需要严格地根据递归函数的定义

    例题二:寻找中序遍历的时候的下一个结点

    具体代码如下:

    package interview.tree;
    
    public class InOrder {
    
      public TreeNode next(TreeNode node) {
        if (node == null) {
          return null;
        }
    
        if (node.getRight() != null) {
          return first(node.getRight());
        } else {
          while(node.getParent() != null
              && node.getParent().getRight() == node) {
            node = node.getParent();
          }
          // now we have:
          // node.getParent() == null
          // || node is left child of its parent
          return node.getParent();
        }
      }
    
      public TreeNode first(TreeNode root) {
        if (root == null) {
          return null;
        }
    
        TreeNode curNode = root;
        while(curNode.getLeft() != null) {
          curNode = curNode.getLeft();
        }
        return curNode;
      }
    
      public void traverse(TreeNode root) {
        for (TreeNode node = first(root);
            node != null;
            node = next(node)) {
          System.out.print(node.getValue());
        }
        System.out.println();
      }
    
      public static void main(String[] args) {
        TreeCreator creator = new TreeCreator();
        InOrder inOrder = new InOrder();
    
        TreeNode sampleTree = creator.createSampleTree();
        inOrder.traverse(sampleTree);
    
        inOrder.traverse(creator.createTree("", ""));
        inOrder.traverse(creator.createTree("A", "A"));
        inOrder.traverse(creator.createTree("AB", "BA"));
        inOrder.traverse(creator.createTree("ABCD", "DCBA"));
        inOrder.traverse(creator.createTree("ABCD", "ABCD"));
      }
    }
    

    总结:

    需要注意的是分情况讨论

    注意null指针

    使用private函数来维护复杂数据结构

    感谢观看,文笔有限,博客不出彩,还请多多见谅
  • 相关阅读:
    Apache Common-IO 使用
    Apache Compress-使用
    使用JavaConfig方式-Spring 基础学习
    设计模式-策略模式
    logback mybatis 打印sql语句
    oracle 迭代查询
    使用 Dom4j 将 XML 转换为 MAP
    Java连接Access数据库的那些坑
    如何从Maven中央存储库下载?
    sublime构建各个编译环境
  • 原文地址:https://www.cnblogs.com/jokingremarks/p/14468540.html
Copyright © 2020-2023  润新知