数据结构-双向链表

本文介绍了双向链表的概念,将其比作带有前后两个环的小球,并详细解释了如何在Java中实现双向链表,包括节点定义、链表大小计算、元素的增加、插入、删除和查找等操作。

双向链表是链表中的一种,java中的LinkedList实现的就是双向链表。双向链表与单链表相比,多了一个前驱指针,使得链表的操纵更为方便。

到双向链表这,用包菜来比喻链表已经是不合适了。在我的理解中双向链表是的节点是一个小球,这个小球有前后两个环,一个环是前驱指针 Node pre;一个环是后向指针 Node next,如果有新的元素加入链表,那么这个小球的next环就会勾住新进来的球,而新进来的pre环则会勾住原来的球。

有了小理解则继续思考双链表需要的方法以及实现思路:

 1、首先写个节点Node,与单链表的相似,多定义一个前驱指针;双链表的类中需要定义一个头结点head和尾节点end,还要有计算链表大小的size

2、接下来是链表元素的增加,a、如果头结点为空,则新元素直接赋给头结点。b、如果尾节点为空则新元素赋给尾节点,并且尾节点的pre指向头结点,头结点的next指向尾节点;c、建一个临时节点存储尾节点,将新节点接在尾节点后,并且让新节点成为尾节点。要记得size++。

3、可以插入,找到对应的节点,在其后的插入,并类似以上的的c步骤

4、删除:先判断索引是否在范围内,如果在索引内,判断距离头结点还是尾节点近,距离近的一端开始搜索,找到后将它的pre节点与next节点连接起来

5、查找:与删除的前一部分类似,先判断距离哪端近,再近端开始搜索,找到并返回

步骤结束。

package linklist;

/**
 * 定义动态集合上的基本操作
 * @author zhengwei lastmodified 2017年3月16日
 *
 */
public interface ICollection {
	/**
	 * 根据关键字搜索出对应对象
	 * 
	 * @param key
	 * @return
	 */
	Object search(Object key);

	/**
	 * 元素个数
	 * 
	 * @return
	 */
	int size();

	/**
	 * 集合是否为空
	 * 
	 * @return
	 */
	boolean isEmpty();

	/**
	 * 集合是否包含某个关键字元素
	 * 
	 * @param o
	 * @return
	 */
	boolean contains(Object key);

	/**
	 * 在集合中新增一个元素
	 * 
	 * @param e
	 * @return
	 */
	void add(Object e);

	/**
	 * 按关键字移除元素
	 * 
	 * @param o
	 * @return
	 */
	void remove(Object key);
}
package linklist;

/**
 * 顺序表
 * @author zhengwei
 *
 */
public interface IList extends ICollection {
	/**
	 * 求指定元素的下标,没有这个元素就返回-1
	 * @param e
	 * @return
	 */
	int indexOf(Object e);
	/**
	 * 获取指定下标处的元素
	 * @param index
	 * @return
	 */
	Object get(int index);
	/**
	 * 在指定下标处插入元素
	 * @param e
	 * @param index
	 */
	void add(Object e,int index);
	/**
	 * 删除指定下标处的元素
	 * @param index
	 * @return 
	 */
	Object delete(int index);
}
package list.linklist;
/**
 * 
 * @author chenkaixin
 *
 * @param 
 */
public class DoublyLink implements IList {

    /**
     * 头结点
     */
    private Node head;
    /**
     * 尾节点
     */
    private Node end;
    /**
     * 链表的大小
     */
    private int size = 0;

    @Override
    public T search(T key) {
        Node tmp = head;
        if ((tmp.data == null || key == null)) {
            return null;
        }
        while (tmp != null) {
            if (tmp.data.equals(key)) {
                return tmp.data;
            } else {
                tmp = tmp.next;
            }
        }
        return null;
    }

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

    @Override
    public boolean isEmpty() {
        boolean b = true;
        if (this.size == 0) {
            b = false;
        }
        return b;
    }

    @Override
    public boolean contains(Object key) {
        boolean b = false;
        Node tem = head;
        while (tem != null) {
            if (tem.data == key) {
                b = true;
            }
        }
        return b;
    }

