(4)链表

链表相比与数组,在进行循环遍历时效率不高,但是插入和删除的优势明显。
链表实际上是由节点组成的,一个链表对外暴露的只有根节点,我们对链表的所以操作都是直接或间接的通过根节点来进行的。
而节点是由一个需要存储的对象和对下一节点的引用组成的,即节点拥有两个成员:存储的对象、下一节点的引用。
写一个简单链表。

package jun.text;

class Link{//链表类,外部能够看见的只有这一个
    private class Node{//定义节点类
        private Object data;//保存数据
        private Node next;//引用关系
        public Node(Object data){
            this.data = data;
        }
        public void addNode(Node newNode){
            if(this.next==null){
                this.next = newNode;
            }
            else{
                this.next.addNode(newNode);
            }
        }
        //第一次调用(Link):this = Link.root
        //第二次调用(Node):this = Link.root.next
        public boolean contaionsNode(Object data) {
            if(data.equals(this.data)){
                return true;
            }else{  //当前节点不满足查询要求
                if(this.next != null){  //有后续节点
                    return this.next.contaionsNode(data);
                }else{
                    return false;
                }
            }
        }
        public Object getNode(int index) {
            //使用当前的foot内容与要查询的索引进行比较,
            //随后将foot的内容自增,目的是为了方便下次查询
            if(Link.this.foot ++ == index){
                return this.data;
            }else{
                if(this.next != null){
                    return this.next.getNode(index);
                }
                return null;
            }
        }

        public void removeNode(Node pre,Object data){
            if(data.equals(this.data)){ //当前节点为要删除的节点
                pre.next = this.next;   //空出当前节点
            }else{
                this.next.removeNode(this, data);
            }
        }
        public void toArrayNode() {
            Link.this.array[Link.this.foot ++] = this.data;
            if(this.next != null){
                this.next.toArrayNode();
            }
        }
    }

    private Node root; //需要根节点
    private int count = 0;//保存元素的个数
    private int foot = 0;
    private Object[] array;//返回的数组
    public void add(Object data){
        if(data == null){//假设不允许为空
            return;
        }
        Node newNode = new Node(data);//要保存的数据
        if(this.root==null){    //当前没有根节点
            this.root = newNode;//保存根节点
        }
        else{//根节点存在,其他节点交给Node类处理
            this.root.addNode(newNode);
        }
        this.count++;
    }

    public int size(){//取得保存的数据量
        return this.count;
    }

    public boolean isEmpty(){//判断链表是否为空
        return this.count==0;
    }

    public Object get(int index){
        if(index>this.count){
            return null;
        }
        this.foot = 0;//表示从前向后查询
        return this.root.getNode(index);//查询过程交给Node类处理

    }

    public boolean contains(Object data){//判断数据是否存在
        //如果没有要查询的数据,根节点也不保存数据
        if(data == null|| this.root == null){
            return false;
        }
        //交给Node类查询
        return this.root.contaionsNode(data);
    }

    public Object[] toArray(){
        if(this.root == null){
            return null;
        }
        this.foot = 0;
        this.array = new Object[this.count];
        this.root.toArrayNode();
        return this.array;
    }

    public void remove(Object data){
        if(this.contains(data)){
            //要删除数据是否是根节点数据
            //root是Node类的对象,此处直接访问了内部类的私有操作
            if(data.equals(this.root.data)){    //为要删除节点
                this.root = this.root.next; //空出当前根节点
            }else{  //不是根元素
                //从第二个元素开始判断
                this.root.next.removeNode(this.root, data);
            }
            this.count--;
        }
    }
}
public class LinkDemo {
    public static void main(String[] args) {
        Link all = new Link();
        all.add("qq");
        all.add("ww");
        all.add("ee");

        Object[] data = all.toArray();
        for(int i=0; i<data.length; i++){
            System.out.print(data[i]+" ");
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用Python实现删除单向链表中等于给定节点值的节点的代码: ```python class ListNode: def __init__(self, val): self.val = val self.next = None def delete_node(head, value): # 处理头节点为要删除节点的情况 while head and head.val == value: head = head.next # 处理无节点的情况 if not head: return None # 处理其他节点为要删除节点的情况 prev, curr = head, head.next while curr: if curr.val == value: prev.next = curr.next else: prev = curr curr = curr.next return head # 构造链表 n, head_val = map(int, input().split()) nodes = {head_val: ListNode(head_val)} for _ in range(n-1): node_val, insert_val = map(int, input().split()) if node_val not in nodes: nodes[node_val] = ListNode(node_val) if insert_val not in nodes: nodes[insert_val] = ListNode(insert_val) nodes[node_val].next = nodes[insert_val] # 删除给定节点值的节点 result = delete_node(nodes[head_val], int(input())) # 输出结果 output = [] while result: output.append(str(result.val)) result = result.next print(" ".join(output)) ``` 注意,为了处理节点值不能重复的要求,我们要用字典来存储每个节点,以节点值为键、节点对象为值。这样在构造链表时,如果遇到已经存在的节点值,就直接使用对应的节点对象;如果遇到新的节点值,就先创建一个新的节点对象并加入字典中。在删除节点时也是一样,用节点值来索引对应的节点对象,从而对节点进行操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值