数据结构-线性表

所谓线性表就是具有一维线性的存储结构,一般有两种存储方式:顺序存储和链式存储。数组就是一种顺序的存储结构,ArrayList就是一种顺序表的实现类。那么来讲一下链式存储的链表。LinkedList则是采用链表实现的容器。
链表又分为单链表和双链表。

单链表

这里写图片描述
An称为An+1的前驱节点,A0称为头节点。单链表只有一个指向后面节点的指针。
结构形式:

java代码
private class Node<E>{
        E item;
        Node<E> next;
        Node(E item,Node<E> next){
            this.item = item;
            this.next = next;
        }
}

这个只是一个链表的结构类,我们需要一个容器来实现这个单链表的具体操作。

package com.creat.mylist;


/**
 * Created by WHZ on 2017/8/10 0010.
 */
public class MySingleList<E>{

    private Node<E> first;
    private int size;

    private class Node<E>{
        E item;
        Node<E> next;

        Node(E item,Node<E> next){
            this.item = item;
            this.next = next;
        }
    }
    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return (size == 0);
    }

    public boolean contains(Object o) {
        if(o == null){
            for(Node<E> x = first; x != null; x = x.next){
                if(x.item == null){
                    return true;
                }
            }
        }else {
            for(Node<E> x = first; x != null; x = x.next){
                if(o.equals(x.item)){
                    return true;
                }
            }
        }
        return false;
    }

    public boolean add(E e) {
        Node<E> node = new Node<E>(e,null);
        if(first == null){
            first = node;
        }else {
            Node<E> x = null;
            for(x = first; x.next != null; x = x.next)
                ;
            x.next = node;
        }
        size++;
        return true;
    }

    public boolean remove(Object o) {
        if(first != null){
            if( o == null){
                Node<E> temp = null;
                for(Node<E> x = first; x != null; x = x.next){
                    if(x.item == null){
                        return removeNode(x, temp);
                    }
                    temp = x;
                }
            }else {
                Node<E> temp = null;
                for(Node<E> x = first; x != null; x = x.next){
                    if(o.equals(x.item)){
                        return removeNode(x, temp);
                    }
                    temp = x;
                }
            }
        }
        return false;
    }

    private boolean removeNode(Node<E> x, Node<E> temp){
        if(x == first){
            first = x.next;
            size--;
            return true;
        }else {
            temp.next = x.next;
            size--;
            return true;
        }
    }

    public void clear() {
        first = null;
        size = 0;
    }

    public E get(int index) {
        if(first != null && size > index && index >= 0){
             Node<E> x = first;
             for(int i = 0; i < index; i++){
                 x = x.next;
             }
             return x.item;
        }else {
            throw new IndexOutOfBoundsException("越界");
        }
    }

    public E set(int index, E element) {
        if(first != null && size > index && index >= 0){
            Node<E> x = first;
            for(int i = 0; i < index; i++){
                x = x.next;
            }
            x.item = element;
            return x.item;
        }else {
            throw new IndexOutOfBoundsException("越界");
        }
    }

    public void add(int index, E element) {
        if(first != null && size > index ){
            Node<E> x = first;
            Node<E> temp = null;
            for(int i = 0; i < index; i++){
                temp = x;
                x = x.next;
            }
            Node<E> newNode = new Node<E>(element,x);
            temp.next = newNode;
            size++;
        }else if(first == null && index == 0){
            first = new Node<E>(element,null);
            size++;
        }else {
            throw new IndexOutOfBoundsException("越界");
        }
    }


    public int indexOf(Object o) {
        if(first != null){
            if( o == null){
                int index = 0;
                for(Node<E> x = first; x != null; x = x.next){
                    if(x.item == null){
                        return index;
                    }
                    index++;
                }
            }else {
                int index = 0;
                for(Node<E> x = first; x != null; x = x.next){
                    if(o.equals(x.item)){
                        return index;
                    }
                    index++;
                }
            }
        }
        return -1;
    }

}

测试结果

package com.creat;

import com.creat.mylist.MySingleList;
import java.io.*;

public class App {

