Java数据结构与算法之数据结构-逻辑结构-线性结构(9)------Java线性结构概念及其基本操作

Java数据结构与算法结构图如下:

图1:

这个系列的博文中前半部分主要学习总结了Java逻辑结构中的集合部分(Java集合类),这部分主要学习总结的就是图1中红色框框起来的部分知识点。这篇博文将会从 Java的线性结构的定义和内容逐一展开系统化的学习。


基本概念的理解:


一、数据结构:

数据结构由数据和结构两部分组成,就是将数据按照一定的结构组合起来,这样不同的组合方式有不同的效率,可根据需求选择不同的结构应用在相应在场景。

数据结构大致
分为两类:

线性结构(如数组,链表,队列,栈等),非线性结构(如树,图,表,多维数组等)。本文介绍下线性结构,下章介绍非线性结构。


二、数组:

数组表示一组有限个相同类型的数据的集合,顺序存储,下标从0开始,其特点是可以根据下标快速的查找到元素,但在增加和删除元素时会导致大量的数据

位置的变动,即这
种情况下性能不高,故数组一般多用于查找频繁,增,删较少的情况。

下图为一个二维数组的结构图:

插入元素:
当往数组某位置上插入元素时,需要将位置后的所有元素往后移动一个位置。
删除元素:
当删除数组上的某个元素时,需要将该元素后的所有元素的位置往前移动一个位置。
下面简单实现数组中插入元素和删除元素功能:

public class ArrayDemo<T> {  
  
    private Object[] array ;  
      
    private int length = 0;  
      
    private final static int DEFAULT_CAPACITY = 10;  
      
    public ArrayDemo(){  
        super();  
        this.array = new Object[DEFAULT_CAPACITY];  
        this.length = DEFAULT_CAPACITY;  
    }  
      
    public ArrayDemo(int length){  
        super();  
        if(length < 0){  
            throw new IllegalArgumentException("error length:"+length);  
        }  
        this.array = new Object[length];  
        this.length = length;  
    }  
      
    public ArrayDemo(Collection<? extends T> c){  
        array = c.toArray();  
        length = c.size();  
        if(array.getClass() != Object[].class){  
            array = Arrays.copyOf(array, length, Object[].class);  
        }  
    }  
      
    /** 
     * 在数组array的index位置处插入一个元素t,如果已经满了,则移除最后一个元素 
     * @param array 
     * @param t 
     * @param indext 
     */  
    public void insert(T t, int index){  
        if(null == t){  
            throw new NullPointerException("null Pointer!");  
        }  
        if(index < 0 || index > length-1){  
            throw new IndexOutOfBoundsException("index is error");  
        }  
        for(int pos = length-1; pos>index; pos--){  
            array[pos] = array[pos-1];  
        }  
        array[index] = t;  
    }  
      
    /** 
     * 删除指定位置上的数组元素 
     * @param array 
     * @param index 
     */  
    public void delete(int index){  
        if(null == array){  
            throw new NullPointerException("null Pointer!");  
        }  
        int length = array.length;  
        if(index < 0 || index > length-1){  
            throw new IndexOutOfBoundsException("index is error");  
        }  
        for(int pos = index; pos < length-1; pos++){  
            array[pos] = array[pos+1];  
        }  
        array[length-1] = null;  
    }  
      
    /** 
     * 遍历输出数组中所有元素 
     */  
    public void trans(){  
        if(null == array){  
            throw new NullPointerException("null Pointer!");  
        }  
        for(int pos=0; pos< length; pos++){  
            System.out.println(array[pos]);  
        }  
    }  
}  

public class Person {  
  
    private String name;  
      
    private String sex;  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public String getSex() {  
        return sex;  
    }  
  
    public void setSex(String sex) {  
        this.sex = sex;  
    }  
  
    @Override  
    public String toString() {  
        return "Person [name=" + name + ", sex=" + sex + "]";  
    }  
  
    public Person(String name, String sex) {  
        super();  
        this.name = name;  
        this.sex = sex;  
    }  
  
    @Override  
    public int hashCode() {  
        final int prime = 31;  
        int result = 1;  
        result = prime * result + ((name == null) ? 0 : name.hashCode());  
        result = prime * result + ((sex == null) ? 0 : sex.hashCode());  
        return result;  
    }  
  
    @Override  
    public boolean equals(Object obj) {  
        if (this == obj)  
            return true;  
        if (obj == null)  
            return false;  
        if (getClass() != obj.getClass())  
            return false;  
        Person other = (Person) obj;  
        if (name == null) {  
            if (other.name != null)  
                return false;  
        } else if (!name.equals(other.name))  
            return false;  
        if (sex == null) {  
            if (other.sex != null)  
                return false;  
        } else if (!sex.equals(other.sex))  
            return false;  
        return true;  
    }  
}  

测试类:

public class TestArray {  
  
    public static void main(String[] args) {  
        ArrayDemo<Person> array = new ArrayDemo<>();  
        Person p = new Person("张三", "m");  
        array.insert(p, 0);  
        array.trans();  
        array.delete(0);  
        System.out.println("---");  
        array.trans();  
    }  
}  


