Java的单链表与双向链表的实现

数据结构即主要研究在数据不同逻辑结构的情况相应物理存储结构的转换问题,并在此存储结构下的各种运算操作。
数据结构分为:

  • 逻辑结构:线性和非线性,非线性又分为树形结构,图与网状结构。

  • 物理结构:顺序,链式,索引,散列。

顺序存储结构的计算机实现为数组,它的有点是查询速度快,时间复杂度为o(1)。但是对于数组的操作会引起位置的变动复杂度会比较大。链表的查询没有数组快,但是操作是十分方便的,只需改变指针即可进行增删改查。
由于java没有指针的概念,只有用引用变量去替换指针。接下来实现一个单链表和双向链表。

public class LinkListTest {
    public static void main(String args[])
    {
        LinkList linklist = new LinkList();

        //分别插入五个wrapper类Integer对象,验证add方法
        linklist.add(new Entry(new Integer(1)));
        System.out.println();
        System.out.println("此时链表的大小为"+linklist.size);

        linklist.printList();
        linklist.add(new Entry(new Integer(2)));
        System.out.println();
        System.out.println("此时链表的大小为"+linklist.size);

        linklist.printList();
        linklist.add(new Entry(new Integer(3)));
        System.out.println();
        System.out.println("此时链表的大小为"+linklist.size);

        linklist.printList();
        linklist.add(new Entry(new Integer(4)));
        System.out.println();
        System.out.println("此时链表的大小为"+linklist.size);

        linklist.printList();
        linklist.add(new Entry(new Integer(5)));
        System.out.println();
        System.out.println("此时链表的大小为"+linklist.size);
        linklist.printList();
        System.out.println();

        //在某个节点插入元素,验证insert方法
        linklist.insertIndexOfList(new Entry(new Integer(10)), 4);//在4位置后插入对象
        System.out.println("此时链表的大小为"+linklist.size);
        linklist.printList();
        System.out.println();

        //验证isEmpty方法
        System.out.println(linklist.isEmpty());

        //验证delete方法
        linklist.delete();
        System.out.println();
        linklist.printList();

        //验证delete(int index)方法
        linklist.delete(2);
        System.out.println();
        linklist.printList();

    }
}
class LinkList
{
    int size;
    Entry header;
    //初始化一个单链表,头结点为空,大小为0
    LinkList()
    {
        size = 0;
        header = new Entry(null,null);
    }
    //在单链表末尾插入一个节点
    public void add(Entry entry)
    {
        Entry p;
        p = header;
        while(p.next != null)
        {
            p = p.next;
        }
        p.next = entry;
        size ++;
    }
    //在单链表确定的位置index插入某个元素之后
    public void insertIndexOfList(Entry entry,int index)
    {
        Entry p;
        p = header;
        for(int i = 0;i < index;i ++)
        {
            p = p.next;
        }
        entry.next = p.next;
        p.next = entry;
        size ++;
    }
    //在单链表的末尾删除节点
    public void delete()
    {
        Entry p;
        p = header;
        for(int i = 0;i < size - 1;i ++)
        {
            p = p.next;
        }
        p.next = null;
        size --;
        return;
    }
    //删除某个index节点
    public void delete(int index)
    {
        Entry p;
        p = header;
        if(index > size || index < 1)
        {
            return;
        }
        else
        {
            for(int i = 0;i < index - 1;i ++)
            {
                p = p.next;
            }
            p.next = p.next.next;
            size --;

        }
    }
    //判断链表是否为空
    public boolean isEmpty()
    {
        if(size == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    //打印链表
    public void printList()
    {
        Entry p;
        p = header;
        System.out.print("头节点为"+p.ob);//头节点
        int i = 0;//计数
        while(p.next != null)
        {
            i ++;
            p = p.next;
            System.out.print("  第"+i+"个节点的ob值为"+p.ob);//从第一个节点(头节点外)分别打印出ob对象
        }
    }
    }
class Entry
{
    Object ob;
    Entry next;
    Entry(Object ob,Entry entry)
    {
        this.ob = ob;
        this.next = entry;
    }
    Entry(Object ob)
    {
        this.ob = ob;
        this.next = null;
    }
}

//下面是双向链表的实现

public class DLinkListTest {

    /**
     * @param args
     */
    /**
     * @param args
     */
    public static void main(String args[])
    {
        DoubleLinkList list = new DoubleLinkList();
        //测试在尾节点插入
        list.addRear(new DoubleEntry(new Integer(1)));

        list.addRear(new DoubleEntry(new Integer(2)));

        list.addRear(new DoubleEntry(new Integer(3)));
//      list.print();
        //测试在链表头插入
        list.addFront(new DoubleEntry(new Integer(0)));
        list.print();
        list.addRear(new DoubleEntry(new Integer(12)));
        list.addRear(new DoubleEntry(new Integer(15)));
        list.addRear(new DoubleEntry(new Integer(10)));
        list.print();
        list.deleteFront(1);
        list.print();
        list.insert(new DoubleEntry(new Integer(120)), 2);
        list.print();
    }

}

//定义一个双向链表
class DoubleLinkList
{
    int size;
    DoubleEntry header;
    //初始化一个双向链表
    DoubleLinkList()
    {
        size = 0;                           //大小为0
        header = new DoubleEntry(null);     //头节点为空 
    }

    //在链表尾部插入元素
    public void addRear(DoubleEntry doubleEntry)
    {
        DoubleEntry p = header;
        while(p.next != null)
        {
            p = p.next;
        }
        p.next = doubleEntry;
        doubleEntry.front = p;
        size ++;
    }
    //在链表头部插入元素
    public void addFront(DoubleEntry doubleEntry)
    {
        DoubleEntry p = header;
        p.next.front = doubleEntry;
        doubleEntry.next = p.next;
        p.next = doubleEntry;
        doubleEntry.front = p;

        size ++;
    }

    //在任意位置插入元素
    public void insert(DoubleEntry doubleEntry,int index)
    {
        DoubleEntry p = header;
        for(int i = 0;i < index;i ++)
        {
            p = p.next;
        }
        doubleEntry.front = p.front;
        p.front.next = doubleEntry;
        doubleEntry.next = p;
        p.front = doubleEntry;
        size ++;
    }
    //删除尾节点
    public void deleteRear()
    {
        DoubleEntry p = header;
        while(p.next != null)
        {
            p = p.next;
        }
        p.front.next = null;
        size --;
    }
    //删除任意一个节点
    public void deleteFront(int index)
    {
        DoubleEntry p = header;
        for(int i = 0;i < index;i ++)
        {
            p = p.next;
        }
        p.front.next = p.next;
        p.next.front =p.front;
        size --;
    }
    //判断链表是否为空
    public boolean isEmpty()
    {
        if(size == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public void print()
    {
        System.out.println();
        System.out.println("链表中除头节点外的节点有"+size+"个");
        DoubleEntry p = header;
        while(p.next != null)
        {
//          System.out.println("该节点的front指向"+p.front +" 该节点的next指向"+((Integer)p.next.ob));
            p = p.next;
            if(p.ob instanceof Integer)
            {
                System.out.print(((Integer)p.ob)+" ");
            }

        }
    }
    }

//定义元素节点
class DoubleEntry
{
    DoubleEntry front,next;
    Object ob;
    DoubleEntry(Object ob)
    {
        this.ob = ob;
    }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值