    public static void main(String[] args ) throws IOException {
        MySingleList<Integer> list = new MySingleList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println("是否包含3:"+list.contains(3));
        System.out.println("3的索引值:"+list.indexOf(3));
        System.out.println("索引1上的数:"+list.get(1));
        list.add(1,4);
        for(int i = 0; i < list.size(); i++){
            System.out.print("第"+i+"个数:"+list.get(i)+" ;");
        }
        System.out.println();
        list.set(1,6);
        for(int i = 0; i < list.size(); i++){
            System.out.print("第"+i+"个数:"+list.get(i)+" ;");
        }
        System.out.println();
        System.out.println("是否为空:"+list.isEmpty());
        System.out.println("链表大小:"+list.size());
        list.clear();
        System.out.println("是否为空:"+list.isEmpty());
        System.out.println("链表大小:"+list.size());
        for(int i = 0; i < list.size(); i++){
            System.out.print("第"+i+"个数:"+list.get(i)+" ;");
        }
    }

}

是否包含3:true
3的索引值:2
索引1上的数:20个数:1 ;第1个数:4 ;第2个数:2 ;第3个数:3 ;0个数:1 ;第1个数:6 ;第2个数:2 ;第3个数:3 ;
是否为空:false
链表大小:4
是否为空:true
链表大小:0

双链表

单链表只拥有头节点,当我们需要增加或者修改尾部的节点时,往往需要遍历整个链表,这样花费了很多时间,所以产生了双链表,拥有头节点和尾节点,每个节点拥有指向前驱节点的指针和后驱节点的指针。java中的LinkedList正是采用了双链表来实现。
这里写图片描述
链表结构:

private class Node<E>{
        Node<E> prev;
        E item;
        Node<E> next;

        Node(Node<E> prev, E item, Node<E> next){
            this.item = item;
            this.prev = prev;
            this.next = next;
        }
    }

简单的容器类:

package com.creat.mylist;

/**
 * Created by WHZ on 2017/8/10 0010.
 */
public class MyLinkedList<E> {

    private Node<E> first;
    private Node<E> last;
    private int size;

    private class Node<E>{
        Node<E> prev;
        E item;
        Node<E> next;

