Java数据结构:链栈,双端栈,循环单链表

链栈

**注意:**在指定栈顶的时候,将数据前面的位置作为栈顶
1. 当数据后为栈顶时:
插入为n(1) Java数据结构:链栈,双端栈,循环单链表_第1张图片
删除为 n(n) --> 需要找到所删除数据的前一个数A
Java数据结构:链栈,双端栈,循环单链表_第2张图片
2. 当表头的下一个为栈顶时:
插入与删除均为n(1)
Java数据结构:链栈,双端栈,循环单链表_第3张图片
代码实现(基于链表的实现基础之上)

package DS02动态链表;

import DS01.Stack;

import java.util.Iterator;

public class LinkedStack<E> implements Stack<E> {
    private LinkList<E> list;

    public LinkedStack(){
        list= new LinkList<E>();
    }

    @Override
    public int getSize() {
        return list.getSize();
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void push(E e) {
        list.addFirst(e);
    }

    @Override
    public E pop() {
        return list.removeFirst();
    }

    @Override
    public E peek() {
        return list.getFirst();
    }

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }

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

双端栈

注意:定义两个结点left,right结点,将两个结点连接起来,在两结点后进行插入删除操作

  1. 插入:(将两结点的后面定义为栈顶)
    创建结点 left.next=new Node(e,left.next); //创建结点,当前元素为e,且当前下一个为左边的下一个
    Java数据结构:链栈,双端栈,循环单链表_第4张图片
    Java数据结构:链栈,双端栈,循环单链表_第5张图片
  2. 删除:(判断是否栈空,然后进行删除)
    Java数据结构:链栈,双端栈,循环单链表_第6张图片
    Java数据结构:链栈,双端栈,循环单链表_第7张图片
  3. 代码实现,类似于将两个栈连接起来,在增删查改之前分类讨论,左边还是右边
    【判空 --> 左指针的下一个是右指针,右指针的下一个是空】
package DS02动态链表;

import DS01.Stack;

import java.util.Iterator;

public class LinkStackDoubleEnd<E> implements Stack<E> {
    //Linklist list; //其只有一个指针,无法使用
    private Node left;
    private Node right;
    private int leftsize;
    private int rightsize;
    //构造函数
    public LinkStackDoubleEnd(){
        left=new Node();
        left.next=right;
        leftsize=0;
        rightsize=0;
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }

    private class Node {
        E data;     //数据域
        Node next;  //指针域

        Node() {
            this(null, null);
        }

        Node(E data, Node next) {
            this.data = data;
            this.next = next;
        }
    }

    @Override
    public int getSize() {
        return getLetfsize()+getRightsize();
    }
    public int getRightsize() {
        return rightsize;
    }
    public int getLetfsize() {
        return leftsize;
    }

    @Override
    public boolean isEmpty() {
        return isleftEmpty()&&isRightEmpty();
    }
    public boolean isleftEmpty() {
        return left.next==right;
    }
    public boolean isRightEmpty() {
        return right.next==null;
    }

    @Override
    public void push(E e) {
        if(rightsize>=leftsize){
            leftpush(e);
        }else{
            rightpush(e);
        }
    }
    public void leftpush(E e) {
        left.next=new Node(e,left.next);
        leftsize++;
    }
    public void rightpush(E e) {
        right.next=new Node(e,right.next);
        rightsize++;
    }

    @Override
    public E pop() {
        if(leftsize>=rightsize){
            return popLeft();
        }else {
            return popRight();
        }
    }
    public E popRight() {
        if(isEmpty()){
            throw new IllegalArgumentException("为空");
        }
        E ret = left.data;
        right.next=right.next.next;
        rightsize--;
        return ret;
    }
    public E popLeft() {
        if(isEmpty()){
            throw new IllegalArgumentException("为空");
        }
        E ret = right.data;
        left.next=left.next.next;
        leftsize--;
        return ret;
    }

    @Override
    public E peek() {
        return leftsize>=rightsize? peekleft():peekright();
    }
    public E peekleft() {
        if(isleftEmpty()){
            throw new IllegalArgumentException("左边为空");
        }
        return left.next.data;
    }
    public E peekright() {
        if(isRightEmpty()){
            throw new IllegalArgumentException("右边为空");
        }
        return right.next.data;
    }