三、链表:


表是一种有序的列表。链表的内容通常存储在内存中分散的位置上。链表由节点组成,每个节点的结构都是相同的。节点分为数据域和链域,

数据域顾名思义,就是存放节点
节点的内容,链域存放的是下一个节点的指针或引用。如果是双向链表的话,链域中还会有前一个节点的指针或引用。下图为单向链表各节

点间的关系图。


下面来实现一个简单的链表结构

public class Node<T> {  
  
    private T data;  
      
    private Node<T> pre;  
      
    private Node<T> next;  
      
    public Node(){  
        super();  
        this.pre = null;  
        this.next = null;  
    }  
      
    public Node(T data){  
        super();  
        this.data = data;  
        this.pre = null;  
        this.next = null;  
    }  
      
    public Node(T data, Node<T> pre, Node<T> next){  
        super();  
        this.data = data;  
        this.pre = pre;  
        this.next = next;  
    }  
  
    public T getData() {  
        return data;  
    }  
  
    public void setData(T data) {  
        this.data = data;  
    }  
  
    public Node<T> getPre() {  
        return pre;  
    }  
  
    public void setPre(Node<T> pre) {  
        this.pre = pre;  
    }  
  
    public Node<T> getNext() {  
        return next;  
    }  
  
    public void setNext(Node<T> next) {  
        this.next = next;  
    }  
}  

链表类:

public class LinkedListDemo<T> {  
  
    private Node<T> head;//头结点  
  
    private Node<T> tail;//尾节点  
      
    private int size;//链表大小  
      
    public LinkedListDemo(){  
        head = new Node<T>(null, null, null);  
        tail = new Node<T>(null, head, null);  
        head.setNext(tail);  
        size = 0;  
    }  
      
    public MyIterator<T> iterator(){  
        return new MyIterator<T>();  
    }  
      
    public void add(T data){  
        Node<T> node = new Node<T>(data);  
        node.setPre(tail.getPre());  
        tail.getPre().setNext(node);  
        tail.setPre(node);  
        node.setNext(tail);  
        size++;  
    }  
      
    public void remove(T data){  
        Node<T> node = head;  
        while(tail != node.getNext()){  
            Node<T> currentNode = node.getNext();  
            if(currentNode.getData().equals(data)){  
                currentNode.getPre().setNext(currentNode.getNext());  
                currentNode.getNext().setPre(currentNode.getPre());  
                size--;  
                break;  
            }  
            node = currentNode;  
        }  
    }  
      
    public void print(){  
        Node<T> node = head;  
        while(tail != node.getNext()){  
            Node<T> currentNode = node.getNext();  
            System.out.println(currentNode.getData().toString());  
            node = currentNode;  
        }  
    }  
      
    /** 
     *  
     * 项目名: adt 
     * 类名: LinkedListDemo.java 
     * 类描述: 定义一个该链表的迭代器来访问 
     * 备注:  
     * 创建日期:2014-10-10 
     * 创建时间:上午12:10:46 
     * @param <T> 
     */  
    @SuppressWarnings("hiding")  
    private class MyIterator<T> implements Iterator<T>{  
  
        @SuppressWarnings("unchecked")  
        private Node<T> currentNode = (Node<T>) head.getNext();//节点读取当前位置  
          
        private Node<T> returnedNode = currentNode;//返回节点的位置  
          
        @Override  
        public boolean hasNext() {  
            return currentNode == tail? false:true;  
        }  
  
        @Override  
        public T next() {  
            if(!hasNext()){  
                throw new IndexOutOfBoundsException();  
            }  
            returnedNode = currentNode;  
            currentNode = currentNode.getNext();  
            return returnedNode.getData();  
        }  
  
        @Override  
        public void remove() {  
            if(!hasNext()){  
                throw new NoSuchElementException();  
            }  
            returnedNode.getPre().setNext(returnedNode.getNext());  
            returnedNode.getNext().setPre(returnedNode.getPre());  
            returnedNode = returnedNode.getNext();  
            currentNode = returnedNode;  
            size--;  
        }  
    }  
}  

测试类:

public class TestDemo {  
  
    public static void main(String[] args) {  
        LinkedListDemo<Person> list = new LinkedListDemo<Person>();  
        //往链表中加入10个元素   
        for(int i=0; i<10;i++){  
            Person p = new Person("zhang"+i, "m");  
            list.add(p);  
        }  
        list.print();  
        System.out.println("========");  
        Person p = new Person("zhang1", "m");  
        list.remove(p);//移除自定的元素  
        list.print();  
        System.out.println("========");  
        Person p1 = new Person("zhang4", "m");  
        Iterator<Person> iterator = list.iterator();  
        while(iterator.hasNext()){  
            Person person = iterator.next();  
            if(person.equals(p1)){  
                iterator.remove();//迭代器移除制定元素  
                break;  
            }  
        }  
        list.print();  
    }  
}  

