Java数据结构之链表——头插法逆置单链表

单链表的就地逆置是指辅助空间O(1)的逆置方法,使用头插法。

定义单链表的基本操作

package Link;

class Node{ // 定义单链表借点类

    public int value; // 该结点所保存的值
    public Node next; // da该结点下一个结点指针

    public Node(int data){

        value = data;
        next = null;

    }

    public Node(){

        next =null;

    }
}

// 定义单链表基本操作
public class LinkList{

    Node head = null; // 头结点为空

    // 尾插法创建单链表
    public Node TailCreateLinkList(int[] arr){

        int len = arr.length;

        if(len == 0){

            System.out.println("创建空链表");

            return head;

        }

        head = new Node(arr[0]);

        Node pre = head;

        for(int i = 1;i < len;i++){

            Node node = new Node(arr[i]);

            pre.next = node;

            pre = node;

        }

        return head;

    }

    // 头插法创建单链表
    public Node HeadCreateLinkList(int[] arr){

        int len = arr.length;

        if(len == 0){

            System.out.println("创建空链表");

            return head;

        }

        for(int i = 0;i < len;i++){

            Node node = new Node(arr[i]);

            node.next = head; // 在链表头部插入结点

            head = node; // 每一个新插入的结点都成为新的头结点

        }

        return head;

    }

    // 头插法向链表表头插入一个值
    public Node HeadInsertLinkList(int a,LinkList linkList){

        if(linkList.head == null){

            System.out.println("创建空链表");

            head = new Node(a);

            return head;

        }

        Node node = new Node(a);

        node.next = head; // 在链表头部插入结点

        head = node; // 每一个新插入的结点都成为新的头结点

        return head;

    }

    public void PrintLinkList(Node head){

        if(head == null){

            System.out.println("链表为空!");
            return;
        }

        Node pre = head;

        while (pre != null){

            System.out.print(pre.value + "\t");
            pre = pre.next;
        }

    }

    public int LinkLength(Node head){

        int len = 0;

        if(head== null){

            System.out.println("链表为空");
            return 0;
        }

        while(head != null){

            len++;
            head = head.next;
        }

        return len;

    }

    public Node LinkListInverse(Node head){


        if(head == null){

            System.out.println("空链表!");
            return head;
        }

        //注释掉的这段第一个结点处理的复杂了
//        Node p = head.next;
//        Node q = p.next;
//
//        if(q == null){
//
//            System.out.println("链表只有一个值,不用翻转!");
//            return head;
//        }
//
//        while(q != null){
//
//           p.next = q.next;
//           q.next = head.next;
//           head.next = q;
//
//           q = p.next;
//        }
//
//        //因为刚才利用原来链表的第一个结点之前插入结点,没做处理该结点,所以最后处理一下第一个结点
//        q = head.next;
//        p.next = head;
//        head = q;
//        p.next.next =null;

        Node p = head;
        Node q = p.next;

        if(q == null){

            System.out.println("链表只有一个值,不用翻转!");
            return head;
        }

        while(q != null){

            p.next = q.next;
            q.next = head;
            head = q;

            q = p.next;

//            PrintLinkList(head); // 打印链表
//            System.out.println();
        }

        return head;
    }

    public Node DeleteElements(int a,Node head){

        if(head == null){

            System.out.println("空链表!");

            return head;
        }

        while(head.value == a){ // 头结点的值等于待删除的值,单独处理

            head = head.next;
            if(head == null){

                return head;

            }
        }

        Node pre = head; // 指向当前结点的前一结点
        Node q = pre.next;

        while(q != null){

            if(q.value == a){  // 当前结点值恰好为待删除的值,pre指针不用移动,因为删除一个q结点之后会带来一个新的q结点

                pre.next = q.next;

                q = pre.next;

            }
            else{ // 当前值不等于待删除值,当前结点指针后移
                pre = pre.next;
                q = pre.next;
            }

        }

        return head;
    }
}

主函数

package Link;

public class LinkListInverse {

    public static void main(String[] args) {

        int [] arr = new int[] {3,3,3,1,3,4,3,3,3,7,3,0,8,2,3,3,3};

//        int [] arr = new int[] {3,3,3,3,3,3,3,3,3,3,3};

        LinkList linkList = new LinkList();

        System.out.println();
        System.out.println("--------尾插法创建单链表--------");
        System.out.println();

        Node tail = linkList.TailCreateLinkList(arr); // 尾插法创建新结点,tail是头结点指针
        linkList.PrintLinkList(tail);

        System.out.println();
//        LinkList linkListHead = new LinkList();
//        Node head = linkListHead.HeadCreateLinkList(arr); // 头插法创建新结点
//        linkListHead.PrintLinkList(head);

//        System.out.println(linkList.LinkLength(tail)); // 链表长度

        System.out.println("--------单链表反转--------");
        tail = linkList.LinkListInverse(tail); // 表头改变了,要赋值给一个变量,不然就错了

        linkList.PrintLinkList(tail);
//        linkList.PrintLinkList(tail); // 为什么链表逆置之后不赋值给tail,tail只有一个值了?

        System.out.println();
        System.out.println("--------删除所有给定值--------");
        System.out.println();

        tail = linkList.DeleteElements(3,tail);

        linkList.PrintLinkList(tail);


    }
}

输出

--------尾插法创建单链表--------

3	3	3	1	3	4	3	3	3	7	3	0	8	2	3	3	3	
--------单链表反转--------
3	3	3	2	8	0	3	7	3	3	3	4	3	1	3	3	3	
--------删除所有给定值--------

2	8	0	7	4	1	
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值