双链表(增,删,改)的各种操作

Node类

package com.doubluelinklist.test;

public class Node {

    private int id;  //编号
    private String name;  //姓名
    public Node pre; //前一个结点
    public Node next; //下一个结点
    
    public Node(int id,String name){
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Node getPre() {
        return pre;
    }

    public void setPre(Node pre) {
        this.pre = pre;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
    
    @Override
    public String toString() {
        return "id = " + this.getId() + "\t" + "name = " + this.getName();
    }   
}

DoubleLikeListSample类

package com.doubluelinklist.test;

import java.util.Stack;

public class DoubleLikeListSample {
    
    private int size;    //记录结点个数的变化
    private Node head = new Node(0,"");   //头结点,值为空,表示一个空结点
    
    /*
     * 1.结点的个数
     * 2.获得头结点
     * 3.判断结点是否存在,即加入的结点的编号是否已经存在
     * 4.插入:
     *     1.尾部加入
     *  2.头部加入
     *  3.指定位置插入
     * 5.删除
     *     1.指定位置删除
     *  2.指定编号删除
     *  3.指定姓名删除
     * 6.修改
     *  1.根据编号进行修改
     *  2.根据姓名进行修改
     * 7.根据编号进行排序
     * 8.两个有序双链表进行合并
     * 9.打印
     * 10.从尾到头打印单链表
     * 11.双向链表反转
     * 12.查找单链表中的倒数第k个结点
     */
    
    /*
     * 1.结点的个数
     */
    public int getSize(){
        return size;
    }

    /*
     * 2.获得头结点
     */
    public Node getHead(){
        return head;
    }
    
    /*
     * 3.判断结点是否已经存在
     */
    private boolean ifNodeNumberExists(Node node){
        Node tmp = head.next;
        for (int i = 1; i <= size; i++) {
            if(node.getId() == tmp.getId()){
                System.out.println("结点已经存在!!!");
                return true;
            }
            tmp = tmp.next;
        }
        return false;
    }
    
    /*
     * 4.1尾部加入
     */
    public void add(Node node){
        
        Node tmp = head;
        
        //判断结点是否存在
        if(ifNodeNumberExists(node)){
            return;
        }
        
        if(head.next == null){
            head.next = node;
            node.pre = head;
        }else{
            for (int i = 1; i <= size; i++) {
                tmp = tmp.next;
            }
            tmp.next = node;
            node.pre = tmp;
        }
        node.next = null;
        size++;
    }

    /*
     * 4.2头部加入
     */
    public void add2(Node node){
        //判断结点是否已经存在
        if(ifNodeNumberExists(node)){
            return;
        }
        
        if(head.next == null){
            head.next = node;
            node.pre = head;
            node.next = null;
        }else{
            node.next = head.next;
            head.next.pre = node;
            head.next = node;
            node.pre = head;
        }
        size++;
    }

    
    /*
     * 4.3指定位置插入
     */
    public void add3(int index,Node node){
        
        Node tmp = head;
        
        //判断结点是否存在
        if(ifNodeNumberExists(node)){
            return;
        }
        
        //判断指定的位置是否正确
        if(index < 1 || index > size + 1){  //设置为 > size + 1,表示可以在结尾加入
            System.out.println("插入的位置不正确!!!");
            return;
        }
        //得到指定位置的前一个结点
        for (int i = 1; i < index; i++) {
            tmp = tmp.next;
        }
        
        if(tmp.next != null){
            node.next = tmp.next;
            tmp.next.pre = node;
            tmp.next = node;
            node.pre = tmp;
        }else{
            //相当于在尾部加入了或者当只有头结点的时候
            node.pre = tmp;
            tmp.next = node;
            node.next = null;
        }
        size++;
    }
    
    /*
     * 5.1指定位置删除
     */
    public void indexDetleNode(int index){
        
        Node tmp = head;
        
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        //判断删除的位置是否正确
        if(index < 1 || index > size){
            System.out.println("删除的位置不正确!!!");
            return;
        }
        
        for (int i = 1; i <= index; i++) {
            tmp = tmp.next;
        }
        if(tmp.next != null){
            tmp.next.pre = tmp.pre;
            tmp.pre.next = tmp.next;
        }else{
            //相当于删除最后一个结点
            tmp.pre.next = null;
        }
        size--;
    }
    
    /*
     * 5.2指定编号删除
     */
    public void idDetleNode(int id){
        Node tmp = head;
        
        //判断链表是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            if(tmp.getId() == id){
                System.out.println("删除成功!!!");
                break;
            }
        }
        if(tmp.next != null){
            tmp.pre.next = tmp.next;
            tmp.next.pre = tmp.pre;
        }else{
            //相当于删除最后一个结点
            tmp.pre.next = null;
        }
        size--;
    }
    
