链表和二叉树

来源:互联网 发布:视频软件 知乎 编辑:程序博客网 时间:2024/06/05 10:49

链表和二叉树

1. 链表

 

1.单链表是由一个个节点组成的,其节点结构由两个域所组成,一个是数据域用于存储数据,一个是节点域用来存储后继节点.

 

例如:public class MyNode<E> {

public MyNode<E> next;    //节点域

public E item;          //数据域

 

public MyNode(E item){

this.item =item;

}

}

 

  2.链表的构建,即添加元素

 

   分两种情况:1.当链表为空时   2.当链表不为空时

   

    例如:

 

        public void add(Eitem) { // 添加元素

 

node = new MyNode<E>(item);

 

if (first ==null) {   //当头结点为null时,即链表为空时

first = node;

 

} else if (last !=null) {    //当尾节点不为null时,即链表不为空

 

last.next =node;

}

 

last = node;

size++;                 //链表的长度加一

}

 

 

 

 

3. 链表节点的删除

          

         分三种情况: 1.在头部删除    只需把头结点后移,再让其指向null

2. 在尾部删除   只需把尾节点后移,再让其指向null

3.在中间删除    把删除节点的前驱的后继指向删除节点的后继,再让删除节点指向null

      

         public void remove(int index) {// 删除元素

 

if (index < 0 ||index >= size) {     //判断索引是否越界

try {

throw new Exception("角标越界");

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

 

pre = first;

 

if (index == 0) {          //在头部删除      

 

first = first.next;     

pre = null;

} else if (index ==size - 1) {    //在尾部删除

 

last = null;

last = pre;

 

} else {            //在中间删除

           

            for (int i = 0;i < index - 1; i++) {     //找到前驱节点

pre = pre.next;

}

 

MyNode<E> temp = pre.next;

pre.next =temp.next;

temp = null;

 

}

size--;         //长度减一

 

}

 

4. 链表增加节点

 

     分三种情况: 1.在头部增加节点  把要增加的节点的后继指向头节点,然后头结点指向要增加的节点

2. 在尾部增加节点   尾节点的后继指向要增加的节点,然后尾节点指向要增加的节点

3. 在中间增加节点    要增加的节点的后继指向它前驱节点的后继,前驱节点的后继指向要增加的节点

 

    public void insert(int index, Eitem) { // 增加节点

 

MyNode<E> md = new MyNode<E>(item);

 

pre = first;

 

 

if (index == 0) {   //头部增加节点

md.next =first;

first = md;

} else if (index ==size - 1) {   //尾部增加节点

             last.next =md;

             last = md;

} else {          //中间增加节点

 

            for (int i = 0;i < index - 1; i++) {   

pre = pre.next;

}

md.next =pre.next;

pre.next =md;

}

size++;    //长度加一

}

 

 

 

2. 二叉树

   

 

   1.二叉树的性质

      1.若根结点的层次为1,则二叉树第i层最多有2(i-1)次方个结点。

2.在高度为k的二叉树中,则最多有2k-1个结点(k0

3.设一棵二叉树节点个数为n,则父节点个数为n/2

4.一棵具有n个结点的完全二叉树,对序号为i0i<n)的结点,则:

1.i=0,则i为根结点,无父母结点;

2.i >0,则i的左右子结点序号为:

2i+1<n,则i的左孩子结点序号为2i+1;否则i无左孩子。

2i+2<n,则i的右孩子结点序号为2i+2;否则i无右孩子。

 

2.二叉树也是由一个个节点构成,其节点由三个域构成,左节点域用来存储左子树,数据域用来存储数据,右节点域用来存储右子树

 

例如:public class TreeNode<E> {

public TreeNode<E> left;  //左子树域

public TreeNode<E> right;   //右子树域

public E item;         //数据域

public TreeNode(E item){

this.item =item;

}

 

}

 

3.二叉树的构建

         1.由于只有父节点才有左右孩子,所以帮所有的父节点构建它的左右子树就可以构建整个二叉树,根据二叉树的性质: 父节点的个数= 所有节点个数/ 2,所有只需要帮助前所有节点个数 / 2个节点构建其左右子树就可以了

 

   例如:

 

public TreeNode<E> createTree() {// 构建二叉树

 

for (int i = 0;i < list.size() / 2;i++) {   

 

if ((2 * i + 1) < list.size()) {   //根据二叉树的性质,判断是否有左孩子

list.get(i).left =list.get(2 * i + 1);

}

 

if ((2 * i + 2) < list.size()) {    //根据二叉树的性质,判断是否有右孩子

 

list.get(i).right =list.get(2 * i + 2);

}

 

}

   

 

 

 4.二叉树的遍历

      根据访问根节点的先后顺序,二叉树的遍历可分为:

   

      前序遍历:

 

   public void PreOrder(TreeNode<E>root) { // 前序遍历

 

if (root !=null) {   //当根节点不为null时,遍历该二叉树

 

System.out.print(root.item +"  ");

PreOrder(root.left);

PreOrder(root.right);

}

 

}

 

  中序遍历:

     public void InOrder(TreeNode<E>root) {   //中序遍历

 

if (root !=null) {

 

PreOrder(root.left);

System.out.print(root.item +"  ");

PreOrder(root.right);

}

}

 

 后序遍历:

  public void PostOrder(TreeNode<E>root) {   //后序遍历

 

if (root !=null) {

 

PreOrder(root.left);

PreOrder(root.right);

System.out.print(root.item +"  ");

}

}