Java 用链表实现线性表(LinkList)增、删、查、遍历等

Java 用单链表实现线性表(增、删、改、查、遍历等)

用数组和单链表实现线性表的区别:

数组更好上手,遍历范围更好控制,但是添加新的信息都要重新创建一个新数组,比较麻烦。具体可以参考这个链接:
link.
单链表比较难上手,特别是遍历链表和删除节点比较难搞,但是添加新的信息比较简单,找空的节点插入就好。单链表可以参考这个链接:
link

Mylinklist的定义、Node类定义和构造函数

public class MyLinkList <E>{
    private static final int defaultLength = 1;
    private int length=1;   //容量   容量=下标+1
    private MyNode<E> head;  //头指针 空的

    public class Node{
        private int size ;     //下标
        private E value;
        private Node next;

        public Node(){
            size =0;
            value = null;
            next =null;
        }
        public Node(E e, int newsize){
            value = e;
            size  =newsize;
            next  =null;
        }
        public Node(E e){
            value =e;
            next =null;
        }
        public Node(int newsize){
            value = null;
            size  =newsize;
            next  =null;
        }
        public void  addNode(Node node){
            next =node;
            length++;

        }
        public void  addValue(E e){
            this.value =e;
        }

    }

Mylinklist构造函数

/**
     * 默认构造函数
     */
public  MyLinkList(){
       length =1;
       head =new MyNode<E>();
    }

/**
     * 用数字构造空线性表
     * @param number
     */
    public  MyLinkList(int number){

        length =number+1;
        head =new MyNode<E>();
        MyNode<E> node =head;
        int size =1;
        for (int i=0; i<number;i++){

            MyNode<E> newnode =new MyNode<E>(size);
            node.addNode(newnode);


            node =node.next;
            size++;
        }
    }//根据传入数据 初始化


/**
     * 根据传入链表构造
     * @param newNode
     */
    public MyLinkList(MyNode<E> newNode){
        head =new MyNode<E>();
        MyNode<E> node =head;
        head.next =newNode;
        this.sortSize();
    }

增:添加新的信息(E是泛型,根据外部传入数据类型变化)

    /**
     *在空的地方插入数据
     * @param data
     */
    public void addOneData(E data){
        MyNode<E> node =head; //从头节点之后插入
        while (true){

            if (node.next ==null){

                int newszie  = node.size+1; //这个怎么可以访问呢
                MyNode<E> newNode = new MyNode<E>(data, newszie);
                node.addNode(newNode);
                length++;
                //System.out.println("添加了新的数据"+newNode.value);
                break;
            }//如果是最后一个,添加新的节点

            if(node.value ==null&&node.size!=0){
                node.value =data;
                break;
            }//确认不是头节点
            node =node.next;
        }
    }

/**
     * 添加新的链表到尾部
     * @param newNode
     */
    public void add (MyNode<E> newNode){
        if (this.head ==null){
            head =new MyNode<E>();
            //head.print();
        }
        MyNode<E> node =head;
        while (true){
            if (node.next ==null){
                System.out.println("最后一位是"+node.size);
                node.addNode(newNode);
                node.print();
                break;
            }//最后一个
            //System.out.println("下标1"+node.size);
            node=node.next;
        }
        this.sortSize();
    }

删:根据下标、元素、链表删除数据


    /**
     * 根据下标删除元素
     * @param number
     */
    public void remove(int number){
        if (number >(length-1)){
            System.err.println("输入超出范围");
        }
        MyNode<E> node =head;
        while (true){
            if (node.next ==null){
                break;
            }//最后一个节点
            if (node.next.size ==number){
                System.out.println("要删除的数字"+number +"  下标"+node.next.value);
                MyNode<E> newnode = node.next.next;
                if(newnode ==null){
                    node.next =null;
                    length--;
                    break;
                }else{
                    newnode.size = node.next.size;
                    node.next =newnode;
                    length--;
                }
            }//中间节点和倒数第二个节点(),包括删除最后一个节点
            node =node.next;
        }
        this.sortSize();
    }


    /**
     * 根据元素获取多个下标,然后移位
     * @param e
     */
    public void remove(E e){
        MyNode<E> node =head;
        while (true){
            if (node.next != null){
                if (node.next.value ==e){
                    MyNode<E> newnode = node.next.next;
                    System.out.println("要删除的数字"+e +"  下标"+node.next.size);
                    newnode.size = node.next.size;
                    node.next =newnode;
                    length--;
                }//中间节点和倒数第二个节点(),包括删除最后一个节点
            }//不是最后一个节点
            if (node.next ==null){

                break;
            }//最后一个节点
            node =node.next;
        }
        this.sortSize();
    }

/**
     * 根据链表,删除所有重复数据
     */
    public void remove(MyNode<E> myNode){
        //默认不是空的链表
        MyNode<E> headNode =this.head;
        while (true){
            while (true){
                if (headNode.next.value == myNode.value ){
                    MyNode<E> node1 =headNode.next.next;
                    headNode.next =node1;
                    break;
                }
                if (headNode.next ==null){
                    break;
                }
                 headNode =headNode.next;
            }// headnode循环
            if (myNode.next ==null){
                break;
            }
            myNode= myNode.next;
        }
        this.sortSize();
    }

查:根据下标得到元素,根据元素获取多个下标

//根据下标获取元素
public E get(int number){
        if (number >(length-1)){
            System.err.println("输入超出范围");
        }
        MyNode<E> node =head;
        while (true){

            if(node.size ==number){

                return node.value;
            }
            if (node.next ==null){
                System.out.println("下标对应的元素为空");
                break;
            }//最后一个,
            node =node.next;
        }
        return null;
    }

/**
     *根据元素获取多个下标
     * @param element
     * @return int[]
     */
    public int[] get(E element){
        MyNode<E> node =head;
        int number=0;
        while (true){
            if (node.next ==null){
                if(node.value==element){
                    System.out.println("元素的位子"+node.size);
                    number++;
                }
                if (number ==0){
                    System.err.println("没有这个元素");
                    return null;
                }
                break;
            }//最后一个
            if(node.value ==element){
                System.out.println("元素的位子"+node.size);
                number++;
            }
            node =node.next;
        }

        //已经找到了对应的元素
        System.out.println();
        System.out.println("个数"+number);
        int[] numbers =new  int[number];

        node =head;
        int i=0;
        while (true){
            if (node.next ==null){
                if(node.value==element){
                    numbers[i] =node.size;
                }
                break;
            }//最后一个
            if(node.value== element){
                numbers[i] =node.size;
                i++;
            }
            node =node.next;
        }
        return numbers;
    }

打印:遍历线性表

/**
     *打印出所有的元素
     * @param
     * @return
     */
    public void print(){
        MyNode<E> node =head;
        System.out.println("下标"+node.size+" 头节点,数据是空的");
        node=node.next;

        while (true){
            if (node.next ==null){
                System.out.println("下标"+node.size+" 数据"+node.value);
                break;
            }//找到最后一个
                System.out.println("下标"+node.size+" 数据"+node.value);
            node =node.next;
        }
    }

排序:根据前后顺序整理下标(从头节点到尾节点)

因为删除节点之后,剩下节点的下标会发生变化,所以需要重新排序

    /**
     * 用于删除节点之后重新排序
     */
    public void sortSize(){
            MyNode<E> node =head;
            int newsize =0;
            while (true){
                if (node.size!=newsize){
                    node.size =newsize;
                }
                node=node.next;
                newsize++;
                if (node.next ==null){
                    node.size =newsize;
                    break;
                }//最后一个
            }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值