[JavaDS]单链表

目录

线性表

单链表:

1创建节点类Node

2 属性

3一些内存变化

4方法实现 

4.1public void addFirst(int data)//头插法

4.2public void addLast(int data)//尾插法

4.3public int size( )//链表长度

4.4public void Index(int index,int data)//插入节点

getIndexPos(int index)//返回当前插入节点的位置

4.5public boolean contains(int tofind)//查询是否包含关键字tofind

4.6public void display()//打印链表中的所有元素

4.7public void Remove(int toRemove)//删除单个节点

4.8private LinkedNode gettoRemovePrev(int toRemove)//找到要删除的前一个元素

public void Remove(int toRemove)//删除节点方法实现

 


线性表

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物

理上存储时,通常以数组和链式结构的形式存储。

eg.常见的线性表:顺序表、链表、栈、队列、字符串

单链表:

 一段物理地址不一定连续,逻辑上一定连续的存储单元存储数据结构

单链表接口:


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

1创建节点类Node:

是MySingleListImpl的内部类

a.节点类引用next:引用本质上是一个指针,也就是地址

  private Node next;

b.整型变量,名称为data

c.利用构造函数对属性进行初始化

public Node(){//无参构造
this.data=-1;
this.next=null;
}
public Node(int data){//有参构造
this.data=data;
}

d.内部类Node类的代码:

class Node {
        private Node next;
        private int data;

        //node的data域没有值,提供一个不带有参数的构造函数
        public Node() {
            //用-1去标识data域中的数据
            this.data = -1;
            this.next = null;
        }
        //实体结点应该有data值
        public Node(int data) {
            this.data = data;
        }
    }

2 属性

a.head:结点类属性,表示链表的头结点

private Node head;

3一些内存变化

a.创建node引用时内存的变化:(LinkedNode node=new LinkedNode)

b.node引用指向next时内存的变化:(node=node.next)

4方法实现 

4.1public void addFirst(int data)//头插法

通俗点讲就是从链表的头部插入节点。这时候我们要考虑两种情况: 

a.头节点为空,插入的节点就指向链表的头节点

this.node=this.head;

b.头节点不为空,插入的节点指向头节点的下一个节点,头节点指向node

this.node=this.head.next;
this.head=node;

方法代码:

