数据结构(三)--链表

数据结构(三)–链表

介绍

链表又分:

  • 单链表
  • 双链表

单链表

  • 头节点不存储数据,所有操作临时引用指向head;
  • 删除/插入节点:先判断当前节点是否满足删除或插入条件,然后判断是否可以移动,最后移动(反复)
  • 遍历节点:判断是否可以移动,移动,打印
  • 打印某一节点:判断是否可以移动,移动,判断当前节点是否可以打印(反复)

代码实现

先实现节点

根据需要可以将数据域data的类型改为泛型**< T >**

public class NodeT<T>{
    private T data;
    private Node next;
    public NodeT(){}
    public NodeT(T data,Node next){
        this.data = data;
        this.next = next;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "NodeT{" +
                "data='" + data + '\''+"}";
    }
}

实现单链表

public class LinelistT<T> {
    private NodeT head ;
    public LinelistT(){
        head = new NodeT<T>(null,null);
    }

    //打印所有节点
    public  void printNodes(){
        NodeT tepm = head;
        while (true){
            if (tepm.getNext()==null) break;
            tepm = tepm.getNext();
            System.out.println(tepm);
        }
    }

    //尾部添加数据
    public void addNode(T data){
        NodeT<T> node = new NodeT<T>(data,null);
        NodeT<T> temp = head;
        while (true){
            if (temp.getNext()==null){
                temp.setNext(node);
                break;
            }
            temp = temp.getNext();
        }
    }

    //插入数据
    public void insertNode(int index,T data){
        //判断越界
        if (index<=0) throw new RuntimeException("越界");

        NodeT<T> node = new NodeT<T>(data,null);
        NodeT temp = head;
        int i=0;
        while (true){
            //添加节点
            if (i==index-1){
                node.setNext(temp.getNext());
                temp.setNext(node);
                break;
            }

            //判断越界
            if (temp.getNext()==null) throw new RuntimeException("越界!!!");

            //移动
            temp = temp.getNext();
            i++;
        }
    }

    //删除节点
    public NodeT deleteNode(int index) {
        //判断越界
        if (index <=0 )
            new RuntimeException("越界!!!");



        NodeT temp = head;
        int i = 0;
        while (true) {
            //删除节点
            if (i == index - 1 && temp.getNext() != null) {
                NodeT temp2 = temp.getNext();
                temp.setNext(temp2.getNext());
                temp2.setNext(null);
                return temp2;

            }

            //判断越界
            if (temp.getNext()==null)
                throw new RuntimeException("越界!!!");

            //移动
            temp = temp.getNext();
            i++;
        }


    }

    //打印某一节点
    public void printNode(int index){
        //判断越界
        if (index<=0) new RuntimeException("越界!!!");

        NodeT temp = head;
        int i=0;
        while (true){
            //判断越界
            if (temp.getNext()==null) {
                new RuntimeException("越界!!!");
            }

            //移动
            i++;
            temp = temp.getNext();

            //打印
            if (i==index){
                System.out.println(temp);
                break;
            }

        }
    }


}

主函数

public static void main(String[] args) {
        LinelistT<String> line = new LinelistT<String>();
        line.addNode("节点一");
        line.addNode("节点二");
        line.addNode("节点三");
        line.printNodes();
        System.out.println("-----------------------------");
        line.deleteNode(2);
        line.printNodes();
        System.out.println("-----------------------------");
        line.insertNode(2,"插入节点");
        line.printNodes();
        System.out.println("-----------------------------");
    }

结果

NodeT{data='节点一'}
NodeT{data='节点二'}
NodeT{data='节点三'}
-----------------------------
NodeT{data='节点一'}
NodeT{data='节点三'}
-----------------------------
NodeT{data='节点一'}
NodeT{data='插入节点'}
NodeT{data='节点三'}
-----------------------------

翻转链表

在单链表中添加以下方法即可,思路如下:

  • 创建一个新的临时链表reverseHead
  • 取出原链表的第一个有效节点
  • 将原链表的第一个有效节点插入到临时链表的第一个有效位置(head后面)
  • 将原链表Heda的next指向reverseHead的next即可
public void reverse(){
        //创建新链表
        LinelistT reverseHead = new LinelistT<T>();
        NodeT temp = head;
        while (true){
            try {
                NodeT node = this.deleteNode(1);
                reverseHead.insertNode(1,node.getData());
            }catch (RuntimeException e) {
                break;
            }
        }
        head.setNext(reverseHead.head.getNext());
    }

取出倒数第n个有效节点

获取有效节点个数

先写一个统计有效节点个数的函数,当然如果你想优化的话,完全可以在链表类中添加一个私有属性Num,用来记录个数,因为这里没写,所以就多写一个函数去遍历。

public int getNodeNum(){
        NodeT temp = head;
        int num = 0;
        while (true){
            //判断是否到尾部
            if (temp.getNext() == null) return num;
            temp = temp.getNext();
            num++;
        }
    }

获取倒数有效节点

public NodeT<T> getNodeByreverse(int reverseIndex){
        int num =  this.getNodeNum();
        if (reverseIndex>num || reverseIndex<=0) 
        	throw new RuntimeException("越界");
        NodeT<T> temp = head;
        int i = 0;
        while (true){
            if (i==num-reverseIndex+1) break;

            temp = temp.getNext();
            i++;
        }
        return temp;
    }
posted @   鸭梨的药丸哥  阅读(6)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示