无头单链表的解析与实现

在这里插入图片描述

概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的引用链
接次序实现的 。

// 1、无头单向非循环链表实现
public interface ILinked {
//头插法
void addFirst(int data);
//尾插法
void addLast(int data);
//任意位置插入,第一个数据节点为0号下标
boolean addindex(int index,int data);
//查找是否包含关键字key是否在单链表当中
boolean contains(int key);
//删除第一次出现关键字为key的节点
3.3 链表面试题
int remove(int key);
//删除所有值为key的节点
void removeAllKey(int key);
//得到单链表的长度
int getLength();
void display();
void clear();
}

public class MySingleLinkedlmpl implements ILinked {
    class Node{
        public int getData() {
            return data;
        }
        private int data;
        public Node next;
        public Node(int data){
            this.data=data;
            this.next=null;
        }
    }//节点类
    private Node head;
    public MySingleLinkedlmpl(){
        this.head=null;
    }
    @Override
    public void addFirst(int data) {
        Node node=new Node(data);
        if(this.head==null){
            this.head=node;
        }else{
            node.next=this.head;
            this.head=node;
        }
    }

    @Override
    public void addLast(int data) {
        Node node=new Node(data);
        Node cur=this.head;
        if(cur==null){
            this.head=node;
        }else {
            //找尾巴
            while(cur.next!=null){
             cur=cur.next;
            }
            //退出上面的循环,cur所指向的位置就是尾节点
             cur.next=node;
        }
    }

    private void checkIndex(int index) {
        if(index < 0 || index > getLength()){
            throw new UnsupportedOperationException("index位置不合法");
        }
    }
    private Node searchIndex(int index){
       checkIndex(index);
       int count=0;
       Node cur=this.head;
       while (count<index-1){
           cur=cur.next;
           count++;
       }
       return cur;
    }
    @Override
    public boolean addindex(int index, int data) {
        Node node=new Node(data);
        if(index==0){
            addFirst(data);
            return true;
        }
        Node cur=searchIndex(index);
        node.next=cur.next;
        cur.next=node;
        return true;
    }

    @Override
    public boolean contains(int key) {
        Node cur=this.head;
        while(cur.next!=null){
            if(cur.data==key){
                return true;
            }
            cur=cur.next;
        }
        return false;
    }
//寻找前驱节点
    private Node searchPrev(int key) {
        Node cur = this.head;
        while (cur.next != null) {
            if(cur.next.data== key){
                return cur;
            }
            cur = cur.next;
        }
        return null;
    }
    @Override
    public int remove(int key) {
        Node cur=this.head;
        if(cur==null){
            throw new UnsupportedOperationException("单链表为空");
        }
        int oldDate=0;
        //删除节点为头节点
        if (this.head.data==key){
            oldDate=this.head.data;
            this.head=this.head.next;
            return oldDate;
        }
        Node prev = searchPrev(key);
        if(prev == null){
            throw new UnsupportedOperationException("没有前驱");
        }
        Node del = prev.next;
        oldDate = del.data;
        prev.next = del.next;
        //del = null;
        return oldDate;
    }

    @Override
    public void removeAllKey(int key) {
        if(this.head == null) {
            return;
        }
        Node prev = this.head;
        Node cur = this.head.next;
        while (cur != null) {
            if(cur.data == key){
                prev.next = cur.next;
                cur = prev.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        if(this.head.data == key){
            this.head = this.head.next;
        }
    }

    @Override
    public int getLength() {
        Node cur=this.head;
        if(cur==null){
            return 0;
        }
        int count=0;
        while(cur.next!=null){
            count++;
            cur=cur.next;
        }
        return count;
    }

    @Override
    public void display() {
        Node cur=this.head;
        while (cur.next!=null){
            System.out.print(cur.data+" ");
            cur=cur.next;
        }
        System.out.println();
    }

    @Override
    public void clear() {
        Node cur=this.head;
        while (cur.next!=null){
            Node del = cur.next;
            cur.next = del.next;
        }
        this.head=null;
    }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
无头单链表是一种常见的链表数据结构,它不像有头单链表那样有一个头节点,而是直接从第一个节点开始存储数据。下面是一种简单的实现方式: ``` // 定义链表节点结构体 struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; // 插入节点 void insertNode(ListNode *&head, int val) { ListNode *newNode = new ListNode(val); if (head == NULL) { head = newNode; } else { ListNode *cur = head; while (cur->next != NULL) { cur = cur->next; } cur->next = newNode; } } // 删除节点 void deleteNode(ListNode *&head, int val) { if (head == NULL) { return; } ListNode *cur = head, *prev = NULL; while (cur != NULL) { if (cur->val == val) { if (prev == NULL) { head = cur->next; } else { prev->next = cur->next; } delete cur; return; } prev = cur; cur = cur->next; } } // 遍历链表 void traverseList(ListNode *head) { ListNode *cur = head; while (cur != NULL) { cout << cur->val << " "; cur = cur->next; } cout << endl; } ``` 在这个实现中,我们用一个指针变量 `head` 来表示链表的头节点,初始值为 `NULL`,表示链表为空。`insertNode` 函数用于在链表末尾插入一个新节点,如果链表为空,则将新节点作为头节点;否则,找到链表末尾的节点,将其 next 指针指向新节点。`deleteNode` 函数用于删除链表中值为 `val` 的节点,如果链表为空则直接返回;否则,遍历链表,找到值为 `val` 的节点,将其从链表中删除。`traverseList` 函数用于遍历链表,输出每个节点的值。 需要注意的是,在使用完链表后,需要手动释放链表中所有节点的内存空间,可以通过循环遍历链表,依次删除每个节点来实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值