算法

1,926 阅读2分钟

1 单向链表反转

1.1 思路

单向链表反转其实是把每个节点的指针域由原来的指向下一个节点,变为指向前一个节点。

  1. 需要三个变量,前驱结点preNode,当前节点curNode,下一个节点nextNode。
  2. 遍历单链表
    • nextNode指向curNode.next
    • curNode的指针域指向前一个节点
    • preNode指向curNode
    • curtNode指向nextNode 直到遍历到最后一个节点为止。
  3. 返回preNode

1.2 代码

public class Node {
    
    private Object data;//数据域
    private Node next;//指针域
 
    public Node(Object data){
        this.data = data;
    }
 
    public Node(Object data,Node next){
        this.data = data;
        this.next = next;
    }
 
    public Object getData() {
        return data;
    }
 
    public void setData(Object data) {
        this.data = data;
    }
 
    public Node getNext() {
        return next;
    }
 
    public void setNext(Node next) {
        this.next = next;
    }
 
}
public static Node reverseListNode(Node head){
        //单链表为空或只有一个节点,直接返回原单链表
        if (head == null || head.getNext() == null){
            return head;
        }
        //前一个节点指针
        Node preNode = null;
        //当前节点指针
        Node curNode = head;
        //下一个节点指针
        Node nextNode = null;
 
        while (curNode != null){
            nextNode = curNode.getNext();//nextNode 指向下一个节点
            curNode.setNext(preNode);//将当前节点next域指向前一个节点
            preNode = curNode;//preNode 指针向后移动
            curNode = nextNode;//curNode指针向后移动
        }
 
        return preNode;
    }

2 二叉树遍历

图片.png

二叉树常用的遍历方式有:前序遍历、中序遍历、后序遍历、层序遍历四种遍历方式,不同的遍历算法,其思想略有不同,我们来看一下这四种遍历方法主要的算法思想:

1、先序遍历二叉树顺序:根节点 –> 左子树 –> 右子树,即先访问根节点,然后是左子树,最后是右子树。 上图中二叉树的前序遍历结果为:0 -> 1 -> 3 -> 4 -> 2 -> 5 -> 6


/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        if(null == root){
            return result;
        }
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode node = stack.pop();
            result.add(node.val);
            if(node.right != null){
                stack.push(node.right);
            }
            if(node.left != null){
                stack.push(node.left);
            }
        }
        return result;
    }
}

2、中序遍历二叉树顺序:左子树 –> 根节点 –> 右子树,即先访问左子树,然后是根节点,最后是右子树。
上图中二叉树的中序遍历结果为:3 -> 1 -> 4 -> 0 -> 5 -> 2 -> 6

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        if(null == root){
            return result;
        }
        Stack stack = new Stack<TreeNode>();
        TreeNode curNode = root;
        while(curNode != null || !stack.isEmpty()){
            while(curNode != null){
                stack.push(curNode);
                curNode = curNode.left;  
            }
            curNode = (TreeNode)stack.pop();
            result.add(curNode.val);
            curNode = curNode.right;
        }
        return result;
    }
}

3、后续遍历二叉树顺序:左子树 –> 右子树 –> 根节点,即先访问左子树,然后是右子树,最后是根节点。
上图中二叉树的后序遍历结果为:3 -> 4 -> 1 -> 5 -> 6 -> 2 -> 0

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> result = new ArrayList<>();
        TreeNode curNode = root;
        TreeNode preNode = null; //记录上一节点
        while(!stack.isEmpty() || curNode != null){
            while(curNode != null){
                stack.push(curNode);
                curNode = curNode.left;
            }
            curNode = stack.peek();
            //后序遍历的过程中在遍历完左子树跟右子树cur都会回到根结点。所以当前不管是从左子树还是右子树回到根结点都不应该再操作了,应该退回上层。
            //如果是从右边再返回根结点,应该回到上层。
            //主要就是判断出来的是不是右子树,是的话就可以把根节点=加入到list了
            if(curNode.right == null || curNode.right == preNode){
                result.add(curNode.val);
                stack.pop();
                preNode = curNode;
                curNode = null;
            } else {
                curNode = curNode.right;
            }
        }
        return result;
    }
}

4、层序遍历二叉树顺序:从最顶层的节点开始,从左往右依次遍历,之后转到第二层,继续从左往右遍历,持续循环,直到所有节点都遍历完成
上图中二叉树的层序遍历结果为:0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6