《JAVA》数组与链表知识


数组
int c[] = {2,3,6,10,99};
int[] d = new int[10];
/**
	 * 数组检索
	 * @param args
	 */
	public static void main(String[] args) {
		String name[];
		name = new String[5];
		name[0] = "egg";
		name[1] = "erqing";
		name[2] = "baby";
		
		for(int i = 0; i < name.length; i++){
			System.out.println(name[i]);
		}
	}
/**
	 * 插入
	 * 
	 * @param old
	 * @param value
	 * @param index
	 * @return
	 */
	public static int[] insert(int[] old, int value, int index) {  
        for (int k = old.length - 1; k > index; k--)  
            old[k] = old[k - 1];  
        old[index] = value;  
        return old;  
    }  

	/**
	 * 遍历
	 * 
	 * @param data
	 */
	public static void traverse(int data[]) {
		for (int j = 0; j < data.length; j++) {
			System.out.println(data[j] + " ");
		}
	}

	/**
	 * 删除
	 * 
	 * @param old
	 * @param index
	 * @return
	 */
	public static int[] delete(int[] old, int index) {
		for (int h = index; h < old.length - 1; h++) {
			old[h] = old[h + 1];
		}
		old[old.length - 1] = 0;
		return old;
	}

Tips:数组中删除和增加元素的原理:增加元素,需要将index后面的依次往后移动,然后将值插入index位置,删除则是将后面的值一次向前移动。

数组表示相同类型的一类数据的集合,下标从0开始。

单链表

链表在空间是不连续的,包括:

  • 数据域(用于存储数据)
  • 指针域(用于存储下一个node的指针)
代码实现

节点类

  • 构造函数
  • 数据域的get,set方法
  • 指针域的get,set方法
public class Node {
    Object element; //数据域
    Node next;  //指针域
    //构造方法
    public Node(Object obj, Node nextval) {
        this.element = obj;
        this.next = nextval;
    }

    //获得当前结点的指针域
    public Node getNext() {
        return this.next;
    }

    //获得当前结点数据域的值
    public Object getElement() {
        return this.element;
    }
    //设置当前结点的指针域
    public void setNext(Node nextval) {
        this.next = nextval;
    }

    //设置当前结点数据域的值
    public void setElement(Object obj) {
        this.element = obj;
    }

    public String toString() {
        return this.element.toString();
    }
}

list类的接口实现代码:(其中把Node作为内部类了)

public interface ListForTest {
    //获得线性表长度
    public int size();

    //判断线性表是否为空
    public boolean isEmpty();

    //插入元素
    public void insert(int index, Object obj) throws Exception;

    //删除元素
    public void delete(int index) throws Exception;

    //获取指定位置的元素
    public Object get(int index) throws Exception;
}

list的实现类代码:

public class TextList implements ListForTest{
    Node head; //头指针
    Node current;//当前指针
    int size;//数量
    //构造函数
    public TextList(){
        head = new Node(null,null);
        current = head;
        this.size = 0;
    }
    //当前索引函数
     public void index(int index) throws Exception
        {
            if(index <0 || index > size -1)
            {
              throw new Exception("参数错误!");    
            }
            int j=0;//循环变量
            while(current != null&&j<index)
            {
                current = current.next;
                j++;
            }

        }    
    public int size() {
        // TODO Auto-generated method stub
        return this.size;
    }


    public boolean isEmpty() {
        // TODO Auto-generated method stub
        return this.size == 0;
    }


    public void insert(int index, Object obj) throws Exception {
        // TODO Auto-generated method stub
        if(index <0 ||index >size)
        {
            throw new Exception("参数错误!");
        }
        if(index == 0){
            Node node = new Node(obj,head);
            head = node;
        }else{
             index(index-1);//定位到要操作结点的前一个结点对象。
                current.setNext(new Node(obj,current.next));
        }
        size++;
    }


    public void delete(int index) throws Exception {
        // TODO Auto-generated method stub
        //判断链表是否为空
        if(isEmpty())
        {
            throw new Exception("链表为空,无法删除!");
        }
        if(index <1 ||index >size)
        {
            throw new Exception("参数错误!");
        }
        if(index == 0){
            head = head.next;
        }else{
             index(index-1);//定位到要操作结点的前一个结点对象。
             current.setNext(current.next.next);
        }
        size--;
    }


