JAVA实现链表

前言

前面我们学习了顺序表,了解到了顺序表的操作方便,也便于理解,但顺序表也有缺点,比如在插入或者删除结点的时候,需要移动大量的数据,如果表比较大,有时还难以分配足够的连续的存储空间,往往导致内存分配失败,这也是这里我们为什么学习链表结构的原因

引入

链表结构,一种动态存储分配的结构,可以根据需要动态申请内存单元,在逻辑上相邻的结点在物理内存上不一定相邻
链表结构的缺点
* 浪费存储空间
* 顺序访问,访问效率较低
* 空间密度不高
所以一般查找频繁的使用表都是采用顺序表,修改操作频繁的使用链表

链表的种类

单链表:链式结构,每个节点只包含一个引用
双向链表:若每个节点包含俩个引用,一个指向下一个结点,另一个指向上一个结点
单循环链表:在单链表中,将终端结点的引用域 null 改为指向表头结点或开始结点即可构成
多重链的循环链表:将表中结点链在多个环上
大家可以了解一下以上的各种表,本文只跟大家演示单链表,接下来我们看代码具体实现

package List;

import java.util.Scanner;

/**
 *@author Mr.wei
 *@version 1.0
 */
public class LinkList {
    static class DATA{
        String key;
        String name;
        int age;
    }

    //定义链表结构
    static class CLType{
        DATA nodeData = new DATA();
        CLType nextNode;
        //插入头结点,头插法
        CLType CLAddFirst(CLType head,DATA nodeData)
        {
            CLType node = new CLType();
            if( node == null ){
                System.out.println("申请内存失败!\n");
                return null;
            }else{
                node.nodeData = nodeData;//保存数据
                node.nextNode = head;
                head = node;
                return head;
            }
        }
        //插入尾结点,
        CLType CLAddend(CLType head,DATA nodeData){
            CLType node,temp;
            node = new CLType();
            if(node == null){
                System.out.println("内存申请失败");
                return null;
            }else{
                node.nodeData = nodeData;
                node.nextNode = null;//设置结点引用为空,即为表尾
                if(head == null){
                    head = node;
                    return head;
                }
                temp = head;
                while( temp.nextNode != null){
                    temp = temp.nextNode;//temp 不为空继续追溯到下一结点,直到为空即是表尾
                }
                temp.nextNode = node;//将node作为新的表尾
                return head;
            }
        }

        //查找结点
        CLType CLFind(CLType head,String key){
            CLType temp;
            temp = head;
            while(temp != null){
                if(temp.nodeData.key.equals(key)){//找到结点返回
                    return temp;
                }
                temp = temp.nextNode;
            }
            return null;//没有找到返回空
        }

        //插入结点
        CLType CLinsert(CLType head,String key,DATA nodeData){
            CLType nodetemp = CLFind(head, key);//查找要插入的结点位置
            CLType node;//接收待插入结点
            if( (node = new CLType()) == null){
                System.out.println("申请内存失败");
            }
            node.nodeData = nodeData;
            if(nodetemp != null){
                node.nextNode = nodetemp.nextNode;
                nodetemp.nextNode = node.nextNode;
            }
            else{
                System.out.println("找不到正确的插入位置");
            }
            return head;
        }
        //删除结点
        int CLdelete(CLType head,String key){
            CLType node,temp;
            temp =  head;
            node = head;
            while(temp != null){
                if(temp.nodeData.key.compareTo(key) == 0){//找到学号执行删除操作
                    node.nextNode =  temp.nextNode;
                    temp = null;
                    return 1;
                }
                else{
                    node = temp;
                    temp = temp.nextNode;
                }
            }
            return 0;
        }
        //得到链表长度
        int CLength(CLType head){
            CLType temp = head;
            int i = 0;
            while(temp != null){
                i++;
                temp = temp.nextNode;
            }
            return i;
        }
        //遍历所有结点
        void CLALL(CLType head){
            CLType temp;
            DATA nodeData;
            temp = head;
            while(temp != null){
                nodeData = temp.nodeData;
                System.out.printf("结点为%s,%s,%d\n",nodeData.key,nodeData.name,nodeData.age);
                temp = temp.nextNode;
            }
        }
    }
    public static void main(String[] args) {
        CLType node,head = null;
        CLType CL = new CLType();
        String key,findkey;
        Scanner input  = new Scanner(System.in);
        System.out.println("请输入链表中的数据,格式为:学号,姓名,年龄(以0结束)");
        do{
            DATA nodeData = new DATA();
            nodeData.key = input.next();
            if(nodeData.key.equals("0")){
                break;
            }
            else{
                nodeData.name = input.next();
                nodeData.age = input.nextInt();
                head = CL.CLAddend(head, nodeData);
                //head = CL.CLAddFirst(head, nodeData);
            }
        }while(true);
        //遍历
        CL.CLALL(head);

        System.out.println("请输入要查找的结点(输入学号)");
        findkey = input.next();
        System.out.println("该学号的名字为"+CL.CLFind(head, findkey).nodeData.name);

        //删除结点
        System.out.println("请输入要删除的学号:");
        findkey = input.next();
        CL.CLdelete(head, findkey);
        CL.CLALL(head);
        //得到表长
        System.out.println("表长为"+CL.CLength(head));
    }
}

代码运行结果

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值