    @Override
    public void clear() {
        clearLeft();
        clearRight();
    }
    public void clearLeft(){
        left.next=right;
        leftsize=0;
    }
    public void clearRight(){
        right.next=null;
        rightsize=0;
    }
    
}

单向循环单链表

注意:该结构使用真实头结点
1. 建立初始链表
Java数据结构:链栈,双端栈,循环单链表_第8张图片
2. 插入新结点:
将rear指针的下一个指针域指向插入新元素,
并将所插入新元素的下一个指向head,
并将rear指针指向该元素

注意分情况判断:
当元素没有值时的插入
当元素只有一个值时的插入
当元素插入的位置是最后一个位置时
当元素插入位置是中间位置

Java数据结构:链栈,双端栈,循环单链表_第9张图片
Java数据结构:链栈,双端栈,循环单链表_第10张图片
3. 删除(与添加同理)
将所要删除的元素标记,
将head指针指向所要删除元素的下一个元素,
将rear的下一个指针指向该新头结点,
并将该元素删除
4. 代码实现

package DS02动态链表;

import DS01.List;

import java.util.Iterator;

//单向循环链表
public class LinkedSingleLoop<E> implements List<E> {
    private Node head;//链表的头指针
    private Node rear;//链表的尾指针
    private int size;
    private LinkedSingleLoop(){
        head=null;
        rear=null;
        size=0;
    }

    private class Node{                     //内部类不可被外界访问
        E data;                             //数据域
        Node next;                          //指针域
        Node(){
            this(null,null);
        }
        Node(E data,Node next){
            this.data=data;
            this.next=next;
        }
    }

    @Override
    public int getSize() {
        return size;
    }

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

    @Override
    public void add(int index, E e) {
        if(index<0||index>=size){
            throw new IllegalArgumentException("角标越界");
        }
        Node n=new Node();
        n.data=e;
        if(isEmpty()){
            head=n;
            rear=n;
            rear.next=head;
        }else if(index==size){
            n.next=rear.next;
            rear.next=n;
            rear=n;
        }else if(index==0){
            rear.next=n;
            n.next=head;
            rear=n;
        }else{
            Node p=head;
            //遍历结束指向所找的元素的前一个
            for (int i = 0; i < index-1; i++) {
                p=p.next;
            }
            p.next=n.next;
            p.next=n;
        }
        size++;
    }

    @Override
    public void addFirst(E e) {
        add(0,e);
    }

    @Override
    public void addLast(E e) {
        add(size-1,e);
    }

    @Override
    public E get(int index) {
        if(isEmpty()){
            throw new IllegalArgumentException("空表");
        }
        if(index<0||index>=size){
            throw new IllegalArgumentException("角标越界");
        }
        if(index==0){
            return head.data;
        }else if(index==size-1){
            return rear.data;
        }else {
            Node p=head;
            //遍历结束指向所找的元素的前一个
            for (int i = 0; i < index-1; i++) {
                p=p.next;
            }
            return p.data;
        }

    }

    @Override
    public E getFirst() {
        return get(0);
    }

    @Override
    public E getLast() {
        return get(size-1);
    }

    @Override
    public void set(int index, E e) {
        if(isEmpty()){
            throw new IllegalArgumentException("空表");
        }
        if(index<0||index>=size){
            throw new IllegalArgumentException("角标越界");
        }
        Node p=head;
        //遍历结束指向所找的元素的前一个
        for (int i = 0; i < index-1; i++) {
            p=p.next;
        }
        p.data=e;
    }

    @Override
    public boolean contains(E e) {
        return find(e)!=-1;
    }

    @Override
    public int find(E e) {
        Node p=head;
        for (int i = 0; i < size-1; i++) {
            if(p.data.equals(e)){
                return i;
            }
            p=p.next;
        }
        return -1;
    }

    @Override
    public E remove(int index) {
        if(isEmpty()){
            throw new IllegalArgumentException("空表");
        }
        if(index<0||index>=size){
            throw new IllegalArgumentException("角标越界");
        }
        E ret =null;
        if(size==1){
            ret =head.data;
            head=null;
            rear=head;
        }else if(index==size-1){
            ret =head.data;
            Node p=head;
            while(p.next!=rear){
                p=p.next;
            }
            p.next=rear.next;
            rear=p;
        }else if(index==0){
            ret =head.data;
            head.next=rear.next;
            head=head.next;
        }else{

            Node p=head;
            for (int i = 0; i < index-1; i++) {
                p=p.next;
            }
            Node del =p.next;
            ret =del.data;
        }
        return ret;
    }

    @Override
    public E removeFirst() {
        return remove(0);
    }

    @Override
    public E removeLast() {
        return remove(size-1);
    }

    @Override
    public void removeElement(E e) {
        int index=find(e);
        if(index!=-1){
            remove(index);
        }else{
            throw new IllegalArgumentException("不合法");
        }
    }

    @Override
    public void clear() {

    }

    @Override
    public Iterator<E> iterator() {
        return new LinkedSingleLoopIterator();
    }

    //迭代器利用计数
    public class LinkedSingleLoopIterator implements Iterator<E>{
        //建立一个虚结点,利用虚节点进行判断
        Node p;
        public LinkedSingleLoopIterator(){
            p=new Node();
            p.next=head;
        }
        @Override
        public boolean hasNext() {
            return p!=rear;
        }

        @Override
        public E next() {
            p=p.next;
            return p.data;
        }
    }
}

你可能感兴趣的:(Java数据结构:链栈,双端栈,循环单链表)