    /*
     * 5.3指定姓名删除
     */
    public void nameDetleNode(String name){
        Node tmp = head;
        
        //判断指定姓名是否存在
        boolean ifNameExists = false;
        
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        
        //获得总结点数
        int len = size;
        for (int i = 1; i <= len; i++) {
            tmp = tmp.next;
            if(tmp.getName().equals(name)){
                if(tmp.next !=null){
                    tmp.next.pre = tmp.pre;
                    tmp.pre.next = tmp.next;
                }else {
                    tmp.pre.next = null;
                }
                ifNameExists = true;
                size--;
            }
        }
        if(!ifNameExists){
            System.out.println("要删除的姓名不存在!!!");
        }    
    }
    
    /*
     * 6.1根据编号进行修改
     */
    public void idUpdateNode(int id,Node node){
        
        Node tmp = head;
        boolean ifIdExists = false;
        
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            if(tmp.getId() == id){
                //判断tmp是否为最后一个结点
                if(tmp.next != null){
                    node.next = tmp.next;
                    tmp.next.pre = node;
                }
                tmp.pre.next = node;
                node.pre = tmp.pre;
                ifIdExists = true;
                break;
            }
        }
        
        if(!ifIdExists){
            System.out.println("指定的编号不存在!!!");
        }
    }
    
    /*
     * 6.2根据姓名进行修改
     */
    public void nameUpdateNode(String srcName,String desName){
        
        Node tmp = head;
        boolean ifNameExists = false;
        
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            if(tmp.getName().equals(srcName)){
                tmp.setName(desName);
                ifNameExists = true;
            }
        }
        if(!ifNameExists){
            System.out.println("姓名不存在!!!");
        }
        
    }
    
    /*
     * 7.根据编号进行排序
     */
    private void sortDoubleList(){
        Node newHead = head.next;
        for(int i = 0; i< size - 1; i++){
            //前一个元素指针
            Node preNode  = null;
            
            //当前处理的元素
            Node curNode = newHead;

            for(int j = 0; j < size - i - 1;j++){
                if(curNode.getId() > curNode.next.getId()){
                    //交换两个结点的引用,此时curNode的指针交换后会前移,只需要更新preNode指向即可
                    //缓存下下个结点
                    Node tmpNode = curNode.next.next;
                    curNode.next.next = curNode;
                    curNode.pre = curNode.next;
                
                    //前驱结点指向nextNode
                    if(preNode != null){
                        preNode.next = curNode.next;
                        curNode.next.pre = preNode;
                    }else{
                        //没有前驱结点证明结点为头结点,更新头结点
                        newHead = curNode.next;
                    }

                    //因为需要把preNode指向原来的下个结点,所以此处复制preNode,preNode后移
                    preNode = curNode.next;

                    //curNode指向下下个结点
                    curNode.next = tmpNode;

                //更新preNode & curNode指针
                }else{
                    preNode = curNode;
                    curNode = curNode.next;
                }
            }
        }    
         head.next = newHead;
    }
    
    /*
     * 8.两个有序单链表合并,并且有序
     */
    public static void combinNodeToNode(DoubleLikeListSample srcDoubleLink,DoubleLikeListSample desDoubleLink){
        Node srcHeadNode = srcDoubleLink.getHead();
        Node desHeadNode = desDoubleLink.getHead();
        
        for (int i = 1; i <= srcDoubleLink.getSize(); i++) {
            srcHeadNode = srcHeadNode.next;
        }
        srcHeadNode.next = desHeadNode.next;

        //排序
        srcDoubleLink.size = srcDoubleLink.getSize() + desDoubleLink.getSize();
        srcDoubleLink.sortDoubleList();
    }
    
    
    /*
     * 9.打印
     */
    public void print(){
        Node tmp = head;
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            System.out.println(tmp.toString());
        }
    }
    
    /*
     * 10.从尾到头打印单链表
     */
    public void endToStartPrint(){
        
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表");
            return;
        }
        
        Node tmp = head;
        //使用栈---先进后出
        Stack<Node> stack = new Stack<>();
        for (int i = 1; i <= size; i++) {
            tmp = tmp.next;
            stack.push(tmp);
        }
        
        while (stack.size() > 0) {
            System.out.println(stack.pop().toString());    
        }
    }

    /*
     * 11.双向链表反转
     * 思想:总是以当前的结点为基准,与头结点进行链接
     */
    public void reverseDoubleList(){
        
        Node cur = head.next;            //当前结点
        Node next = null;                //下一个结点
        Node tmpHead = new Node(0,"");              //前一个指针
        
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return;
        }
        
        while (cur != null) {
            next = cur.next;
            cur.next = tmpHead.next;
            if(tmpHead.next != null){
                tmpHead.next.pre = cur;
            }
            cur.pre = tmpHead;
            tmpHead.next = cur;
            cur = next;
        }
        head = tmpHead;
    }
    
    /*
     * 12.查找单链表中的倒数第k个结点
     * 思路:就是顺查找第size -k + 1个结点
     */
    public Node findReciprocalKNode(int k){
        
        Node node = head;
        //判断k是否存在
        if(k < 1 || k > size){
            System.out.println("k输入不正确!!!");
            return null;
        }
        //判断是否为空链表
        if(head.next == null){
            System.out.println("空链表!!!");
            return null;
        }
        
        for (int i = 1; i <= size - k + 1; i++) {
            node = node.next;
        }
        return node;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值