    public Object get(int index) throws Exception {
        // TODO Auto-generated method stub
        if(index <0 || index >size-1)
        {
            throw new Exception("参数非法!");
        }
        index(index);

        return current.getElement();
    }
    public class Node {
        Object element; //数据域
        Node next;  //指针域
        //构造方法
        public Node(Object obj, Node nextval) {
            this.element = obj;
            this.next = nextval;
        }

        //获得当前结点的指针域
        public Node getNext() {
            return this.next;
        }

        //获得当前结点数据域的值
        public Object getElement() {
            return this.element;
        }
        //设置当前结点的指针域
        public void setNext(Node nextval) {
            this.next = nextval;
        }

        //设置当前结点数据域的值
        public void setElement(Object obj) {
            this.element = obj;
        }

        public String toString() {
            return this.element.toString();
        }
    }

}

顺序表和单链表的比较:

顺序表

优点:主要优点是支持随机读取,以及内存空间利用效率高;

缺点:主要缺点是需要预先给出数组的最大数据元素个数,而这通常很难准确作到。当实际的数据元素个数超过了预先给出的个数,会发生异常。另外,顺序表插入和删除操作时需要移动较多的数据元素。

链表

优点:主要优点是不需要预先给出数据元素的最大个数。另外,单链表插入和删除操作时不需要移动数据元素;

缺点:主要缺点是每个结点中要有一个指针,因此单链表的空间利用率略低于顺序表的。另外,单链表不支持随机读取,单链表取数据元素操作的时间复杂度为O(n);而顺序表支持随机读取,顺序表取数据元素操作的时间复杂度为O(1)。

Stack

特性是:先进后出(FILO, First In Last Out)。java工具包中的Stack是继承于Vector(矢量队列)的,由于Vector是通过数组实现的,这就意味着,Stack也是通过数组实现的而非链表。当然,我们也可以将LinkedList当作栈来使用!

继承关系

java.lang.Object
↳     java.util.AbstractCollection<E>
   ↳     java.util.AbstractList<E>
       ↳     java.util.Vector<E>
           ↳     java.util.Stack<E>

public class Stack<E> extends Vector<E> {}

常用的API

            boolean       empty()
synchronized E             peek()
synchronized E             pop()
             E             push(E object)
synchronized int           search(Object o)

源码解析

package java.util;

public
class Stack<E> extends Vector<E> {
    // 版本ID。这个用于版本升级控制,这里不须理会!
    private static final long serialVersionUID = 1224463164541339165L;

    // 构造函数
    public Stack() {
    }

    // push函数:将元素存入栈顶
    public E push(E item) {
        // 将元素存入栈顶。
        // addElement()的实现在Vector.java中
        addElement(item);

        return item;
    }

    // pop函数:返回栈顶元素,并将其从栈中删除
    public synchronized E pop() {
        E    obj;
        int    len = size();

        obj = peek();
        // 删除栈顶元素,removeElementAt()的实现在Vector.java中
        removeElementAt(len - 1);

        return obj;
    }

    // peek函数:返回栈顶元素,不执行删除操作
    public synchronized E peek() {
        int    len = size();

        if (len == 0)
            throw new EmptyStackException();
        // 返回栈顶元素,elementAt()具体实现在Vector.java中
        return elementAt(len - 1);
    }

    // 栈是否为空
    public boolean empty() {
        return size() == 0;
    }

    // 查找“元素o”在栈中的位置:由栈底向栈顶方向数
    public synchronized int search(Object o) {
        // 获取元素索引,elementAt()具体实现在Vector.java中
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }
}

总结

(01) Stack实际上也是通过数组去实现的。
       执行push时(即,将元素推入栈中),是通过将元素追加的数组的末尾中。
       执行peek时(即,取出栈顶元素,不执行删除),是返回数组末尾的元素。
       执行pop时(即,取出栈顶元素,并将该元素从栈中删除),是取出数组末尾的元素,然后将该元素从数组中删除。
(02) Stack继承于Vector,意味着Vector拥有的属性和功能,Stack都拥有。












猜你喜欢

转载自blog.csdn.net/callmezhe/article/details/79453361