数据结构——单链表

来源:互联网 发布:amd处理器优化 编辑:程序博客网 时间:2024/09/21 08:54

       链表也是一种常用的数据结构,机制灵活用途广泛,适用于许多通用数据库。讨论一下数组的使用缺陷: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}

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

0 0
原创粉丝点击