链表_单向链表模拟

链表

  • 链表以节点的方式进行存储
  • 链表节点包括 data(存放数据),next(存放下一节点的指针)
  • 各个节点不一定是连续
  • 链表分 有头节点的链表、没有头节点的链表
package com.zsx.structure.linkedlist;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 单链表
 */
public class SingleLinkedListDemo {

    public static void main(String[] args) {
        //创建单链表
        SingleLinkedList singleLinkedList = new SingleLinkedList();

        //创建节点
        HeroNode heroNode1 = new HeroNode(1, "A", "aa");
        HeroNode heroNode2 = new HeroNode(2, "B", "bb");
        HeroNode heroNode3 = new HeroNode(3, "C", "cc");
        HeroNode heroNode4 = new HeroNode(5, "E", "ee");
        HeroNode heroNode5 = new HeroNode(4, "D", "dd");

        HeroNode heroNode6 = new HeroNode(4, "Z", "zz");
        //加入
        singleLinkedList.addByOrder(heroNode1);
        singleLinkedList.addByOrder(heroNode2);
        singleLinkedList.addByOrder(heroNode3);
        singleLinkedList.addByOrder(heroNode4);
        singleLinkedList.addByOrder(heroNode5);
        singleLinkedList.addByOrder(heroNode5);
        //修改
        singleLinkedList.update(heroNode6);
        singleLinkedList.delete(1);
        //展示
        singleLinkedList.show();

//        - #### 单链表中有效节点的个数
        System.out.println(singleLinkedList.getCount());

//         - #### 查找单链表中的单数第K个节点
        System.out.println(singleLinkedList.getNode(4));

//        - #### 单链表的反转
//        singleLinkedList.reverse2();
//        singleLinkedList.show();

//        - #### 从头打为打印单链表 要求①反向遍历 方式②Stack栈
        singleLinkedList.showByRevese();

//        - #### 合并有序的单链表,合并后依旧有序


    }

}


class SingleLinkedList {
    //初始化头结点
    private HeroNode head = new HeroNode(0, "", "");

    /**
     * 添加
     * 添加到列表的最后
     * ①找到当前列表的最后节点
     * ②将最后节点的next指向新的节点
     *
     * @param heroNode
     */
    public void addLast(HeroNode heroNode) {
        //临时
        HeroNode tmp = head;

        //遍历链表,找到最后的节点
        while (true) {
            //没有下一个节点,则为最一个节点
            if (tmp.getNext() == null) {
                break;
            }
            //向后移
            tmp = tmp.getNext();
        }
        //设置新的节点
        tmp.setNext(heroNode);

    }


    /**
     * 修改
     * 根据编号修改英雄
     *
     * @param heroNode
     */
    public void update(HeroNode heroNode) {

        //判断是否为空
        if (head.getNext() == null) {
            System.out.println("空");
            return;
        }
        HeroNode tmp = head;
        //表示是否找到
        boolean flag = false;
        while (true) {
            if (tmp == null) {
                break;
            }

            if (tmp.getNo() == heroNode.getNo()) {
                //找到
                flag = true;
                break;
            }

            tmp = tmp.getNext();

        }
        if (flag) {
            tmp.setName(heroNode.getName());
            tmp.setNickName(heroNode.getNickName());
        } else {
            System.out.println("找不到");
        }

    }

    /**
     * 根据no删除
     *
     * @param no
     */
    public void delete(int no) {
        //判断是否为空
        if (head.getNext() == null) {
            System.out.println("空");
            return;
        }
        HeroNode tmp = head;

        //是否找到
        boolean flag = false;

        while (true) {

            if (tmp.getNext() == null) {
                //最后一个节点了
                break;
            }
            if (tmp.getNext().getNo() == no) {
                flag = true;
                break;
            }
            tmp = tmp.getNext();
        }

        if (flag) {
            //指针指向要删除指针的下一个节点。

            tmp.setNext(tmp.getNext().getNext());
        } else {
            System.out.println("找不到");
        }

    }

    /**
     * 插入中间
     *
     * @param heroNode
     */
    public void addByOrder(HeroNode heroNode) {
        //临时
        HeroNode tmp = head;
        //默认添加的编号不存在
        boolean flag = false;
        //遍历链表,找到要插入的节点
        while (true) {
            //没有下一个节点,则为最一个节点
            if (tmp.getNext() == null) {
                break;
            }
            //大于当前节点的no
            if (tmp.getNext().getNo() > heroNode.getNo()) {
                break;
            } else if (tmp.getNext().getNo() == heroNode.getNo()) {
                flag = true;
            }
            //向后移
            tmp = tmp.getNext();
        }
        if (flag) {
            //编号存在
            System.out.println("已经存在相同编号:" + heroNode);
            return;
        }
        //设置新的节点
        //声明原先的节点
        HeroNode preNode = tmp.getNext();
        heroNode.setNext(preNode);
        tmp.setNext(heroNode);

    }

