JAVA语言实现单链表的增删改查

数据结构中基本链表结构特点:
(1)链表是以节点的方式来存储,属于链式存储;
(2)每个节点包含data域,next域:指向下一节点;
(3)链表的各个节点不一定是连续存储;
(4)头节点不存储数据,只用于指向下一个节点。
下面的程序是单向链表的基本操作,增删改查,反转,逆序打印。

package yu.practice03.Linkedlist;

import org.w3c.dom.ls.LSOutput;

import java.util.Stack;

public class singlelistDemo {
    public static void main(String[] args) {
        PersonNode person01 = new PersonNode(1,"张三","三三");
        PersonNode person02 = new PersonNode(2,"李四","四四");
        PersonNode person03 = new PersonNode(3,"王五","五五");
        PersonNode person04 = new PersonNode(4,"陈六","六六");
        LinkedList linkedlist = new LinkedList();
        linkedlist.add(person01);
        linkedlist.add(person02);
        linkedlist.add(person03);
        linkedlist.add(person04);
        System.out.println("将新节点插入到链表末尾的方法:");
        linkedlist.show();
        System.out.println("linkedlist链表的有效长度:" + LinkedList.getLength(linkedlist.getHead()));
        System.out.println("=======================================================");
        System.out.println("将新节点按照num的大小有序插入的方法:");
        LinkedList list = new LinkedList();
        list.addByOrder(person04);
        list.addByOrder(person02);
        list.addByOrder(person03);
        list.addByOrder(person01);
        list.show();
        System.out.println("linkedlist链表的有效长度:" + LinkedList.getLength(linkedlist.getHead()));
        System.out.println("=======================================================");
        System.out.println("删除一个节点:");
        list.delete(3);
        list.delete(6);
        list.show();
        System.out.println("=======================================================");
        System.out.println("更新一个节点:");
        PersonNode person05 = new PersonNode(2,"李子","小五");
        list.update(person05);
        list.show();
        System.out.println("=======================================================");
        System.out.println("list链表的有效长度:" + LinkedList.getLength(list.getHead()));
        System.out.println("=======================================================");
        LinkedList.getKNode(list.getHead(),2);//对应什么参数传入什么参数进去
        LinkedList.getKNode(list.getHead(),4);
        System.out.println("=======================================================");
        System.out.println("链表反转之后为:" );
        LinkedList.reverse(list.getHead());
        list.show();
        System.out.println("=======================================================");
        System.out.println("链表反向打印之后为:" );
        list.reversePrint(list.getHead());
    }
}
//链表的增删改查

class LinkedList{
    //创建一个头节点
    private PersonNode head = new PersonNode(0,"","");

   public PersonNode getHead(){
       return head;
   }
    //增加一个节点到链表的尾部
    //1.找到当前链表的最后一个节点
    //2.将节点插入到最后一个节点后
    public void add(PersonNode personNode){
       PersonNode temp = head;
       while(true){
           if(temp.next == null){
               break;
           }
           temp = temp .next;
       }
        temp.next = personNode;//通过参数列表传进来的参数值
    }
    //第二种方法按照num的顺序来插入节点
    public void addByOrder(PersonNode personNode){
        PersonNode temp = head;
        boolean flag = false;
        //遍历找到该节点,找到之后即退出循环做下一步动作;
        while(true){
            //如果这里直接让temp=head.next,会出现temp.num是空;
            if(temp.next == null){
                break;
            }
            if(temp.next.num > personNode.num ){
               break;
            }
            if(temp.next.num == personNode.num){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            System.out.println("要插入的编号为:" + personNode.num + "已经存在,不能插入");
        }else{
            personNode.next = temp.next;
            temp.next = personNode;
        }
    }
    //删除一个节点
    public void delete(int num){
        PersonNode temp = head;
        boolean flag = false;
        while(true){
            if(temp.next == null){
                break;
            }
            if(temp.next.num == num){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
            temp.next = temp.next.next;
        }else{
            System.out.println("编号为" + num + "的人不存在!");
        }
    }
    //根据编号改变节点的属性
    public void update(PersonNode personNode){
        PersonNode temp = head;
        boolean flag = false;
        while(true){
            if(temp.next == null){
                break;
            }
            if(temp.next.num == personNode.num){
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if(flag){
           //更新的程序忘记
           temp.next.name = personNode.name;
           temp.next.nickName = personNode.nickName;
        }else{
            System.out.println("您要更新的成员不存在!");
        }
    }
    //输出链表的有效长度---不包括头长度
    public static int getLength(PersonNode head){
        PersonNode temp = head.next;
        boolean flag = true;
        if(head.next == null){
            return 0;
        }
        int i = 0;
        while (true){
            if(temp == null){
                break;
            }
            i++;
            temp = temp.next;
        }
        return i;
    }
    //找到倒数第k个节点的信息,在这里传入一个index索引
    public static PersonNode getKNode(PersonNode head, int index){
        if(head.next == null){
            System.out.println("链表为空");
            return null;
        }
        PersonNode temp = head;
        int size = getLength(head);
            if(index < 0 || index > size){
                System.out.println("索引值为" + index + "的值不存在!");
                return null;
            }
            for(int i = 0 ; i < size - index; i++){
                temp = temp.next;
            }
        System.out.println(temp);
            return temp;
    }
    //反转链表
    public static void reverse(PersonNode head){
        PersonNode cur = head.next;
        PersonNode newReverseHead = new PersonNode(0,"","");
        PersonNode next = null;
        if(head.next == null || head.next.next == null){
            return ;
        }
        while(cur != null){
            next = cur.next;
            cur.next = newReverseHead.next;
            newReverseHead.next = cur;
            cur = next;//让cur后移 完成遍历
        }
        //缺少一步骤,让头指针相连
        head.next = newReverseHead.next;
    }
    //逆向打印链表中的节点
    //不可以用反转的方式,因为会破坏单项链表的数据结构
    //利用栈先进后出的方式来逆向打印
    public static void reversePrint(PersonNode head){
        if(head. next == null){
            return;
        }
        //创建一个新的栈
        //压栈
        Stack<PersonNode> stack = new Stack<PersonNode> ();
        PersonNode cur = head.next;
        while(cur != null){
            stack.push(cur);
            cur = cur.next;
        }
        //遍历栈,将栈中的节点打印出来
        while(stack.size()>0){
            System.out.println(stack.pop());
        }
    }

    //显示链表
    public void show(){
        if(head.next == null){
            System.out.println("链表为空");
            return;//注意这里仍要返回
        }
        PersonNode temp = head.next;
        while(true){
            if(temp == null){
                break;
            }
            System.out.println(temp);
            temp = temp.next;
        }

    }

}

//定义链表节点的属性
//person后面什么都没有 修饰符+类名称{}
class PersonNode{
    //定义变量时要谨慎使用权限,private仅限于本类中使用
    public String name;
    public String nickName;
    public int num;
    public PersonNode next;
    //一个标准类通常有:系统默认赠送的一个无参构造,自己定义的有参构造,一个getter,setter
    //创建构造器快捷键Alt + insert;
    public PersonNode(int num, String name ,String nickName) {
        this.num = num;
        this.name = name;
        this.nickName = nickName;
    }
    //重写toString 方法,为了清晰显示
    @Override
    public String toString() {
        return"[num =  " + num + ", name = " + name + ", age = " + nickName + " ]";
    }
}


发布了29 篇原创文章 · 获赞 1 · 访问量 1246

猜你喜欢

转载自blog.csdn.net/weixin_42082088/article/details/104071029