二叉树和链表复习

今天根据斯坦福大学的在线课程复习链表和二叉树

上面对于二叉树的递归定义非常简洁:

 a binary tree is either empty (represented by a null pointer), or is made of a single node, where the left and right pointers (recursive definition ahead) each point to a binary tree

 

二叉树的一个分支:二叉搜索树(binary search tree,BST),是所有左节点的值 <= 中间节点 ,右节点的值 > 中间节点。

这就是一棵二叉搜索树

 

BST的优点是便于插入和查找,在一棵数量为N的BST中插入和查找的算法复杂度是O(lgN),类似二分查找。

 

下面使用Java描述的二叉树,包括插入和查找的基本方法。另外说一点,面向对象的好处就是对外屏蔽不需要显示的细节,封装。

// BinaryTree.java 
public class BinaryTree { 
  // Root node pointer. Will be null for an empty tree. 
  private Node root; 
 

  /* 
   --Node-- 
   The binary tree is built using this nested node class. 
   Each node stores one data element, and has left and right 
   sub-tree pointer which may be null. 
   The node is a "dumb" nested class -- we just use it for 
   storage; it does not have any methods. 
  */ 
  private static class Node { 
    Node left; 
    Node right; 
    int data;

    Node(int newData) { 
      left = null; 
      right = null; 
      data = newData; 
    } 
  }

  /** 
   Creates an empty binary tree -- a null root pointer. 
  */ 
  public void BinaryTree() { 
    root = null; 
  } 
 

  /** 
   Returns true if the given target is in the binary tree. 
   Uses a recursive helper. 
  */ 
  public boolean lookup(int data) { 
    return(lookup(root, data)); 
  } 
 

  /** 
   Recursive lookup  -- given a node, recur 
   down searching for the given data. 
  */ 
  private boolean lookup(Node node, int data) { 
    if (node==null) { 
      return(false); 
    }

    if (data==node.data) { 
      return(true); 
    } 
    else if (data<node.data) { 
      return(lookup(node.left, data)); 
    } 
    else { 
      return(lookup(node.right, data)); 
    } 
  } 
 

  /** 
   Inserts the given data into the binary tree. 
   Uses a recursive helper. 
  */ 
  public void insert(int data) { 
    root = insert(root, data); 
  } 
 

  /** 
   Recursive insert -- given a node pointer, recur down and 
   insert the given data into the tree. Returns the new 
   node pointer (the standard way to communicate 
   a changed pointer back to the caller). 
  */ 
  private Node insert(Node node, int data) { 
    if (node==null) { 
      node = new Node(data); 
    } 
    else { 
      if (data <= node.data) { 
        node.left = insert(node.left, data); 
      } 
      else { 
        node.right = insert(node.right, data); 
      } 
    }

    return(node); // in any case, return the new pointer to the caller 
  } 

 

另外还有获得树的高度以及最小值的方法

 

//获得树的高度

/**
Returns the max root-to-leaf depth of the tree. Uses a recursive helper that recurs down to find the max depth. */ public int maxDepth() { return(maxDepth(root)); } private int maxDepth(Node node) { if (node==null) { return(0); } else { int lDepth = maxDepth(node.left); int rDepth = maxDepth(node.right); // use the larger + 1 return(Math.max(lDepth, rDepth) + 1); } } //获得最小值 /** Returns the min value in a non-empty binary search tree. Uses a helper method that iterates to the left to find the min value. */ public int minValue() { return( minValue(root) ); } /** Finds the min value in a non-empty binary search tree. */ private int minValue(Node node) { Node current = node; while (current.left != null) { current = current.left; } return(current.data); }

 

 

 

关于链表

 

记得大学还没毕业的时候有一次面试,面试官问我把一个链表倒置需要几个指针?当时没答出来,印象特别深刻,所以这次就把这个知识点复习下。

使用C代码写的,但思路是一样的

/*
 Iterative list reverse.
 Iterate through the list left-right.

 Move/insert each node to the front of the result list --
 like a Push of the node.
*/
static void Reverse(struct node**headRef){
        struct node*result=NULL;
        struct node*current=*headRef;
        struct node*next;
        while(current!=NULL){
            next=current->next; // tricky: note the next node
            current->next=result; // move the node onto the result
            result=current;
            current=next;
        }
        
        *headRef=result;
}

 

需要三个指针,一个指向需要倒置的链表,一个保存next节点,一个指向倒置后返回的链表。

 

posted @ 2016-05-11 11:56  andrew-chen  阅读(1442)  评论(0编辑  收藏  举报