链表小结

链表小结

链表

 

    链表是一种重要的数据结构,在程序设计中占有很重要的地位。 C 语言和 C ++ 语言中是用指针来实现链表结构的,由于 java 语言不提供指针,所以有人认为在 java 语言中不能实现链表,其实不是这样, java 语言比 C 语言和 C ++ 语言更容易实现链表结构。 Java 语言中的对象引用实际上就相当于指针的作用。链表与数组和队列这种数据结构在存储上的不同体现在:其物理存储为非连续,非顺序的,数据元素的逻辑顺序是通过链表中对象的引用(指针)来实现的。链表有一系列结点(链表中的每个元素称为结点)组成,节点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。相比于线性表顺序结构,链表比较容易插入和删除。

 

一、 单向链表

单向链表 的每一个结点只有一个指针域和数据域组成


 

/**

  * 单向链表的节点类

  *

  */

public class LinkNode {

    // 节点内的数据对象

    private Object obj ;

    // 对下一节点的引用

    private LinkNode next ;

    // 在创建节点对象的时候就传入节点中的数据对象

    public LinkNode(Object obj){

        this . obj = obj;

    }

    public Object getObj(){

        return obj ;

    }

    public void setObj(Object obj){

        this . obj = obj;

    }

    public LinkNode getNext(){

        return next ;

    }

    public void setNext(LinkNode next){

        this . next = next;

    }

}

/**

  * 单向链表类

  * *

  */

public class LinkList {

    public static void main(String args[]) {

        LinkList list = new LinkList();

        // 创建链表

        LinkNode root = list.createLink();

        // 遍历

        list.printLinkList(root);

    }

 

    // 创建链表

    public LinkNode createLink() {

        String s = " 根节点 " ;

        LinkNode root = new LinkNode(s);

        LinkNode n1 = new LinkNode( " 一节点 " );

        LinkNode n2 = new LinkNode( " 二节点 " );

        LinkNode n3 = new LinkNode( " 三节点 " );

        root.setNext(n1);

        n1.setNext(n2);

        n2.setNext(n3);

        return root;

    }

    public void printLinkList(LinkNode root) {

        if ( null != root) {

            Object data = root.getObj();

            System. out .println(data);

            // 继续向下打印

            printLinkList(root.getNext());

        }

    }

}

 

二、 双向链表

单向链表的缺点是如果你相对链表中的某个结点进行操作,如果是单向非循环链表,只能从表头开始查找、这是有单链表的结构所导致的,因为单向链表每个结点只有一个存储子节点的地址的链域。而双向链表则是对单向链表的一种改进,在双向链表中结点由数据域和一个存储直接子结点地址的右链域,一个存储直接父结点地址的左链域。这样无论从链表中的任何位置都可以得到整个链表中的元素。


/**

  * 双向链表结点类

  *

  */

public class LinkNode {

    // 定义双向链表的三个属性

    private Object obj ;

    private LinkNode child ;

    private LinkNode parent ;

    // 重载构造方法,并传入参数

    public LinkNode(Object obj){

        this . obj = obj;

    }

    // 取得链表中的元素

    public Object getObj() {

        return obj ;

    }

    // 设置链表中的元素

    public void setObj(Object obj) {

        this . obj = obj;

    }

    public LinkNode getChild() {

        return child ;

    }

    public void setChild(LinkNode child) {

        this . child = child;

    }

    public LinkNode getParent() {

        return parent ;

    }

    public void setParent(LinkNode parent) {

        this . parent = parent;

    }  

}

链表实现自定义队列

实现数据 的查找,删除,添加,插入,长度,等操作

/**

  * 双向链表类

  *

  */

public class LinkList {

 

    // 定义一个头结点

    public static  LinkNode head = null;

    // 定义一个尾结点

    public  LinkNode foot = head;

    // 程序入口

    public static void main(String args[]){

        LinkList list = new LinkList();

        for(int i=0;i<10;i++){

            list.add(" 练习 "+i);

        }

        list.add(6, " 新加入的 ");

        System.out.println(" 删除前遍历》》》》》》》》》》》》》》》 ");

        list.printList(head);

        list.size();

        LinkNode c = list.getNode(4);

        System.out.println(">>>>>>>>>>>>>>>>>>");

        System.out.println(c.getObj());    

        list.remove(3);

        System.out.println(" 元素的个数: "+list.size());

        System.out.println(" 删除后遍历《《《《《《《《《《《《《《《《《《《 ");

        list.printList(head);

        System.out.println(" 更改某位置上的元素! ");

        list.update(2, " 人不犯我我不犯人! ");

        list.printList(head);

    }

    /**

      * 添加一個元素的方法

      * @param obj

      */

    public  void add(Object obj){

        LinkNode node = new LinkNode(obj);

        if(head==null){

            head = node;

            foot = head;

        }

        else{

            node.setParent(foot);

            foot.setChild(node);

            foot = node;

        }

    }

    /**

      * 插入一個元素的方法

      * @param index 所要插入元素的索引位置

      * @param obj 所要插入的元素

      */

    public void add(int index,Object obj){

        if(index>size()||index<0){

            throw new RuntimeException(" 越界: "+index+",size:"+size());

        }else{

            LinkNode newnode = new LinkNode(obj);

            // 得到所要插入位置的索引

            LinkNode node = this.getNode(index);

            if(index==0){

//              head.setChild(newnode);

//              newnode.setParent(head);

                head = newnode;

               

            }else{

                // 得到父节点对象

                LinkNode fnode = node.getParent();

                fnode.setChild(newnode);

                newnode.setParent(fnode);          

            }

            newnode.setChild(node);

            node.setParent(newnode);

        }      

    }

    /**

      * 删除指定索引位置上的元素

      * @param index 要删除元素的索引位置

      */

    public void remove(int index){

        if(index>size()||index<0){

            throw new RuntimeException(" 越界: "+index+",size:"+size());

        }else{

            // 获得要删除元素的索引值

            LinkNode node = this.getNode(index);

            LinkNode fnode = node.getParent();

            LinkNode cnode = node.getChild();

            if(index==0){

                head = cnode;

            }else if(cnode == null){

                cnode = null;

            }

            else{

                cnode.setParent(fnode);

                fnode.setChild(cnode);

            }

        }

    }

    public void update(int index,Object obj){

        if(index>size()||index<0){

            throw new RuntimeException(" 越界: "+index+",size:"+size());

        }

        else{

            LinkNode node = this.getNode(index);

            node.setObj(obj);

        }

    }

    /**

      * 获取链表的长度

      * @return

      */

    public int size(){

        int count = 0;

        if(head==null){

            return 0;

        }

            // 创建一个节点对象

            LinkNode node = head.getChild();

            while(node!=null){

                count++;

                node = node.getChild();

            }

            return count+1;

           

        }

    /**

      * 得到指定位置上的元素

      * @param index

      * @return

      */

        public LinkNode getNode(int index){

           

            if(index>size()||index<0){

                throw new RuntimeException(" 越界: "+index+",size:"+size());

            }

            else {

                int i = 0;

                LinkNode node = head;

                // 如果没有找到就继续向下找

                while(i!=index){

                    node = node.getChild();

                    i++;

                }              

                return node;

            }          

}

    /**

      * 打印链表中的元素

      * @param head

      */

    public  void printList(LinkNode head){

        if(head!=null){

            Object obj = head.getObj();

            System.out.println(obj);           

            printList(head.getChild());

        }  

    }  

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值