数据结构——单链表

本文介绍了单链表的基本概念及其实现方式,并详细探讨了如何通过添加、删除节点以及查找特定元素来操作单链表。文章还提供了具体的代码示例,帮助读者更好地理解链表的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       链表也是一种常用的数据结构,机制灵活用途广泛,适用于许多通用数据库。讨论一下数组的使用缺陷:1.无序数组搜索效率比较低,有序数组插入效率比较低。无论哪一种删除效率都很低。2。数组大小一旦创建了就不能改变该数组的大小了。链表相对于数组这些缺陷都有一定的改善。

链结点

通常每个对象中都包含一个对下一个链结点的引用。如下图所示:

这里写图片描述

关于自引用

       在定义链表基本结构时会用到自引用,这是建立链表的重要环节。Link的自引用字段仅仅是对另外一个Link对象的引用而已,不是一个对象,仅仅是计算机内存中的对象地址,不需要具体值,相当于指向对象,这个引用能够找到对象在哪里。

//创建一个link类,实现对数据的封装和自身引用
class Link
{
    private int data1=0;
    private double data2=0;
    Link nodeNext;

    public int getData1() {
        return data1;
    }
    public void setData1(int data1) {
        this.data1 = data1;
    }
    public double getData2() {
        return data2;
    }
    public void setData2(double data2) {
        this.data2 = data2;
    }
    public Link(int data1,double data2)
    {
        this.data1=data1;
        this.data2=data2;
    }
    public void showLink()
    {
        System.out.println("{"+data1+","+data2+"}");
    }
}

       关于链表的操作通常有add、remove数据项,查找find等。在单链表先实现以下简单的功能:1)从链表head部插入数据 2)head处删除数据 3)遍历链表数据项。

插入数据项。这里的数据项仅仅保存两个数值。

private Link firstNode=null;//需要初始化为null
    //从头部开始增加节点
    public void add(int data1,double data2)
    {
        Link newNode=new  Link(data1,data2);//向链表中添加数据
        newNode.nodeNext=firstNode;//链表指向以前的firstNode
        firstNode=newNode;//更新当前firstNode引用, 链表的最后一个tail引用是null

    }

       从链表head处开始添加数据,firstNode初始化为null是比较重要的,因为最终这是判断链表尾部(tail)的标志。之后就是对firstNode引用进行更新,这样就实现了对链表的数据添加,以上对数据的添加其实是模拟栈结构。

删除数据项

public Link remove()
    {
        Link temp=firstNode;//保存当前节点
        firstNode=firstNode.nodeNext;//将头接头直接指向被删除节点的下一个节点 可以参考图进行理解
        return temp;//返回节点信息

    }

删除数据项可以用下图理解

这里写图片描述

删除之前

这里写图片描述

删除之后

public void showLinkList()
    {
        Link current=firstNode;
        while(current!=null)
        {
            current.showLink();
            current=current.nodeNext;
        }

    }

测试代码

LinkList list=new LinkList();
        list.add(1,1.0);//链表尾部 指向null
        list.add(2,2.0);
        list.add(3,3.0);
        list.add(4,4.0);
        list.add(5,5.0);
        list.add(6,6.0);//此时firstNode指向最后一次添加node
        list.showLinkList();//从firstNode开始打印输出
        list.remove();
        list.remove();
        list.remove();
        list.showLinkList();

输出结果是

{6,6.0}
{5,5.0}
{4,4.0}
{3,3.0}
{2,2.0}
{1,1.0}
删除后链表数据项为:
{3,3.0}
{2,2.0}
{1,1.0}

       第一次输出是对链表中的数据进行遍历,之后输出是从链表删除一些数据后链表剩余的数据项。由于链表是表的head部开始添加后删除的,满足先进后出的栈结构。

通常链表还有关键数据项的查找与删除关键数据等操作。

关键数据项的find

//在链表中查找关键字的方法
    public void find(int key)
    {
        Link current=firstNode;
        while(true)
        {
            if(current.getData1()==key)
            {
                break;
            }
            else 
            {
                current=current.nodeNext;
                if(current==null)
                    break;
            }

        }
        if(current!=null)
        {
            System.out.println("find it");
            System.out.println("key is "+current.getData1()+" and the other data is "+current.getData2());
        }else
        {
            System.out.println("we can not find it");
        }


    }

测试一下:

list.find(2000);

输出:we can not find it

list.find(6);

输出:find it

key is 6 and the other data is 6.0

关于关键数据项的删除

这种删除从链表head部开始删除较麻烦,需要引入privious Link对象。

//从链表中删除关键字 指定节点的删除
    public Link removeKey(int key)
    {
        Link privious=firstNode;
        Link current=firstNode;
        while(current.getData1()!=key)//没找到key 指针移动
        {
                 privious=current;
                 current=current.nodeNext;
                 if(current==null)
                 break;
        }
        //找到了key
        if(current==firstNode)
        {
            firstNode=firstNode.nodeNext;
        }
        else
        {
            privious.nodeNext=current.nodeNext;
        }
        return current;

    }

测试一下:

        list.add(1,1.0);//链表尾部 指向null
        list.add(2,2.0);
        list.add(3,3.0);
        list.add(4,4.0);
        list.add(5,5.0);
        list.add(6,6.0);//此时firstNode指向最后一次添加node
        list.showLinkList();//从firstNode开始打印输出
        list.removeKey(1);
        list.removeKey(3);
        list.removeKey(5);
        list.showLinkList();

测试结果是:

{6,6.0}
{4,4.0}
{2,2.0}

以上结果与预期一致。关于单链表基本上就是以上的几种操作,更多的还有双端链表、有序链表、双向链表以及迭代器的链表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值