数据结构之链表

一.单链表

package com.bzw.linkedlist;

import java.util.Stack;

public class SingleLinkedList {
    public static void main(String[] args) {

        Hero hero1 = new Hero(1, "宋江", "及时雨");
        Hero hero2 = new Hero(2, "卢俊义", "玉麒麟");
        Hero hero3 = new Hero(3, "吴用", "智多星");
        Hero hero4 = new Hero(4, "林冲", "豹子头");
        Hero hero5 = new Hero(5, "小卢", "玉麒麟~~");
        Hero hero6 = new Hero(6, "小卢", "玉麒麟~~");

        SingleLinked singleLinked = new SingleLinked();
        SingleLinked singleLinked1 = new SingleLinked();

//        singleLinked.addHero(hero2);
//        singleLinked.addHero(hero3);
//        singleLinked.addHero(hero4);
//        singleLinked.addHero(hero1);


        singleLinked.addHeroByOrder(hero3);
        singleLinked.addHeroByOrder(hero2);
        singleLinked1.addHeroByOrder(hero4);
        singleLinked.addHeroByOrder(hero1);
        singleLinked.addHeroByOrder(hero5);
        singleLinked1.addHeroByOrder(hero6);

//        singleLinked.addHeroByOrder(hero4);
//        singleLinked.showHero();
//        singleLinked.update(hero5);
//        singleLinked.delete(hero4);
        singleLinked.showHero();
        System.out.println();
        singleLinked1.showHero();

        //练习题
//        System.out.println("有效结点个数"+getLength(singleLinked.getHead()));
//
//        System.out.println(findNode(singleLinked.getHead(),4));

//        reverseLinkedList(singleLinked.getHead());
//        singleLinked.showHero();

//        reversePrint(singleLinked.getHead());

        jojnLinkedList(singleLinked.getHead(), singleLinked1.getHead());
        System.out.println();

        singleLinked.showHero();

    }

    //链表有效结点个数
    public static int getLength(Hero head) {
        if (head.next == null) {
            System.out.println("链表为空");
            return 0;
        }
        Hero temp = head.next;
        int count = 0;
        while (temp != null) {
            count++;
            temp = temp.next;
        }
        return count;
    }

    //查询倒数第k个结点
    public static Hero findNode(Hero head, int index) {
        if (head.next == null) {
            System.out.println("空链表");
        }
        int size = getLength(head);
        Hero temp = head.next;
        if (index < 0 || index > size) {
            return null;
        }
        for (int i = 0; i < size - index; i++) {
            temp = temp.next;
        }
        System.out.println("倒数第" + index + "个结点:");
        return temp;
    }

    //反转链表
    public static void reverseLinkedList(Hero head) {
        if (head.next == null) {
            System.out.println("空链表");
        }
        Hero temp = head.next;
        Hero next = null;     //temp 结点的下一个(非常重要的一个指针(变量),不用这个变量把temp.next存起来的话,单链表就会断掉)
        Hero newHead = new Hero(0, "", "");
        while (temp != null) {
            next = temp.next;
            temp.next = newHead.next;     //temp的下一个结点指向新链表的最前端。(其实就是将新加入的结点和后面的结点连接起来)
            newHead.next = temp;
            temp = next;

        }
        head.next = newHead.next;
    }

    //逆序打印(利用栈的先进后出特点,不破坏原链表的结构)
    public static void reversePrint(Hero head) {
        if (head.next == null) {
            System.out.println("链表为空");
        }
        Stack<Hero> stack = new Stack<>();
        Hero temp = head.next;
        while (temp != null) {

            stack.push(temp);
            temp = temp.next;

        }
        while (stack.size() > 0) {
            System.out.println(stack.pop());
        }

    }

    //将两个链表按顺序合并成一个链表(练习)
    public static void jojnLinkedList(Hero head1, Hero head2) {
        Hero temp1 = head1.next;
        Hero temp2 = head2.next;
        Hero temp3 = null;      //暂存temp1.next;如果不用一个变量暂存的话,后面temp1.next已经指向了其他的值,就不是我们想要的结果。
        while (temp1 != null && temp2 != null) {
            if(temp1.next == null){
                temp1.next = temp2;
                break;
            }
            if (temp2.no > temp1.no && temp2.no < temp1.next.no) {
                head2.next = temp2.next;
                temp3 = temp1.next;
                temp1.next = temp2;
                temp2.next = temp3;
                temp1 = temp1.next;
                temp2 = head2.next;
            } else temp1 = temp1.next;
        }
    }
}
/*
    private 私有 只能在同一个类中才能访问到
    friendly(默认) 同一个包下可以访问(子孙类也只能在同一个包下)
    protected 保护  同一个包下可以访问(其他包的继承了用protected修饰的,其子孙类也可以继承,即其他包的子孙类也可以访问)
    public 公共 在哪都能访问到
 */