public void addFirst(int data){
Node node=new Node(data);
if(this.head==null){
this.node=this.head;
return;
}else{
this.node=this.head.next;
this.head=node;
return;
}

4.2public void addLast(int data)//尾插法

就是从链表的尾部插入节点。

思想:

这时候要考虑链表的头节点为空的情况

a.头节点为空,和头插法类比。

b.头节点不为空,new 一个cur对象,将当前头节点的定义为cur,遍历cur直到cur.next为空说明链表遍历结束。

此时插入node节点,使得cur.next指向node

方法代码:

public void addLast(int data){
Node node=new Node(data);
if(this.head==null){
this.head=this.node;
}else{
Node cur=this.head;
while(cur!=null){
this.cur=this.cur.next;
}
this.cur.next=this.node;
}

4.3public int size( )//链表长度

思想:创建计数变量count,new 一个Node对象cur 遍历单链表,可以得出链表的长度。

方法代码:

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

4.4public void Index(int index,int data)//插入节点

思想:

1 头插

2 尾插

3 中间插

在实现插入方法前我们需要找到被插入节点的前驱

这里引入另一个方法

getIndexPos(int index)//返回当前插入节点的位置

思想:

a.new 一个Node类对象cur,遍历单链表直到index位置退出循环

b.中间插:

也就是node节点插入到index(目标插入点)-1的后面,利用找到插入节点位置的方法,找到插入节点的前驱prev,再将node的next指向prev的next,prev的next指向node

方法代码:

public void Index(int index,int data){
Node node=new Node(data);
int len=size();
if(index<0||index>len){
return;
}
if(index==0){
addFirst(data);
return;
}
if(index==len){
addLast(data);
return;
}
Node prev=getIndexPos(index-1);
node.next=prev.next;
prev.next=node;
}

4.5public boolean contains(int tofind)//查询是否包含关键字tofind

思想:Node 类节点cur遍历链表,当cur.data==tofind说明成功找到,返回true,否则返回false

方法代码:

public boolean contains(int tofind){
Node cur=this.head;
while(cur!=null){
if(this.cur.data==tofind){
return true;
}
this.cur=this.cur.next;
}
return false;
}

4.6public void display()//打印链表中的所有元素

public void display()
{
    System.out.println("[");
    LinkedNode cur=this.head;
    while(cur!=null){
        System.out.print(cur.data);
        if(node.next!=null){
        System.out.print(",");
        }
        cur=cur.next;
        }
        System.out.println("]");
        }

for循环:

public void display(){
System.out.println(“[“);
for(LinkedNode node=this.head;node!=null;node=node.next){
System.out.print(node.data);
if(node.next!=null){
System.out.print(”,“);
}
}
System.out.println(“]”);
}

4.7public void Remove(int toRemove)//删除单个节点

思想:

1 检查是否是空链表

2 检查删除的是否是头节点

3 找到要删除的前一个元素,将要删除的前一个元素指向被删除元素的下一个元素。

4.8private LinkedNode gettoRemovePrev(int toRemove)//找到要删除的前一个元素

1 先判断是不是空链表

2 prev不为空时遍历单链表

要删除的节点toRemove等于prev.next的data域时,返回prev 

private LinkedNode gettoRemovePrev(int toRemove){
if(this.head==null){
return;
}
LinkedNode prev=this.head;
while(prev!=null){
if(prev.next.data==toRemove){
return prev;
}
prev=prev.next;
}
return;
}

public void Remove(int toRemove)//删除节点方法实现

public void Remove(int toRemove){
if(this.head==null){
return;
}
if(this.head.data==toRemove){
this.head==this.head.next;
}
LinkedNode prev=gettoRemovePrev(toRemove);
node=prev.next;
prev.next=node.next;
}

 

 完整代码:

public class MySingleListImpl implements ILinked {
    //内部类
    class Node {
        private Node next;
        private int data;

        //node的data域没有值,提供一个不带有参数的构造函数
        public Node() {
            //用-1去标识data域中的数据
            this.data = -1;
            this.next = null;
        }
        //实体结点应该有data值
        public Node(int data) {
            this.data = data;
        }
    }
    private Node head;
    public MySingleListImpl() {
        this.head = new Node();
        this.head.next = this.head;
    }
    //头插法
    @Override
    public void addFirst(int data) {
        Node node = new Node(data);
        node.next = this.head.next;
        this.head.next = node;
    }
    //尾插法
    @Override
    public void addLast(int data) {
        //从头开始找
        Node cur = this.head;
        while (cur.next != this.head) {
            cur = cur.next;
        }
        //拿到一个结点实例
        Node node = new Node(data);
        node.next = this.head;
        cur.next = node;
    }

    private void checkIndex(int index) {
        if (index < 0 || index > getLength()) {
            throw new UnsupportedOperationException("下标不合法");
        }
    }
    //任意位置插入,第一个数据节点为0号下标
    @Override
    public boolean addIndex(int index, int data) {
        checkIndex(index);
        Node cur = this.head;
        for (int i = 0; i < index; i++) {
            cur = cur.next;
        }
        Node node = new Node(data);
        node.next = cur.next;
        cur.next = node;
        return true;
    }
    //查找是否包含关键字key是否在单链表当中
    @Override
    public boolean contains(int key) {
        Node cur = this.head.next;
        while (cur != head) {
            if (cur.data == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    private Node searchPrev(int key) {
        int oldData = 0;
        Node prev = this.head;
        while (prev.next != this.head) {
            if (prev.next.data == key) {
                return prev;
            }
            prev = prev.next;
        }
        return null;
    }

    @Override
    public int remove(int key) {
        Node prev = searchPrev(key);
        if (prev == null) {
            //return -1;
            throw new UnsupportedOperationException("key不存在前驱");
        }
        int oldData = 0;
        Node delNode = prev.next;
        oldData = delNode.data;
        prev.next = delNode.next;
        return oldData;
    }
    //删除所有值为key的节点
    @Override
    public void removeAllKey(int key) {
        Node prev = this.head;
        Node cur = prev.next;
        while (cur != this.head) {
            if (cur.data == key) {
                prev.next = cur.next;
                cur = cur.next;
            } else {
                prev = cur;
                cur = cur.next;
            }
        }
    }
    //得到单链表的长度
    @Override
    public int getLength() {
        Node cur = this.head.next;
        int count = 0;
        while (cur != this.head) {
            cur = cur.next;
            count++;
        }
        return count;
    }

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

主函数: 

public class Test3
{
            public static void main(String[] args) throws Exception {
                MySingleListImpl cHeadSingleList = new MySingleListImpl();
                cHeadSingleList.addFirst(1);
                cHeadSingleList.addFirst(3);
                cHeadSingleList.addFirst(105);
                cHeadSingleList.addFirst(3);
                cHeadSingleList.addFirst(9);
                cHeadSingleList.display();
                cHeadSingleList.addIndex(0, 3);
                cHeadSingleList.addLast(100);
                cHeadSingleList.display();
                System.out.println(cHeadSingleList.contains(135));
                cHeadSingleList.removeAllKey(3);
                cHeadSingleList.display();
                cHeadSingleList.clear();
                Thread.sleep(1000);
            }
        }

运行结果:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include<iostream> using namespace std; enum yaya { error,success }; struct node { int data; node*next; }; class List{ public: List(); ~List(); int length(); yaya set_data(int n); node* get_ptr(int m); yaya inset_node(int x,int y); int delete_node(int i); void put_in(int x); void breaktwo(List&la,List&lb); void same_data(List&l1,List&l2,List&l); int out_data(); private: int count; node* head; }; List::List(){ head=new node; head->next=NULL; count=0; } int List::length(){ return count; } yaya List::set_data(int n){ node*p=head; for(int j=0;j<n;j++){ cin>>p->data; p=p->next; count++; if(p==NULL){ return error; } } return success; } node* List::get_ptr(int m){ node*p=head; int j=0; while(p!=NULL&&j<m){ j++; p=p->next; } return p; } yaya List::inset_node(int x,int y){ if(x<=0||x>count+1){ return error; } node*p=new node; p->data=y; node*current=head; for(int j=1;j<x;j++){ current=current->next; } p->next=current->next; current->next=p; count++; return success; } int List::delete_node(int i){ if(i<=0||i>count) return NULL; node*current=head; for(int j=1;j<i;j++){ current=current->next; }node*u=current->next; current->next=u->next; delete u; count--; return success; } void List::put_in(int x){ node*p=new node; p->data=x; node*current=head; for(;current!=NULL&&current->next!=NULL&&current->next->data<x;){ current=current->next; } p->next=current->next; current->next=p; count++; return; } void List::breaktwo(List& la,List& lb){ node*q=head->next; la.inset_node(la.count+1,q->data); while(q!=NULL&&q->next!=NULL&&q->next->next!=NULL){ q=q->next->next; la.inset_node(la.count+1,q->data); } node*w=head->next->next; lb.inset_node(lb.count+1,w->data); while(w!=NULL&&w->next!=NULL&&w->next->next!=NULL){ w=w->next->next; lb.inset_node(lb.count+1,w->data); } } void List::same_data(List&l1,List&l2,List&l){ node*p=l1.head; for(int i=1;i<=l1.count;i++){ p=p->next; node*q=l2.head; for(int j=1;j<=l2.count;j++){ q=q->next; if(p->data==q->data) l.inset_node(l.length()+1,p->data); } } } int List::out_data(){ node*p=head; for(int j=1;j<=count;j++){ p=p->next; cout<<(p->data)<<" "; } cout<<endl; return 0; } List::~List(){ node*p=head,*s; while(p!=NULL){ s=p; p=p->next; delete s; } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值