Java链表基础

一、单向链表的基本介绍

数组和链表都是最基础的线性数据结构,可以用来实现栈,队列等非线性,有特定应用场景的数据结构,我们发现数组作为数据存储结构有很很多缺陷,在无序数组中搜索效率低,在有序数组中插入效率又很低,无论哪种情况删除操作效率都很低;而且数组一旦创建,大小不可更改。

  • 相邻元素之间通过指针链接
  • 最后一个元素的后继指针为NULL
  • 在程序执行过程中,链表的长度可以增加或缩小
  • 链表的空间能够按需分配
  • 没有内存空间的浪费
    如下图所示,在数据结构中,a1里面的指针存储着a2的地址,这样一个链接一个,就形成了链表。
    ![链表](https://img-blog.csdnimg.cn/20201114155214739.png#pic_center
    下图描述了单向链表存储情况。存储是分散的,每一个节点只要记录下一节点,就把所有数据串了起来,形成了一个单向链表。
    在这里插入图片描述
    节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的。也就是说,节点拥有两个成员:储存的对象、对下一个节点的引用。下面图是具体的说明:
    在这里插入图片描述
    链表的优点:
  • 插入和删除时不需移动其他元素, 只需改变指针,效率高。
  • 链表各个节点在内存中空间不要求连续,空间利用率高。
  • 大小没有固定,拓展很灵活。
    链表的缺点
  • 查找数据时效率低,因为不具有随机访问性。

二、单向链表基础功能的实现

1.创建头结点


    class Node {
        Node next = null;// 节点的引用,指向下一个节点
        int date;//链表中的节点,data代表节点的值,next是指向下一个节点的引用
        public Node(int n){
            this.date=n;
        }

    }

初始化头结点

    Node head = null;

2.向链表中插入数据

    public void addNode(int d) {
        Node newNode = new Node(d);  //实例化一个节点
        if (head == null) {
            head = newNode;
            return;
        }
        Node tmp = head;
        while (tmp.next != null) {
            tmp = tmp.next;
        }
        tmp.next = newNode;
    }

3.计算链表的长度

    public int length() {
        int len = 0;
        Node tmp = head;
        while (tmp != null) {
            len++;
            tmp = tmp.next;
        }
        return len;
    }

3.删除重复节点

    public void deleteDuplecate() {
        Node p = head;
        while (p != null) {
            Node q = p;
            while (q.next != null) {
                if (p.date == q.next.date) {
                    q.next = q.next.next;
                } else
                    q = q.next;
            }
            p = p.next;
        }
    }

4.删除指定值的节点

    public void delete(int n) {
    
        while (head.date==n&&head.next!=null)//处理链表头部值连续相同的情况
        {
            head=head.next;
        }
         if(head.date==n)
        return null;
        Node p=head;


        while (p.next != null) {
            if (p.next.date == n) {
                p.next = p.next.next;
            } else
                p = p.next;
        }
    }

5.打印链表

    public void printlist() {
        Node L = head;
        while (L != null) {
            System.out.println(L.date);
            L = L.next;
        }
    }

6.链表反转

    public void reversaL(){
        Node ReversaHead =head;
        Node pNode=head;
        Node pRive=null;
        while (pNode!=null)
        {
            Node pNext=pNode.next;
            if(pNext==null)
            {
                ReversaHead=pNode;
            }
            pNode.next=pRive;
            pRive=pNode;
            pNode=pNext;
        }
        this.head=ReversaHead;
        //return this.head;
    }

7.查找单链表的中间节点

public Node SearchMid(Node head) {
        Node p = this.head, q = this.head;
        while (p != null && p.next != null && p.next.next != null) {
            p = p.next.next;
            q = q.next;
        }
        System.out.println("Mid:" + q.data);
        return q;
    }

8.查找倒数第k个元素

采用两个指针P1,P2,P1先前移K步,然后P1、P2同时移动,当p1移动到尾部时,P2所指位置的元素即倒数第k个元素 。

public Node findElem(Node head, int k) {
        if (k < 1 || k > this.length()) {
            return null;
        }
        Node p1 = head;
        Node p2 = head;
        for (int i = 0; i < k; i++)// 前移k步
            p1 = p1.next;
        while (p1 != null) {
            p1 = p1.next;
            p2 = p2.next;
        }
        return p2;
    }

9.对链表进行排序

public Node orderList() {
        Node nextNode = null;
        int tmp = 0;
        Node curNode = head;
        while (curNode.next != null) {
            nextNode = curNode.next;
            while (nextNode != null) {
                if (curNode.data > nextNode.data) {
                    tmp = curNode.data;
                    curNode.data = nextNode.data;
                    nextNode.data = tmp;
                }
                nextNode = nextNode.next;
            }
            curNode = curNode.next;
        }
        return head;
    }

链表功能引用

在主函数中引用

public class LinkedList {
    public static void main(String[] args) {
        Listdemo list=new Listdemo();
        LinkedList<Integer>
        Scanner sc=new Scanner(System.in);
        int sum=sc.nextInt();
        for (int i=0;i<sum;i++)
        {
            int s=sc.nextInt();
            list.addNode(s);
        }
        System.out.println("length="+list.length());
        //list.printlist();
        //list.deleteDuplecate();
        //list.delete(15);
        //System.out.println("length="+list.length());
        //list.delete(5);
        //list.printlist();
        list.reversaL();
        list.printlist();


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值