java表 ADT

基本介绍


实现方法:
1. 简单数组
2. 简单链表
数组
对于表的所有操作都可通过简单数组来实现,虽然数组是固定容量的,但在需要时我们可通过创建一个新数组来扩大容量。使用数组实现其遍历输出时间是线性的,查找花费常数时间。但插入和删除将花费大量开销,当然要看插入删除所发生的位置。最坏情况为在位置0操作,最好情况则为在末尾操作。
链表
与数组相比链表的输出和查找时间都将增大,然而当我们频繁的插入删除时链表将为我们节约大量时间。它每一个节点(Node)都包含两方面的内容:
1.节点本身的数据(data);
2.下一个节点的信息(next)。 (如果为双链表则还将包含上一个节点信息(prev))


java中的实现

在java.util包中集合框架Collection接口的继承接口List主要用于实现表。
Vector:
基于数组(Array)的List,封装了数组所不具备的一些功能进而方便我们使用,Vector是线程同步的(sychronized)的,这也是Vector和ArrayList 的一个的重要区别。

ArrayList:
同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。因此在性能上要比Vector好,但是需要自己在管理线程的同步问题。
LinkedList:
链表LinkedList不同于前面两种List,它不是基于数组的,所以不受数组性能的限制。
今后使用中我们可直接通过实例化对象来实现表结构,如:List list = new ArrayList();
当然我们也可尝试编写属于自己的ArrayList与LinkedList在编写中将用到迭代器,内部类,和嵌套类。

代码实现:

MyArrayList:

import java.util.Iterator;

public class MyArrayList<AnyType> implements Iterable<AnyType>{
private static final int addsize=10 ;
private int nowsize ;
private AnyType[] theArray ;
public MyArrayList()
{
    this.clear();
}
public void clear() 
{
    this.nowsize = 0 ;
    arraychange(addsize);

}
public void arraychange(int newsize) 
{
    if(newsize>nowsize)
        return;
    else
        {
        AnyType []old = theArray ;
        theArray = (AnyType []) new Object[newsize] ;
        for(int i=0;i < size();i++)
            theArray[i] = old[i] ;
        }
}
public int size()
{
    return nowsize;
}
public AnyType set(int index , AnyType news){
    if(index>=this.size() || index<0)
        throw new ArrayIndexOutOfBoundsException();
    AnyType old = this.theArray[index];
    this.theArray[index] = news ;
    return old ;
}
public AnyType get(int index ){
    if(index>=this.size() || index<0)
        throw new ArrayIndexOutOfBoundsException();
    AnyType old = this.theArray[index];
    return old ;
}
public void add(AnyType news){
    this.add(this.size(), news);

}
public void add(int index , AnyType news){
    if(this.theArray.length==this.size())
        this.arraychange(this.size()*2+1);
    if(index>=this.size() || index<0)
        throw new ArrayIndexOutOfBoundsException();
    for(int i=this.nowsize;i<index;i--)
        this.theArray[i]=this.theArray[i-1] ;
                this.theArray[index] = news ;
                this.nowsize++;
}
public void remove(int index ){

    if(index>=this.size() || index<0)
        throw new ArrayIndexOutOfBoundsException();
    for(int i = index ; i < this.nowsize -1 ; i++)
        this.theArray[i] = this.theArray[i+1] ;
                this.nowsize--;

}
@Override
public Iterator<AnyType> iterator() {

    return new ArrayListIterator<AnyType>();
}
private class ArrayListIterator<AnyType> implements Iterator<AnyType>
{
   private int c = 0;
    @Override
    public boolean hasNext() {
        // TODO Auto-generated method stub
        return c<size();
    }

    @Override
    public AnyType next() {
        if(!hasNext())
            throw new ArrayIndexOutOfBoundsException();
        return (AnyType) theArray[c++];
    }

    @Override
    public void remove() {
        MyArrayList.this.remove(c--);

    }

}

}


MyLinkedList:此方法中迭代器与上一方法大致相同,所以未做实现

