数据结构第二篇——手把手教你链表

一、链表的初步认识:

从上一篇中,我们已经知道了顺序表,但是从顺序表的插入和删除来看,是比较麻烦的,时间复杂度为O(n),因此这里就有了另外一种结构:链表。链表就是逻辑结构上连续,但是物理结构上不一定连续。对于链表来说,一共有8种链表。

1 单向和双向的

在这其中,第一种是单向的,也是没有头结点的,就类似有傀儡节点;第二种是双向的,也是有类似的傀儡节点,但是要注意头和尾节点,中间的插入和删除需要注意。

2 带头或者不带头的

3 循环或者不循环的

分类别就是上面的三种类别,组合起来就是8种。

但是用的最多的还是:

无头单向非循环的链表,结构:

 

 二:链表的实现

老规矩,咱就是说,直接上代码

首先是定义节点:

class LinkNode{
    public int data;
    public LinkNode next;
    public LinkNode(int data){
        this.data=data;
    }
}

(1)addFirst(int data):实现链表的头插,这个还是基表简单的,思想就是把新节点的next域指向最开始的头结点就行,其最后实现的是倒序

 public void addFirst(int data){
            //头插法的本质就是:把新节点以头节点为依靠,插在头结点的前面,即依靠头来插入
            //首先的把数据用节点包装起来
            LinkNode linkNode=new LinkNode(data);
            linkNode.next=head;

            //然后再把head移到新节点处
            head=linkNode;

        }

(2)addLast(int data):就是按照正常的顺序进入链表,只是要注意:需要再定义一个节点指针来遍历链表,见代码

public void addLast(int data) {
            //就是以尾巴(最后一个节点)为依据来插入,那么就需要找到最后一个节点
            //先包装data

            LinkNode linkNode = new LinkNode(data);

            if (this.size() == 0) {
                head = linkNode;
            } else {
                LinkNode temp = head;
                while (temp.next != null) {
                    temp = temp.next;
                }
                //这里以找到最后一个节点结束
                temp.next = linkNode;
            }
        }

(3)求链表的大小:遍历一定要找一个节点指针,然后遍历

 //得到单链表的长度
        public int size(){
            int count=0;
            LinkNode temp=head;
            while(temp!=null){
                count++;
                temp=temp.next;
            }
            return count;
        }

(4)判断下标是否合法:下标和顺序表一样,不能小于0,不能超过长度,但是链表没有下标

 public boolean isIndex(int index){
            if(index<0||index>this.size()){
                return false;
            }
            return true;
    }

(5)addIndex(int index,int data):把data元素添加到index下标的位置

 public boolean addIndex(int index,int data){
            if(isIndex(index)==false){
                return false;
            }
            else{
                //先包装
                LinkNode linkNode=new LinkNode(data);
                if(index==0){
                    addFirst(data);
                }
                if(index==this.size()){
                    addLast(data);
                }
                else {
                    LinkNode temp=head;
                    for(int i=0;i<index-1;i++){
                        temp=temp.next;
                    }
                    //这里以index-1的下标节点结束
                    linkNode.next=temp.next;
                    temp.next=linkNode;
                }
            }
            return true;
        }

(6)contains(int key):判断链表中是否含有key元素

   //查找是否包含关键字key是否在单链表当中
        public boolean contains(int key){
            LinkNode temp=head;
            while(temp!=null){
                if(temp.data==key){
                    return true;
                }
                temp=temp.next;
            }
            return false;
        }

(7)remove(int key):删除第一次遇到key的元素,注意在这里我们必须注意要找到该元素的前一个位置,于是temp.next.data,而不是temp.next

  public void remove(int key) {
            if(head.data==key){
                head=head.next;
            }
            else{
                LinkNode temp=head;
                for(int i=0;i<this.size()-1;i++){
                    if(temp.next.data==key){
                        temp.next=temp.next.next;
                        break;
                    }
                    temp=temp.next;
                }
            }
        }

(8)removeAllKey(int key):删除所有值为key的元素,和remove的区别就是找到了但是没有break退出

   //删除所有值为key的节点
        public void removeAllKey(int key){
            if(head.data==key){
                head=head.next;
            }
                LinkNode temp=head;
                for(int i=0;i<this.size()-1;i++){
                    if(temp.next.data==key){
                        temp.next=temp.next.next;
                    }
                    temp=temp.next;
                }
        }

(9)display():打印链表,遍历即可


        public void display(){
            LinkNode temp=head;
            while(temp!=null){
                System.out.print(temp.data+" ");
                temp=temp.next;
            }

            System.out.println("\n");
        }

(10)clear():清空链表,那么

     public void clear(){
            LinkNode temp=head;
            while(temp!=null){
                temp=temp.next;
                head=null;
                head=temp;
            }
        }

最后,链表的基本操作就结束了,本节一直都用的不带头结点的非循环链表来讲的,下次出栈、队列、二叉树.....,方便以后的复习,所以点赞关注起来吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值