单链表

基本概念

  单链表分为带头结点和不带头节点。带头结点的单链表,头指针head指向头结点,头结点中不包含任何的信息。例如下图
## 图1

单链表的基本操作

单链表的增加

单链表的无序增加

思路

  head是头指针,它不能动,因此我们需要创建临时遍历。
  主要使用的方法便是尾插法,首先遍历整个链表,找到最后一个节点。再在链表的尾部插入结点。

代码实现
//创建英雄节点
package LinkedList链表;

import java.util.Stack;

public class SingleLinkedListDemo {
    public static void main(String[] args) {
        HeroNode heroNode1 = new HeroNode(1,"宋江","及时雨");
        HeroNode heroNode2 = new HeroNode(2,"吴用","智多星");
        HeroNode heroNode3 = new HeroNode(3,"林冲","豹子头");
        HeroNode heroNode4 = new HeroNode(4,"卢俊义","玉麒麟");
        HeroNode heroNode5 = new HeroNode(4,"卢哥","玉麒麟~~");

        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.add(heroNode1);
        singleLinkedList.add(heroNode4);
        singleLinkedList.add(heroNode2);
        singleLinkedList.add(heroNode3);
	}
}

//创建单链表
class SingleLinkedList{
    private HeroNode head = new HeroNode(0,"","");

    public HeroNode getHead() {
        return head;
    }

    public void add(HeroNode heroNode){
        //因为head是头指针,因此我们要创建一个临时变量
        HeroNode temp = head;
        //遍历链表,找到最后
        while (true){
            if(temp.next == null){
                break;
            }
            //如果没有找到最后,继续往后找
            temp = temp.next;
        }
        //退出循环说明找到最后一个,将最后一个指向新的节点
        temp.next = heroNode;
    }


}
class HeroNode{
    public int num;
    public String name;
    public String nickname;
    public HeroNode next;

    //生成构造器
    public HeroNode(int num, String name, String nickname) {
        this.num = num;
        this.name = name;
        this.nickname = nickname;
    }

    //重写toString

    @Override
    public String toString() {
        return "heroNode{" +
                "num=" + num +
                ", name='" + name + '\'' +
                ", nickname='" + nickname + '\'' +
                '}';
    }
}

单链表的有序增加

思路

  在单链表中,我们需要找到的temp是位于添加位置的前一个结点,不然插入不了
  1)因为head为头结点,不能变动,因此还是创建一个临时变量。同时需要创建一个boolean标志值变量,用来判断添加的标号是否存在
  2)判断链表是否为空
  3)判断结点中数据类的编号的大小

代码实现

  单链表内部方法

    public void addByOrder(HeroNode heroNode){
        HeroNode temp = head;
        boolean flag = false;
        while (true){
            if(temp.next == null){
                break;
            }
            if (temp.next.num > heroNode.num){
                break;
            }else if (temp.next.num == heroNode.num){
                flag = true;
                break;
            }
            temp = temp.next;
        }

        if(flag){
            System.out.println("输入的编号已经存在");
        }else {
            heroNode.next = temp.next;
            temp.next = heroNode;
        }
    }

单链表的遍历

思路

  主要原理为循环遍历单链表,判定结点是否为空。

代码实现

  单链表内部方法

    public void list(){
        if(head.next == null){
            System.out.println("链表为空");
            return;
        }
        //因为head是头指针,因此我们要创建一个临时变量
        HeroNode temp = head.next;
        while (true){
            if(temp == null){
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }
    }

单链表的删除

思路

  给定形参编号,删除数据域为该编号的结点
  1)创建临时变量代替头结点,创建boolean标志值。
  2)循环遍历单链表,找到数据域为指定编号的结点。

代码实现

  单链表内部方法

    public void delete(int no){
        HeroNode temp = head;
        boolean flag = false;
        while (true){
            if(temp.next == null){
                break;
            }
            if (temp.next.num == no){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag){
            temp.next = temp.next.next;
        }else {
            System.out.println("没有该节点");
        }
    }

单链表的修改

思路

  删除指定编号的结点
  1)循环遍历单链表,找到指定编号的结点
  2)进行删除操作(被删除结点的上一个结点的next指针指向被删除结点下一个结点)

代码实现

    public void update(HeroNode heroNode){
        HeroNode temp = head.next;
        boolean flag = false;
        while (true){
            if(temp == null){
                break;
            }
            if (temp.num == heroNode.num){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.name = heroNode.name;
            temp.nickname = heroNode.nickname;
        }else {
            System.out.println("没有找到");
        }
    }

单链表的进阶操作

返回单链表中有效节点个数,不包含头结点

思路

  主要是利用循环遍历单链表,节点不为空。

代码实现

    public static int getLength(HeroNode head){
        if (head.next == null){
            return 0;
        }
        int length = 0;
        HeroNode temp = head.next;
        while (temp != null){
            temp = temp.next;
            length++;
        }
        return length;
    }

打印倒数第k个结点

思路

  找到有效个数,(打印倒数第k个 )== (打印整数length-k个)

代码实现

    public static HeroNode getLastNode(HeroNode head, int k){
        if(head.next == null){
            return null;
        }

        int length = getLength(head);
        if(k<=0 || k>length){
            return null;
        }

        HeroNode temp = head.next;
        for (int i = 0;i < length - k;i++){
            temp = temp.next;
        }
        return temp;
    }

单链表的反转

思路

  1)先定义一个新的头结点
  2)从头遍历原来的链表,每遍历一个结点,就取出,放在新的头结点最前端。
  3)head.next = reverseHead.next,使新的头结点第一个元素连接到原来头结点后边

代码实现

    public static void reversetList(HeroNode head){
        if(head.next == null || head.next.next == null){
            return;
        }
        HeroNode cur = head.next;
        HeroNode next = null;
        HeroNode reverseHead = new HeroNode(0,"","");

        while (cur != null){
        //记录当前节点的下一个结点内容,如果不记录链表会断开
            next = cur.next;
        //将新节点后边的结点连接点当前指针的后边
            cur.next = reverseHead.next;
       //每次循环都令新的头结点后面插入cur结点
            reverseHead.next = cur;
       //令指针向后移动
            cur = next;
        }
        head.next = reverseHead.next;
    }

不改变单链表结构逆序输入单链表中内容

思路

  1)先将单链表进行反转,再遍历。缺点会改变单链表的结构。
  2)利用栈这个数据结构先进后出的特点。实现逆序打印。

代码实现

public static void printContent(SingleLinkedList singleLinkedList){
        if (singleLinkedList.getHead().next == null){
            return;
        }
        Stack<HeroNode> stack = new Stack<HeroNode>();
        while (singleLinkedList.getHead().next != null){
            stack.push(singleLinkedList.getHead().next);
            singleLinkedList.getHead().next = singleLinkedList.getHead().next.next;
        }
        while (stack.size()>0){
            System.out.println(stack.pop());
        }
    }

声明

  本文是作者在学习数据结构中的一些笔记,希望能够帮助到大家。作者才疏学浅,如有错误,欢迎批评指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值