        Node(Node<E> prev, E item, Node<E> next){
            this.item = item;
            this.prev = prev;
            this.next = next;
        }
    }
    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return (size == 0);
    }

    public boolean contains(Object o) {
        if(first != null){
            if(o == null){
                for(Node<E> x = first; x != null; x = x.next){
                    if(x.item == null){
                        return true;
                    }
                }
            }else {
                for(Node<E> x = first; x != null; x = x.next){
                    if(o.equals(x.item)){
                        return true;
                    }
                }
            }
        }
        return false;
    }


    public boolean add(E e) {
        Node<E> newNode = new Node<E>(last, e, null);
        if(last == null){
            first = newNode;
        }else {
            last.next = newNode;
        }
        last = newNode;
        size++;
        return false;
    }

    public boolean remove(Object o) {
        if(first != null){
            if(o == null){
                for(Node<E> x = first; x != null; x = x.next){
                    if(x.item == null){
                        if(x == first){
                            x.next.prev = null;
                            first = x.next;
                        }else if(x == last){
                            x.prev.next = null;
                            last = x.prev;
                        }else {
                            x.next.prev = x.prev;
                            x.prev.next = x.next;
                        }
                        size--;
                        return true;
                    }
                }
            }else {
                for(Node<E> x = first; x != null; x = x.next){
                    if(o.equals(x.item)){
                        if(x == first){
                            x.next.prev = null;
                            first = x.next;
                        }else if(x == last){
                            x.prev.next = null;
                            last = x.prev;
                        }else {
                            x.next.prev = x.prev;
                            x.prev.next = x.next;
                        }
                        size--;
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void clear() {
        first = null;
        last = null;
        size = 0;
    }

    public E get(int index) {
        if(first != null && size > index && index >= 0){
            if(size/2 > index){
                Node<E> temp = first;
                for(int i = 0; i < index; i++){
                    temp = temp.next;
                }
                return temp.item;
            }else {
                Node<E> temp = last;
                for(int i = size-index; i > 1; i--){
                    temp = temp.prev;
                }
                return temp.item;
            }
        }else{
            throw new IndexOutOfBoundsException("越界");
        }
    }

    public E set(int index, E element) {
        if(first != null && size > index && index >= 0){
            if(size/2 > index){
                Node<E> temp = first;
                for(int i = 0; i < index; i++){
                    temp = temp.next;
                }
                temp.item = element;
                return temp.item;
            }else {
                Node<E> temp = last;
                for(int i = size-index; i > 1; i--){
                    temp = temp.prev;
                }
                temp.item = element;
                return temp.item;
            }
        }else{
            throw new IndexOutOfBoundsException("越界");
        }
    }

    public void add(int index, E element) {
        if(first != null && size > index && index >= 0){
            if(size/2 > index){
                Node<E> x = first;
                for(int i = 0; i < index; i++){
                    x = x.next;
                }
                Node<E> newNode = new Node<E>(x.prev, element, x);
                if(x == first){
                    x.prev = newNode;
                   first = newNode;
                }else {
                    x.prev.next = newNode;
                    x.prev = newNode;
                }
            }else {
                Node<E> x = last;
                for(int i = size-index; i > 1; i--){
                    x = x.prev;
                }
                Node<E> newNode = new Node<E>(x.prev, element, x);
                if(x == first){
                    x.prev = newNode;
                    first = newNode;
                }else {
                    x.prev.next = newNode;
                    x.prev = newNode;
                }
            }
            size++;
        }else{
            throw new IndexOutOfBoundsException("越界");
        }
    }

    public int indexOf(Object o) {
        int index = 0;
        for(Node<E> x = first; x != null; x = x.next){
            if(o == null){
                if(x.item == null){
                    return index;
                }
            }else {
                if(o.equals(x.item)){
                    return index;
                }
            }
            index++;
        }
        return -1;
    }


}

测试结果:

package com.creat.mylist;

/**
 * Created by WHZ on 2017/8/10 0010.
 */
public class MyLinkedClient {

    public static void main(String[] args){
        MyLinkedList<String> linkedList = new MyLinkedList<String>();
        linkedList.add("whz");
        linkedList.add("zdd");
        linkedList.add("haiyoushui");
        for(int i = 0; i < linkedList.size(); i++){
            System.out.println("第"+i+"个是:"+linkedList.get(i));
        }
        System.out.println(linkedList.size());
        linkedList.add(1,"没谁了");
        for(int i = 0; i < linkedList.size(); i++){
            System.out.println("第"+i+"个是:"+linkedList.get(i));
        }
        System.out.println("没谁了存在不:"+linkedList.contains("没谁了"));
        System.out.println("没谁存在不:"+linkedList.contains("没谁"));
        System.out.println("zdd在第几个:"+linkedList.indexOf("zdd"));
        linkedList.remove("whz");
        linkedList.remove("haiyoushui");
        for(int i = 0; i < linkedList.size(); i++){
            System.out.println("第"+i+"个是:"+linkedList.get(i));
        }
        linkedList.set(0,"whz");
        for(int i = 0; i < linkedList.size(); i++){
            System.out.println("第"+i+"个是:"+linkedList.get(i));
        }
        linkedList.clear();
        System.out.println("是否为空:"+linkedList.isEmpty());
        for(int i = 0; i < linkedList.size(); i++){
            System.out.println("第"+i+"个是:"+linkedList.get(i));
        }
    }
}
第0个是:whz
第1个是:zdd
第2个是:haiyoushui
30个是:whz
第1个是:没谁了
第2个是:zdd
第3个是:haiyoushui
没谁了存在不:true
没谁存在不:false
zdd在第几个:20个是:没谁了
第1个是:zdd
第0个是:whz
第1个是:zdd
是否为空:true

总结:基于数组实现的集合在查找方面速度较快,数组是固定大小,所以在插入,删除方面速度较慢,插入时需要以后该位置之后的所有元素。基于链表实现的集合在插入,删除方面有很大的优势,在查找方面略疏于数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值