public class MyLinkedList<T> implements Iterable<T> {
 private int size ;
 private int count = 0 ;
 private Node<T> begin ;
 private Node<T> end ;
 public MyLinkedList ()
 {
     this.clear() ;
 }
 public void clear() {
    this.begin = new Node<T>(null,null,null);
    this.end = new Node<T>(null,this.begin,null);
    this.begin.next = this.end ;

}
 public int size() {
        return this.size;

    }
 public boolean isEmpty()
 {
     return size() == 0 ;
 }
 public boolean add(T x)
 {
     this.add(this.size(),x);
    return true;

 }
 public void add(int idx, T x) {
    this.addBefore(this.getNode(idx),x);

}
 public T get(int idx, T x) {

        return getNode(idx).data;

    }
 public T set(int idx, T x) {
     Node<T> old = getNode(idx) ;
     T o = old.data ;
     old.data = x ;
     return o ;

    }
 public T remove(int idx) {

        return remove(getNode(idx));

    }
private T remove(Node<T> n) {
    n.next.prev = n.prev ;
    n.prev.next = n.next;
    this.size--;
    this.count++;
    return n.data;
}
private void addBefore(Node<T> node, T x) {
    Node<T> n = new Node<T> (x,node.prev,node.next);
    n.prev.next = n ;
    node.prev = n;
    this.size++;
    this.count++;
}
private Node<T> getNode(int idx) {
    Node<T> p;
    if(idx<0||idx>this.size())
        throw new ArrayIndexOutOfBoundsException();
    if(idx<this.size()/2)
    {
        p = this.begin;
        for(int i=0;i<idx;i++)
            p=p.next;
    }
    else
    {
        p = this.end;
        for(int i=this.size();i>idx;i--)
            p=p.prev;
    }
    return p;
}

@Override
    public Iterator<T> iterator() {

        return null;
    }
    public static class Node<T>{

        private T data;
        private Node<T> prev ;
        private Node<T> next ;
        public Node(T d , Node<T> p,Node<T> n )
        {
            this.data = d ;
            this.prev = p ;
            this.next = n ;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * 二叉树节点ADT接口 */ package dsa; public interface BinTreePosition extends Position { //判断是否有父亲(为使代码描述简洁) public boolean hasParent(); //返回当前节点的父节点 public BinTreePosition getParent(); //设置当前节点的父节点 public void setParent(BinTreePosition p); //判断是否为叶子 public boolean isLeaf(); //判断是否为左孩子(为使代码描述简洁) public boolean isLChild(); //判断是否有左孩子(为使代码描述简洁) public boolean hasLChild(); //返回当前节点的左孩子 public BinTreePosition getLChild(); //设置当前节点的左孩子(注意:this.lChild和c.parent都不一定为空) public void setLChild(BinTreePosition c); //判断是否为右孩子(为使代码描述简洁) public boolean isRChild(); //判断是否有右孩子(为使代码描述简洁) public boolean hasRChild(); //返回当前节点的右孩子 public BinTreePosition getRChild(); //设置当前节点的右孩子(注意:this.rChild和c.parent都不一定为空) public void setRChild(BinTreePosition c); //返回当前节点后代元素的数目 public int getSize(); //在孩子发生变化后,更新当前节点及其祖先的规模 public void updateSize(); //返回当前节点的高度 public int getHeight(); //在孩子发生变化后,更新当前节点及其祖先的高度 public void updateHeight(); //返回当前节点的深度 public int getDepth(); //在父亲发生变化后,更新当前节点及其后代的深度 public void updateDepth(); //按照中序遍历的次序,找到当前节点的直接前驱 public BinTreePosition getPrev(); //按照中序遍历的次序,找到当前节点的直接后继 public BinTreePosition getSucc(); //断绝当前节点与其父亲的父子关系 //返回当前节点 public BinTreePosition secede(); //将节点c作为当前节点的左孩子 public BinTreePosition attachL(BinTreePosition c); //将节点c作为当前节点的右孩子 public BinTreePosition attachR(BinTreePosition c); //前序遍历 public Iterator elementsPreorder(); //中序遍历 public Iterator elementsInorder(); //后序遍历 public Iterator elementsPostorder(); //层次遍历 public Iterator elementsLevelorder(); }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值