测试结果:

Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
========  
Person [name=zhang0, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
========  
Person [name=zhang0, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  


四、队列

队列数据结构类似于生活中队列,有一个很重要的特性:先进先出即增加元素肯定是在队列的尾部添加,删除元素肯定是删除队列

头部的元素。队列的实现可以用数据结构,

也可以用链表结构。


下面简单是一个用数组结构实现的队列结构:

public class QueueDemo<T> {  
  
    private Object[] object;  
      
    /** 
     * 队列容量 
     */  
    private int capicity;  
  
    /** 
     * 队列中元素的个数 
     */  
    private int size;  
      
    private final static int DEFAULT_CAPICAL = 10;  
      
    public QueueDemo(){  
        capicity = DEFAULT_CAPICAL;  
        object = new Object[capicity];  
    }  
      
    public QueueDemo(int capicity){  
        this.capicity = capicity;  
        object = new Object[this.capicity];  
    }  
      
    public int size(){  
        return size;  
    }  
      
    public boolean isEmpty(){  
        return size==0;  
    }  
      
    /** 
     * 往队列中添加元素 
     * @param t 
     */  
    public void add(T t){  
        if(size == capicity){  
            throw new IndexOutOfBoundsException("queue is full");  
        }  
        object[size++]=t;  
    }  
      
    /** 
     * 移除队列中的元素 
     */  
    public void remove(){  
        if(isEmpty()){  
            throw new IndexOutOfBoundsException("queue is empty");  
        }  
        for(int pos = 0; pos < size-1; pos++){//将整个数组往前以一个位置  
            object[pos] = object[pos+1];  
        }  
        size--;  
    }  
      
    public void clear(){  
        Arrays.fill(object, null);  
        size=0;  
    }  
      
    public void print(){  
        for(int i=0; i<size; i++){  
            System.out.println(object[i].toString());  
        }  
    }  
}  


测试类:

public class TestQueue {  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        QueueDemo<Person> queue = new QueueDemo<Person>();  
        for(int i=0; i<10; i++){  
            Person p = new Person("zhang"+i, "m");  
            queue.add(p);  
        }  
        queue.print();  
        System.out.println("=====");  
        while(queue.size() > 0){//依次删除队列头元素  
            queue.remove();  
            queue.print();  
            System.out.println("=====");  
        }  
    }  
  
}  

输出:

Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang9, sex=m]  
=====  
=====  

五、栈

栈结构与队列类似,不过区别在于栈是先进后出的。即最先进栈的元素是最后一个出栈的。栈的结构也可以用数组或链表来实现。


下面简单实现一个基于数组结构的栈,实现只是稍微修改下上面队列结构的代码。

public class StackDemo<T> {  
  
    private Object[] object;  
      
    private int capicity;  
  
    private int size;  
      
    private final static int DEFAULT_CAPICAL = 10;    
  
    public StackDemo(){  
        capicity = DEFAULT_CAPICAL;  
        object = new Object[capicity];  
    }  
      
    public StackDemo(int capicity){  
        this.capicity = capicity;  
        object = new Object[this.capicity];  
    }  
      
    public int size(){  
        return size;  
    }  
      
    public boolean isEmpty(){  
        return size==0;  
    }  
      
    public void add(T t){  
        if(size == capicity){  
            throw new IndexOutOfBoundsException("queue is full");  
        }  
        object[size++]=t;  
    }  
      
    /** 
     * 修改移除元素的代码 
     */  
    public void remove(){  
        if(isEmpty()){  
            throw new IndexOutOfBoundsException("queue is empty");  
        }  
        object[--size]=null;  
    }  
      
    public void clear(){  
        Arrays.fill(object, null);  
        size=0;  
    }  
      
    public void print(){  
        for(int i=0; i<size; i++){  
            System.out.println(object[i].toString());  
        }  
    }  
      
}  

测试类:

public class TestStack {  
  
    /** 
     * @param args 
     */  
    public static void main(String[] args) {  
        StackDemo<Person> queue = new StackDemo<Person>();  
        for(int i=0; i<10; i++){  
            Person p = new Person("zhang"+i, "m");  
            queue.add(p);  
        }  
        queue.print();  
        System.out.println("=====");  
        while(queue.size() > 0){  
            queue.remove();  
            queue.print();  
            System.out.println("=====");  
        }  
    }  
}  

结果:

Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
Person [name=zhang9, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
Person [name=zhang8, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
Person [name=zhang7, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
Person [name=zhang6, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
Person [name=zhang5, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
Person [name=zhang4, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
Person [name=zhang3, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
Person [name=zhang2, sex=m]  
=====  
Person [name=zhang0, sex=m]  
Person [name=zhang1, sex=m]  
=====  
Person [name=zhang0, sex=m]  
=====  
=====  


六、几种简单的线性结构介绍完了,在实际的应用环境中需要参考各种数据结构的特点来选择。

数组:查找速度很快,但长度固定,增,删效率较低。

链表:增删效率较高,长度不固定,但查找需要从头遍历整个链表,效率较低。

队列:可用数组,链表实现,先进先出。

栈:可用数组,链表实现,先进后出。


博文以上内容学习自:http://blog.csdn.net/xianymo/article/details/39942611



















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值