    @Override
    public void add(T e) {
        if (head == null) {
            head = new Node(e);
        } else if (end == null) {
            end = new Node(e);
            end.pre = head;
            head.next = end;
        } else {
            Node tem = new Node(e);
            tem.pre = end;
            end.next = tem;
            end = tem;
        }
        this.size++;
    }

    @Override
    public void remove(T key) {
        Node tem = head;
        while (true) {
            if (tem.data.equals(key)) {
                delExcege(tem);
                this.size--;
                System.out.println(tem.data);
                break;
            }
            tem = tem.next;
        }
    }

    @Override
    public int indexOf(T e) {
        Node tem = head;
        int index = 0;
        while (tem != null) {
            if (tem.data.equals(e)) {
                return index;
            }
            tem = tem.next;
            index++;
        }
        return -1;
    }

    @Override
    public T get(int index) {
        int i = 0;
        Node tem = head;
        if (index > 0 && index < this.size) {
            while (tem != null) {
                if (i == index) {
                    return tem.data;
                }
                tem = tem.next;
                i++;
            }
        }

        return null;
    }

    @Override
    public void add(T e, int index) {
        Node newNode = new Node(e);
        int i;
        if (0 < index && index < this.size) {
            if (index < size / 2) {
                Node tem = head;
                i = 0;
                while (tem != null) {
                    if (i == index) {
                        addExcege(newNode, tem);
                    }
                    tem = tem.next;
                    i++;
                }
            } else {
                Node tem = end;
                i = this.size-1;
                while (tem != null) {
                    if (i == index) {
                        addExcege(newNode, tem);
                    }
                    tem = tem.pre;
                    i--;
                }
            }

        }
    }

    @Override
    public Object delete(int index) {
        Node tem = head;
        Object result = null;
        int i;
        if (0 < index && index < this.size) {
            if (index < size / 2) {
                i = 0;
                while (tem != null) {
                    if (i == index) {
                        delExcege(tem);
                        result = tem.data;
                    }
                    tem = tem.next;
                    i++;
                }
            } else {
                while (tem != null) {
                    i = this.size - 1;
                    if (i == index) {
                        delExcege(tem);
                        result = tem.data;

                    }
                    tem = tem.pre;
                    i--;
                }
            }

        }

        return result;
    }

    private void addExcege(Node newNode, Node tem) {
        newNode.next = tem.next;
        tem.next.pre = newNode;
        tem.next = newNode;
        newNode.pre = tem;
    }

    private void delExcege(Node tem) {
        tem.pre.next = tem.next;
        tem.next.pre = tem.pre;
    }

    private class Node {
        Node next;
        Node pre;
        T data;

        public Node(T data) {
            this.data = data;

        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (this.getClass() != obj.getClass())
                return false;
            Node other = (Node) obj;
            if (!getOuterType().equals(other.getOuterType()))
                return false;
            if (data == null) {
                if (other.data != null)
                    return false;
            } else if (!data.equals(other.data))
                return false;
            return true;
        }

        private DoublyLink getOuterType() {
            return DoublyLink.this;
        }

        @Override
        public String toString() {
            return this.data.toString();
        }

    }

    @Override
    public String toString() {
        Node e = head;
        StringBuilder sb = new StringBuilder("[");
        while (e != null) {
            sb.append(e.data.toString()).append(",");
            e = e.next;
        }
        sb.deleteCharAt(sb.lastIndexOf(",")).append("]");
        return sb.toString();
    }

    public static void main(String[] args) {
        DoublyLink dl = new DoublyLink();
        dl.add('3');
        dl.add('9');
        dl.add('4');
        dl.add('6');
        dl.add('8');
        dl.add('b');
        dl.add('p');
        System.out.println(dl.indexOf('9'));
        System.out.println(dl.size());
        System.out.println(dl.toString());
        System.out.println("=======================================");
        dl.remove('9');
        System.out.println(dl.get(3));
        System.out.println(dl.size());
        System.out.println(dl.toString());
        System.out.println("=================================");
        dl.add('a', 2);
        System.out.println(dl.toString());
        System.out.println("=================================");
        dl.delete(4);
        System.out.println(dl.search('a'));
        System.out.println(dl.toString());
        System.out.println("==================================");
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值