Java链表的实现

在Java中没有struct来定义结构体,我们可以封装一个类来当结构体(快捷键alt+shift+S)

public class LinkNode {
    public int data;//数据域
    public LinkNode next;//指向下一个节点(指针域)

    public int getData() {
        return data;
    }
    public void setData(int data) {
        this.data = data;
    }
    public LinkNode getNext() {
        return next;
    }
    public void setNext(LinkNode next) {
        this.next = next;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + data;
        result = prime * result + ((next == null) ? 0 : next.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        LinkNode other = (LinkNode) obj;
        if (data != other.data)
            return false;
        if (next == null) {
            if (other.next != null)
                return false;
        } else if (!next.equals(other.next))
            return false;
        return true;
    }
    public LinkNode(int data, LinkNode next) {
        super();
        this.data = data;
        this.next = next;
    }
    public LinkNode() {
        super();
    }
    @Override
    public String toString() {
        return "[data=" + data + ", next->\n" + next + "]";
    }
}

构造一个空的链表,也就是头结点,并把头结点的数据域赋为0,指针域赋为null

private static void initLnode(LinkNode L) {
        L.setData(0);
        L.setNext(null);
    }

链表的遍历

private static int traverse(LinkNode L) {
        LinkNode p = L;
        int count = 0;//计数器     计算节点的个数
        while (p.next != null) {
            p = p.next;
            count++;
        }
        return count;
    }

在第i个位置插入一节点

//L是传递过来的链表   count是传递过来的节点的个数
private static void insertLnode(LinkNode L, int count) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("please enter the data:");
        int data = scanner.nextInt();
        System.out.println("please enter the position:");
        int pos = scanner.nextInt();
        //待插入的位置最大就是结点个数加一,且不能小于零
        if (pos > count + 1 || pos <= 0) {
            System.out.println("Illegal location!");
        } else {
            LinkNode p = L;// 把头结点赋给p
            LinkNode q = new LinkNode();//待插入的节点
            int i = 0;// 循环变量
            //要在第i位置插入一个元素,要找到第i-1个元素,然后在它后面插入一个节点
            while (p.next != null && i < pos - 1) {
                p = p.next;
                i++;
            }
            //在第i个位置插入节点
            if (p.next == null) {
                 q.setData(data);
                 q.setNext(null);
                 p.setNext(q);
            } else {
                 q.setData(data);
                 q.setNext(p.next);
                 p.setNext(q);
            }

            System.out.println("Insert success.");
        }

    }

删除第i个节点

private static void deleteLnode(LinkNode l, int pos) {
        int count = traverse(l);
        LinkNode p = l;
        LinkNode r = new LinkNode();//记录p的上一个节点
        //确保pos在合法范围内
        if (pos <= 0 || pos > count) {
            System.out.println("Illegal location!");
        } else {
            //向后移动pos个位置,找到第pos个节点
            for (int j = 0; j < pos; j++) {
                r = p;
                p = p.next;
            }
            if (p.next == null) {//如果第pos个节点是最后一个节点
                r.setNext(null);
            } else {
                r.setNext(p.next);
            }
        }
    }

两个有序的链表合并后仍然有序

private static LinkNode merge(LinkNode L, LinkNode L1) {
        LinkNode Lm = new LinkNode();//合并后的链表
        LinkNode p = L;
        LinkNode q = L1;

        initLnode(Lm);
        LinkNode r = Lm;

        p = p.next;//从头结点向后移动一位,指向第一个节点
        q = q.next;//从头结点向后移动一位,指向第一个节点

        //L:2 5 7 9 10 11
        //L1:3 5 6 8
        //L有6个节点  L1有4个节点  先把前4个节点合并
        while (p != null && q != null) {
            if (p.data > q.data) {
                LinkNode s = new LinkNode();
                s.setData(q.data);
                s.setNext(null);
                r.setNext(s);
                q = q.next;//L向后移动一位
                r = r.next;//Lm向后移动一位
            } else if (p.data < q.data) {
                LinkNode s = new LinkNode();
                s.setData(p.data);
                s.setNext(null);
                r.setNext(s);
                p = p.next;
                r = r.next;
            } else {// 两数相等  同一个数据要在Lm上连接两次
                LinkNode s = new LinkNode();//第一次连接
                s.setData(q.data);
                s.setNext(null);
                r.setNext(s);
                r = r.next;

                LinkNode t = new LinkNode();//第二次连接
                t.setData(q.data);
                t.setNext(null);
                r.setNext(t);
                r = r.next;

                q = q.next;
                p = p.next;
            }
        }
        //L:2 5 7 9 10 11
        //L1:3 5 6 8
        //合并后Lm:2 3 5 5 6 7 8 9   L还有两个节点,把剩下的两个节点直接合并到Lm后面
        if (p != null && q == null) {//L链表还有剩余节点
            while (p != null) {
                LinkNode s = new LinkNode();
                s.setData(p.data);
                s.setNext(null);
                r.setNext(s);
                r = r.next;
                p = p.next;
            }
        }
        if (p == null && q != null) {//L1链表还有剩余节点
            while (q != null) {
                LinkNode s = new LinkNode();
                s.setData(q.data);
                s.setNext(null);
                r.setNext(s);
                r = r.next;
                q = q.next;
            }
        }
        return Lm;
    }

测试方法

public class LNodeTest {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int m = 0;

        System.out.println("1.init Lnode");
        System.out.println("2.insert Lnode");
        System.out.println("3.delete Lnode");
        System.out.println("4.traverse");
        System.out.println("5.Linked list merging");
        System.out.println("6.output Lnode");

        LinkNode L = new LinkNode();

        while (true) {
            System.out.println("please enter the opration code:");
            int n = sc.nextInt();
            switch (n) {
            case 1:
                initLnode(L);
                System.out.println(L);
                m++;
                break;
            case 2:
                if (m == 0) {
                    System.out.println("please initialize first.");
                } else {
                    int count = traverse(L);
                    System.out.println("count = " + count);
                    insertLnode(L, count);
                }
                break;
            case 3:
                if (m == 0) {
                    System.out.println("please initialize first.");
                } else {
                    System.out.println("please enter the position:");
                    int pos = sc.nextInt();
                    deleteLnode(L, pos);
                }
                break;
            case 4:
                if (m == 0) {
                    System.out.println("please initialize first.");
                } else {
                    int c = traverse(L);
                    System.out.println("count = " + c);
                }
                break;
            case 5:
                if (m == 0) {
                    System.out.println("please initialize first.");
                } else {
                    LinkNode L1 = new LinkNode();
                    initLnode(L1);
                    while (true) {
                        int count = traverse(L1);
                        System.out
                                .println("Do you want to continue input elements?(Y|N)");
                        char c = sc.next().charAt(0);
                        if (c == 'Y' || c == 'y') {
                            insertLnode(L1, count);
                        } else if (c == 'N' || c == 'n') {
                            break;
                        }
                    }

                    LinkNode L2 = merge(L, L1);
                    System.out.println("combine");
                    System.out.println(L2);//调用LinkNode封装类中的toString方法
                }
                break;
            case 6:
                if (m == 0) {
                    System.out.println("please initialize first.");
                } else {
                    System.out.println(L);//调用LinkNode封装类中的toString方法
                }
                break;
            default:
                System.out.println("Opcode error.");
                break;
            }
        }

    }

以L:2 5 7 9 10 11,L1:3 5 6 8为例,运行程序
运行结果:
这里写图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值