数据结构-双向链表实现

一.Node节点类

/**
 * @author 2902996750
 * @version 1.0
 * @date 2022/10/6 16:38
 * Node对象
 */
public class Node<T> {
    /**
     * 存放Node对象值
     */
    T item;
    /**
     * 存放前一个Node对象
     */
    Node pre;
    /**
     * 存放后一个Node对象
     */
    Node next;

    public Node(T item, Node pre, Node next) {
        this.item = item;
        this.pre = pre;
        this.next = next;
    }
}

二.双向链表实现类 

import java.util.Iterator;

/**
 * @author 2902996750
 * @version 1.0
 * @date 2022/10/6 16:39
 * 实现双向链表
 */
public class TowWayLinkList<T> implements Iterable {
    /**
     * 头结点
     */
    Node<T> head;
    /**
     * 尾结点
     */
    Node<T> last;
    /**
     * 元素个数
     */
    int count;

    public TowWayLinkList() {
        //初始化头结点和尾结点
        this.head = new Node<T>(null,null,null);
        this.last = null;
        this.count = 0;
    }

    /**
     * 清空链表
     */
    public void clear(){
        this.head.next=null;
        this.head.pre=null;
        this.head.item=null;
        this.last=null;
        this.count=0;
    }

    /**
     * 获取链表长度
     */
    public int length(){
        return count;
    }

    /**
     * 判断链表是否为空
     */
    public boolean isEmpty(){
        return count==0;
    }

    /**
     * 获取链表第一个元素
     * @return
     */
    public Node<T> getFirst(){
        if (!isEmpty()){
            return this.head.next;
        }
        return null;
    }

    /**
     * 获取最后一个元素
     */
    public Node<T> getLast(){
        if (!isEmpty()){
            return last;
        }
        return null;
    }

    /**
     * 插入元素
     */
    public void insert(T t){
        //如何链表为空
        if (isEmpty()){
            Node<T> tNode = new Node<>(t, head, null);
            head.next=tNode;
            last=tNode;
        }else {
            //链表不为空
            Node<T> tNode = new Node<>(t, last, null);
            last.next=tNode;
            last=tNode;
        }
        count++;
    }

    /**
     * 向指定位置插入元素
     */
    public void insert(int n,T t){
        //找到n位置的上一个节点
        Node node=head;
        for (int i = 0; i < n-1; i++) {
            node=node.next;
        }
        //找到第n个节点
        Node next = node.next;
        //创建一个新节点
        Node<T> node1 = new Node<>(t, node, next);
        node.next=node1;
        next.pre=node1;
        count++;
    }

    /**
     * 获取指定位置的值
     */
    public T get(int count){
        Node node=head;
        for (int i = 0; i < count; i++) {
            node=node.next;
        }
        return (T)node.item;
    }

    /**
     * 获取指定元素t在链表中第一次出现的位置
     */
    public int indexof(T t){
        Node node=head;
        int i;
        for ( i = 0; i < count; i++) {
            if (node.next.item.equals(t)){
                break;
            }
        }
        return i;
    }

    /**
     * 删除指定索引对应节点
     * @param count 指定元素的位置
     * @return true false
     */
    public T remove(int count){
        Node node=head;
        //count对应前一个节点
        Node node1;
        //count对应后一个节点
        Node node2;
        for (int i = 0; i < count; i++) {
            node=node.next;
        }
        node1=node.pre;
        node2=node.next;
        node1.next=node2;
        node2.pre=node1;
        count--;
        return (T) node.item;
    }

    /**
     * 反转链表
     */
    public void reverse(){
        if(!isEmpty()) {
            reverse(head.next);
        }
    }

    /**
     * 反转链表中的某个节点,并把反转后的节点返回
     * 反转链表原理:
     *     1.调用reverse方法反转每一个节点,从节点1开始
     *     2.如果发现有下一个节点,则递归调用reverse对下一个节点反转
     *     3.最终没有下一个节点时,让head指向最后一个元素节点。
     * @return
     */
    public Node reverse(Node node){
        Node node1=head;
        if (node.next!=null){
            Node reverse = reverse(node.next);
            node1=reverse;
        }
        node.pre=node1;
        node.next=null;
        node1.next=node;
        return node;
    }

    @Override
    public Iterator iterator() {
        return new Titerator(head);
    }
}

三.实现迭代器

import java.util.Iterator;

/**
 * @author 2902996750
 * @version 1.0
 * @date 2022/10/6 18:41
 */
public class Titerator implements Iterator {
    private Node node;

    public Titerator(Node node) {
        this.node = node;
    }

    @Override
    public boolean hasNext() {
        return node.next!=null;
    }

    @Override
    public Object next() {
        node = node.next;
        return node.item;
    }
}

四.测试类

import java.util.Iterator;

/**
 * @author 2902996750
 * @version 1.0
 * @date 2022/10/6 18:46
 */
public class Test {
    public static void main(String[] args) {
        TowWayLinkList<Object> list = new TowWayLinkList<>();
        list.insert("chai");
        list.insert("jian");
        list.insert("fu");
        list.insert("chaijianfu");
        list.insert(1,"1");
        System.out.println("---------------------------");
        System.out.println("获取第一个元素:"+list.getFirst().item);
        System.out.println("获取最后一个元素:"+list.getLast().item);
        System.out.println("获取指定下标元素:"+list.get(2));
        System.out.println("---------------------------");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }
        System.out.println("---------------------------");
        Object remove = list.remove(2);
        System.out.println("删除的元素的值:"+remove);
        System.out.println("---------------------------");
        list.reverse();
        Iterator iterator1 = list.iterator();
        while (iterator1.hasNext()){
            Object next = iterator1.next();
            System.out.println(next);
        }
    }
}

五.例题

package 例题;

/**
 * @author 2902996750
 * @version 1.0
 * @date 2022/10/8 10:34
 * 单链表
 */
public class Node<T> {
    T t;
    Node next;

    public Node(T t, Node next) {
        this.t = t;
        this.next = next;
    }
}
package 例题;

/**
 * @author 2902996750
 * @version 1.0
 * @date 2022/10/8 10:18
 */
public class Test {
    /**
     * 约瑟夫问题:
     *      描述:41个人坐一圈,第一个人编号为1,第二个编号为2,以此类推
     *           编号1的开始报数,依次向后,报数为3的人自杀退出圈
     *           从退出那个人开始的下一个人再次从1开始报数,以此类推
     *           求出最后退出的那个人的编号
     * @param args
     */
    public static void main(String[] args) {
        //1.构建41个循环链表,设计一个计数器
        //生成第一个节点
        Node<Integer> first = new Node<>(1, null);
        //记录前一个节点
        Node<Integer> node=first;
        for (int i = 2; i <=41; i++) {
            Node<Integer> node1 = new Node<>(i, null);
            node.next=node1;
            node=node1;
        }
        node.next=first;
        //设计计数器
        int count=1;
        //2。遍历循环列表
        Node node1=first;
        //记录自杀人的前一个节点
        Node node2 = null;
        //记录自杀人的后一个节点
        Node node3 = null;
        while (count<=3){
            if (count==3){
                System.out.println("自杀人的编号:"+node1.t);
                node3=node1.next;
                node2.next=node3;
                node1=node3;
                count=1;
                continue;
            }
            node2=node1;
            node1=node1.next;
            //这里因为是3个数报数,肯定会留下两个人报数
            //如果是其他数就需要考虑其他停止条件
            if (node1.next.next==node1){
                System.out.println("最后没有自杀的编号:"+node1.next.t);
                System.out.println("最后没有自杀的编号:"+node1.t);
                break;
            }
            count++;
        }
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值