class Hero{
    public int no;
    public String name;
    public String nickName;
    public Hero next;

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


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

class SingleLinked{
    Hero head = new Hero(0,"","");//头结点

    public Hero getHead() {
        return head;
    }

    //直接添加在链表尾部(不考虑顺序)
    public  void addHero(Hero heroNode){
        Hero temp = head;       //因为是单链表,头结点不能动,否则会找不到链表。所以利用一个temp结点来完成操作
        while(true){

            if(temp.next == null){
                break;
            }
            temp = temp.next;
        }
        temp.next = heroNode;

    }

    //按顺序添加
    public void addHeroByOrder(Hero heroNode){
        Hero temp = head;

        while (true){
            if(temp.next == null){
                temp.next = heroNode;
                break;
            }
            else if(heroNode.no < temp.next.no){
                heroNode.next = temp.next;
                temp.next = heroNode;
                break;
            }
            if(heroNode.no == temp.next.no){
                System.out.printf("结点%d已存在,插入失败\n",heroNode.no);
                break;

            }

            temp = temp.next;

        }


    }

    public void delete(Hero heroNode){

        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        Hero temp = head;       // temp 是等于head 还是等于 head.next 。具体需要具体分析
        Boolean flag = false;
        while (true){
            if(temp.next == null){
                break;
            }
            if(temp.next.no == heroNode.no){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if(flag){
            temp.next = temp.next.next;
        }
        else {
            System.out.println("没有你要删除的结点");
        }
    }
    public void update(Hero heroNode){
        Hero temp = head.next ;
        if(temp == null){
            System.out.println("链表为空,请先插入数据");
            return;
        }
        while (true){
            if(temp == null ){
                System.out.println("没有该结点");
                break;
            }
            if(temp.no == heroNode.no){
                temp.name = heroNode.name;
                temp.nickName = heroNode.nickName;
                break;
            }

            temp = temp.next;
        }
    }
    public void showHero(){
        if(head.next == null){
            System.out.println("链表为空");
        }
        Hero temp = head.next;
        while (true){
            if(temp == null){
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }


}

二.双向链表

package com.bzw.linkedlist;

public class DoubleLinked {

    public static void main(String[] args) {

        Hero2 hero1 = new Hero2(1, "宋江", "及时雨");
        Hero2 hero2 = new Hero2(2, "卢俊义", "玉麒麟");
        Hero2 hero3 = new Hero2(3, "吴用", "智多星");
        Hero2 hero4 = new Hero2(4, "林冲", "豹子头");
        Hero2 hero5 = new Hero2(2, "小卢", "玉麒麟~~");

        DoubleLinkedList doubleLinkedList = new DoubleLinkedList();

//        doubleLinkedList.add(hero1);
//        doubleLinkedList.add(hero2);
//        doubleLinkedList.add(hero3);
//        doubleLinkedList.add(hero4);

        doubleLinkedList.addByOrder(hero1);
        doubleLinkedList.addByOrder(hero4);
        doubleLinkedList.addByOrder(hero2);
        doubleLinkedList.addByOrder(hero3);

        doubleLinkedList.delete(hero3);

//        doubleLinkedList.update(hero5);
//        doubleLinkedList.delete(hero5);

        doubleLinkedList.showLinked();


    }
}

class Hero2{
    public int no;
    public String name;
    public String nick;
    public Hero2 pre;
    public Hero2 next;

    public Hero2(int no,String name,String nick){
        this.no = no;
        this.name = name;
        this.nick = nick;
    }

    @Override
    public String toString() {
        return "Hero2{" +
                "no=" + no +
                ", name='" + name + '\'' +
                ", nick='" + nick + '\'' +
                '}';
    }
}
class DoubleLinkedList{
    Hero2 head = new Hero2(0,"","");

    public Hero2 getHead() {
        return head;
    }

    //遍历(不要小看任何一个操作,思路稍微有点错就达不到理想效果)
    public void showLinked(){
        if(head.next == null){
            System.out.println("链表为空");
        }
        Hero2 temp = head.next;
        while (true){
            if(temp == null){
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }


    //添加(直接添加在最后)
    public void add(Hero2 newHeroNode) {
        Hero2 temp = head;
        while (true) {
            if (temp.next == null){
                break;
            }
             temp = temp.next;

        }
        temp.next = newHeroNode;
        newHeroNode.pre = temp;
    }

    //添加(按顺序添加)
    public void addByOrder(Hero2 newHeroNode){
        Hero2 temp = head;
        while (true){
            if (temp.next == null){
                temp.next = newHeroNode;
                newHeroNode.pre = temp;
                break;
            }
            if (newHeroNode.no > temp.no && newHeroNode.no < temp.next.no ){
                temp.next.pre = newHeroNode;
                newHeroNode.next = temp.next;
                temp.next = newHeroNode;
                newHeroNode.pre = temp;
                break;
            }
            else if (newHeroNode.no < temp.no && newHeroNode.no >temp.pre.no){
                newHeroNode.pre = temp.pre;
                temp.pre.next = newHeroNode;
                temp.pre = newHeroNode;
                newHeroNode.next = temp;
                break;
            }
            else if (newHeroNode.no == temp.no){
                System.out.println("结点已存在");
            }
            temp = temp.next;
        }

    }

    //修改
    public void update(Hero2 newHeroNode){

        Hero2 temp = head.next;

        if (temp == null){
            System.out.println("空链表");
        }
        while (true){
            if (temp.no == newHeroNode.no){
                temp.name = newHeroNode.name;
                temp.nick = newHeroNode.nick;
                break;
            }
            temp = temp.next;
        }
    }

    //删除(双向链表的删除和单链表有所不同。单链表删除时是找到要删除结点的前一个结点,
    // 而双向链表就是找到要删除的这个结点。)
    public void delete(Hero2 heroNode){

        Hero2 temp = head.next;
        while (true){
            if (temp.no == heroNode.no){
                temp.pre.next = temp.next;
                temp.next.pre = temp.pre;
                break;
            }
            temp = temp.next;
        }

    }

}

三.循环链表(约瑟夫问题)

package com.bzw.linkedlist;

//约瑟夫环实现代码
public class RingLinkedList {

    public static void main(String[] args) {

        RingLinked ringLinked = new RingLinked();

        ringLinked.add(5);
        ringLinked.show();

        ringLinked.countBoy(1,2,5);
    }
}

class Boy{

    private int no;
    private Boy next;

    public Boy(int no){
        this.no = no;
    }
    public int getNo() {
        return no;
    }

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

    public Boy getNext() {
        return next;
    }

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

    @Override
    public String toString() {
        return "Boy{" +
                "no=" + no +
                '}';
    }
}


class RingLinked{

    Boy first = null;

    //添加(这里是实现约瑟夫环问题代码,实现环形链表可以设头结点也可以不设)
    public void add(int nums) {

        Boy temp = null;

        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);

            if (i == 1) {
                first = boy;
                first.setNext(first);
                temp = first;
            } else {
                temp.setNext(boy);
                boy.setNext(first);
                temp = boy;
            }
        }
    }

    //遍历
    public void show(){

        if (first == null){
            System.out.println("空链表");
            return;
        }

        Boy temp = first;
        while (true){
            System.out.println(temp);
            if (temp.getNext() == first){
                break;
            }
            temp = temp.getNext();
        }
    }

    //出圈顺序
    public void countBoy(int k,int m,int n){

        Boy helper = first;//始终跟在first后面,用于删除结点
        while (true){
            if (helper.getNext() == first)
                break;
            else {
                helper = helper.getNext();//helper = helper.next;
            }
        }
        //移动到开始报数的那个位置
        for (int i=0;i<k-1;i++){
            first = first.getNext();
            helper = helper.getNext();
        }
        while (true){
            //圈中只剩一个结点
            if (helper == first){
                break;
            }
            for (int i=0;i<m-1;i++){
                first = first.getNext();
                helper = helper.getNext();
            }
            System.out.println("出圈结点为:" + first.getNo());
            first = first.getNext();
            helper.setNext(first);//helper.next = first;
        }
        System.out.println("最后一个结点为:"+helper.getNo());
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值