    /**
     * 显示
     */
    public void show() {
        System.out.println("-------------show--------------");
        //空链表
        if (head.getNext() == null) {
            return;
        }
        //临时
        HeroNode tmp = head.getNext();
        while (true) {
            System.out.println(tmp);
            //没有下一个节点,则为最一个节点
            if (tmp.getNext() == null) {
                break;
            }
            //向后移
            tmp = tmp.getNext();
        }
    }


    //        - #### 单链表中有效节点的个数
    public int getCount() {
        int count = 0;

        HeroNode tmp = head.getNext();

        while (tmp != null) {
            count++;
            tmp = tmp.getNext();
        }

        return count;
    }


    //         - #### 查找单链表中的第K个节点
    public HeroNode getNode(int k) {
        int count = 0;

        HeroNode tmp = head.getNext();
        HeroNode result = null;
        while (tmp != null) {
            count++;
            if (count == k) {
                result = tmp;
                break;
            }

            tmp = tmp.getNext();
        }

        return result;
    }

    /**
     * - #### 单链表的反转
     * 方法①:存入容器,遍历容器
     */
    public void reverse() {
        HeroNode tmp = head.getNext();
        List<HeroNode> list = new ArrayList();

        while (tmp != null) {
            list.add(tmp);
            tmp = tmp.getNext();
        }

        HeroNode tmp1 = head;
        int i = list.size() - 1;
        //移除 最后一个元素的尾指针
        list.get(0).setNext(null);
        while (i >= 0) {
            tmp1.setNext(list.get(i));
            tmp1 = tmp1.getNext();
            i--;
        }

    }

    /**
     * - #### 单链表的反转
     * 方法②:克隆节点
     */
    public void reverse1() {
        HeroNode tmp = head.getNext();
        //获取尾部节点
        HeroNode reverseNode = tmp.clone();
        reverseNode.setNext(null);

        while (tmp != null) {

            if (tmp.getNext() == null) {
                break;
            }

            HeroNode tmp1 = tmp.getNext().clone();
            tmp1.setNext(reverseNode);
            reverseNode = tmp1;

            //指针指向下游
            tmp = tmp.getNext();

        }
        head.setNext(reverseNode);
    }

    /**
     * - #### 单链表的反转
     * 方法③:
     */
    public void reverse2() {

        if (head.getNext() == null || head.getNext().getNext() == null) {
            return;
        }
        //辅助指针 --> 遍历链表使用
        HeroNode cur = head.getNext();
        //指向当前节点的下一个节点
        HeroNode next = null;
        //
        HeroNode reverse = null;

        while (cur != null) {
            //先保存下一节点
            next = cur.getNext();
            //设置新的当前节点的下一节点
            cur.setNext(reverse);
            //
            reverse = cur;
            //指针下移
            cur = next;
        }

        head.setNext(reverse);

    }

    /**
     * 从头打为打印单链表 要求①反向遍历 方式②Stack栈
     * 方式②:Stack栈
     */
    public void showByRevese() {
        System.out.println("反向遍历~~~~~~~~~~");
        HeroNode cur = head.getNext();
        //创建栈
        Stack<HeroNode> stack = new Stack<>();
        while (cur != null) {

            //入栈
            stack.add(cur);
            //指针下移
            cur = cur.getNext();
        }
        while (true) {
            if (!stack.isEmpty()) {
                System.out.println(stack.pop());
            }
        }
    }


//        - #### 合并有序的单链表,合并后依旧有序

    /**
     * 添加其他
     * @param heroNodeHead
     */
    public void add(HeroNode heroNodeHead){



    }

}

/**
 * 模拟英雄排行
 */
class HeroNode implements Cloneable {

    /**
     * 号码
     */
    private int no;

    /**
     * 名字
     */
    private String name;

    /**
     * 昵称
     */
    private String nickName;

    /**
     * 下一个
     */
    private HeroNode next;

    public HeroNode(int no, String name, String nickName) {
        this.no = no;
        this.name = name;
        this.nickName = nickName;
    }

    @Override
    public String toString() {
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nickName='" + nickName + '\'' +
                '}';
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public HeroNode getNext() {
        return next;
    }

    public void setNext(HeroNode next) {
        this.next = next;
    }

    @Override
    protected HeroNode clone() {
        // TODO Auto-generated method stub
        try {
            return (HeroNode) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值