数据结构02-链表

说明:由于该数据结构是由java并且是原生实现,所以与C有一些出入,不过原理是相同的

1.链表的定义

    为了表示线性表元素a与a+1的逻辑关系,存储数据时,除了存储元素本身的信息之外,还存储了直接后继元素的位置信息。这两部分组成的数据元素被称为“结点”,一个结点分为两部分,存放数据元素信息的部分被称为数据域,

    存放直接后继元素位置的部分被称为指针域。

    单链表:结点指针域只存放直接后继元素位置的链表,也叫单向链表。

    双链表:结点指针域同时存放前驱元素和后继元素位置的链表,也叫双向链表。

    循环链表:一般的链表尾结点(最后一个结点)的指针域一般null,但是有的链表将最后一个节点的指针域指向头结点,构成一个环,称作循环链表。

    头结点: 一个链表的头节点,就是指针域指向该链表的第一个结点的结点,一般用来唯一确定一个链表(也有的链表是不带头结点的,那时我们通过链表的第一个结点来确定链表),注意:头结点的数据与是null

2.实现原理

    链表的每一个结点包括两部分,数据域和指针域,数据域用来存储数据,指针域用来存储后继结点的位置。

 1 class Link<T>{
 2     /**
 3     *用来存储数据
 4     */
 5     T data;
 6     /**
 7     *用来存储下一结点位置
 8      */
 9     Link next;
10 }

3.链表的基本操作

    1.初始化 init() 创建一个链表

    2.清空 clear() 清空一个链表

    3.销毁 destroy() 销毁链表

    4.在头部插入一个结点 insertFront()

    5.在尾部插入一个结点 insertBackend()

    6.在任意位置插入一个结点 insertIndex()

    7.删除任意位置元素 delete()

    8.查找元素 find()

    9.获取指定位置节点的值 get()

4.代码实现

  4.1链表代码实现

  1 package com.xiaobai.linelist;
  2 
  3 /**
  4  * @Author: xiaobai
  5  * @Date: 2019/5/1 9:00
  6  * @email:
  7  * @address:
  8  * @desc 模拟单链表操作
  9  * @Version 1.0
 10  */
 11 @SuppressWarnings("ALL")
 12 public final class Link<T> {
 13     /**
 14      * data 是要存储的数据
 15      */
 16     private T data;
 17     /**
 18      * next是下一结点的引用位置
 19      */
 20     public Link<T> next;
 21 
 22     /**
 23      * 初始化操作 构造方法返回一个空结点
 24      */
 25     public Link(){
 26         this.next = null;
 27         this.data = null;
 28     }
 29 
 30     /**
 31      * 构造一个新的链表结点
 32      * 新结点是没有后继结点的 所以直接null
 33      * @param data 数据
 34      */
 35     public Link(T data){
 36         this.data = data;
 37         this.next = null;
 38     }
 39 
 40     /**
 41      * 清空链表操作
 42      * @param link 要被清空的链表头节点
 43      */
 44     public void clear(){
 45         //让每一个结点的引用都为 null GC 自动回收
 46         Link<T> link = this;
 47         while(link.next!=null){
 48             Link curr = link.next;
 49             link.next = link.next.next;
 50             curr = null;
 51         }
 52         link = null;
 53     }
 54 
 55     /**
 56      * 销毁链表 这里的销毁和清空我认为没有什么区别,所以直接调用
 57      * 如果大家认为有区别的话,可以与我交流
 58      * @param link 被销毁的链表
 59      */
 60     public void destroy(){
 61         this.clear();
 62     }
 63 
 64     /**
 65      * 在链表的头部插入一个结点(默认是带头结点的链表)
 66      * @param head 链表的头节点
 67      * @param data 被插入的数据
 68      * @return 插入结果
 69      */
 70     public boolean insertFront(T data){
 71         //先构建一个新的结点
 72         Link<T> node = new Link<T>(data);
 73         try {
 74             //将结点插入到头部 即 新节点后继指向原来的第一个结点  头节点后继指向新节点
 75             node.next = this.next;
 76             this.next = node;
 77             return true;
 78         }catch (Exception e){
 79             e.printStackTrace();
 80             return false;
 81         }
 82     }
 83 
 84     /**
 85      * 在链表的尾部插入一个结点
 86      * @param head 链表头节点
 87      * @param data 要插入的数据
 88      * @return 插入结果
 89      */
 90     public boolean insertBackend(T data){
 91         //先构建一个新的结点
 92         try {
 93             Link<T> node = new Link<T>(data);
 94             //然后找到链表的尾
 95             Link<T> point = this.next;
 96             while(point.next!=null){
 97                 point = point.next;
 98             }
 99             //插入
100             point.next = node;
101             return true;
102         } catch (Exception e) {
103             e.printStackTrace();
104             return false;
105         }
106     }
107 
108     /**
109      * 在任意位置插入一个结点
110      * @param head 要插入的链表
111      * @param i  插入位置 从0开始
112      * @param data 插入的数据
113      * @return 插入结果
114      */
115     public boolean insertIndex(int i,T data){
116         Link curr = this.next;
117         //空链表 拒绝插入
118         if(null == curr && i > 0){
119             return false;
120         }
121         int count = 0;
122         //找到被插入的位置(要找被插入位置前一个)
123         while(count != i-1 && null != curr){
124             curr = curr.next;
125             count ++;
126         }
127         //如果循环提前结束 说明i值过大
128         if(count != i-1){
129             return false;
130         }
131         //开始插入节点
132         Link<T> node = new Link<T>(data);
133         node.next = curr.next;
134         curr.next = node;
135         return true;
136     }
137 
138     /**
139      * 删除任意位置元素
140      * @param i 被删除的位置  从0 开始
141      * @return 被删除的元素 删除失败返回null
142      */
143     public T delete(int i){
144         T del = null;
145         int count = 0;
146         Link<T> curr = this.next;
147         //找到被删除结点的前一个结点
148         while (curr != null&& count < i-1){
149             curr = curr.next;
150             count++;
151         }
152         //如果不满足条件 删除失败
153         if(count!=i-1){
154             return del;
155         }
156         //如果找到 执行删除操作 (GC 自动释放)
157         del = curr.next.data;
158         curr.next = curr.next.next;
159         return del;
160     }
161 
162     /**
163      * 查找元素是否存在  可能需要重写存储对象的equals方法
164      * @param data 被查找元素
165      * @return 查找结果
166      */
167     public boolean find(T data){
168         Link curr = this.next;
169         while(curr != null){
170             if(curr.data.equals(data)||curr.data ==data){
171                 return true;
172             }
173             curr = curr.next;
174         }
175         return false;
176     }
177 
178     /**
179      * 获取指定位置的元素
180      * @param i 位置
181      * @return 获取到的值 没有返回null
182      */
183     public T get(int i) {
184         T data = null;
185         Link<T> curr = this.next;
186         int count = 0;
187         while(count!=i && curr!=null){
188             curr = curr.next;
189             count ++;
190         }
191         if(count == i && curr!= null){
192             data = curr.data;
193         }
194         return data;
195     }
196 
197     @Override
198     public String toString() {
199         StringBuilder sb = new StringBuilder().append("HashCode = "+this.hashCode()).append(" {head -> ");
200         Link<T> curr = this.next;
201         while (curr!=null){
202             sb.append(curr.data+" -> ");
203             curr = curr.next;
204         }
205         sb.append(" null}");
206         return sb.toString();
207     }
208 }

 

  4.2  测试代码及结果

 1 /**
 2  * @Author: xiaobai
 3  * @Date: 2019/5/1 9:42
 4  * @email: 
 5  * @address:
 6  * @Version 1.0
 7  */
 8 public class TestLink {
 9     public static void main(String[] args) {
10         System.out.println("初始化链表");
11         Link<Integer> link = new Link<>();
12         System.out.println("当前链表: "+link);
13 
14         System.out.println("在前端插入一个元素 5");
15         link.insertFront(5);
16         System.out.println("当前链表: "+link);
17 
18         for(int i=1;i<=10;i++){
19             link.insertBackend(i);
20         }
21         System.out.println("依次从后端继续插入10个数后: "+link);
22 
23         link.insertIndex(3,100);
24         //索引从0开始
25         System.out.println("在第三个位置上插入100以后的链表 "+link);
26 
27         System.out.println("在第100个位置上插入0 "+link.insertIndex(100,0));
28 
29         System.out.println("删除第三个位置上的元素"+link.delete(3));
30         System.out.println(link);
31 
32         System.out.println("查找元素10的结果"+link.find(10));
33         System.out.println("查找元素100的结果"+link.find(100));
34 
35         System.out.println("获取第3个结点的值 "+link.get(3));
36         System.out.println("获取第999个结点的值 "+link.get(999));
37 
38         link.clear();
39         System.out.println("执行清空操作后的链表: "+link);
40 
41         link.destroy();
42 
43     }
44 }

      运行结果图:

 

转载于:https://www.cnblogs.com/xiaobai1202/p/10799114.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第四章 面向对象

第四章 面向对象 1. 基本格式 定义&#xff1a;当函数(业务功能)比较多&#xff0c;可以使用面向对象来进行归类&#xff0c;如果有一个凡事使用的公共值&#xff0c;也可以放到对象中 #格式&关键字 class 类名:def __inti__(self,x)self.x xdef 方法名(self,name):print(…

洛谷P2347 砝码称重 某一年noip提高组原题

可以转化为01背包求方案数的问题&#xff0c;dp数组f[][]表示第几个砝码能称出的重量,可压缩至一维 转移方程为f(i,j)f(i-1,j-w[i]) 当前我们可以称出的重量必定是由之前的砝码重量转移过来的 #include<bits/stdc.h> using namespace std; const int N550; const int max…

解决:-bash: unzip: command not found (Linux 中 unZip/Zip 的安装及使用)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Linux系统没有自带的压缩解压工具&#xff1b;需要我们自己安装&#xff1b; 当用到zip或者unzip如果没有安装就会出现 unzip: Command…

云计算时代IT专业人员需具备的10项技能

摘要&#xff1a;IT专业人员需要不断的学习&#xff0c;才能确保自己的工作能力跟上时代的步伐。云时代IT专业人员不仅需要具备一定的专业技能&#xff0c;比如快速运用自身知识快速在互联网上构建应用程序&#xff0c;还必须具备商业、金融、业务需求分析等等。 【编者按】谈…

java自定义注解学习笔记

注解学习笔记之自定义注解 Target&#xff08;{1,2,3,4,5,6,7}&#xff09; 1.ElementType.CONSTRUCTOR:用于描述构造器2.ElementType.FIELD:用于描述域3.ElementType.LOCAL_VARIABLE:用于描述局部变量4.ElementType.METHOD:用于描述方法5.ElementType.PACKAGE:用于描述包6.Ele…

[xsy3132]数表

题意&#xff1a;一个$n\times m$的数表&#xff0c;数值$\in[0,4)$&#xff0c;你可以任意次选择一行或一列$1,\text{mod }4$&#xff0c;要最小化所有数的和 因为$n\leq10$&#xff0c;所以数表可以看成$m$个$n$位$4$进制数$a_{1\cdots m}$&#xff0c;以下使用不进位加法 定…

linux 下载、安装 maven

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 创建maven的文件夹并下载maven的tar包到此文件夹中 //进入一个目录 cd /usr/local//创建一个文件夹 mkdir maven//下载maven的tar包…

ELK4之进阶学习

1.精确查找和模糊查找(term和match的区别) match经过分析(analyer)的, term是不经过分词,直接去倒排索引中查找精确的值. 2.建议器的简介(最左前缀或者自带的做) (1)直接用现成的 (2)不只是纠错,还有建议等等. (3)优点:用户体验,服务器减少请求(减少压力,太耗电了,热量太大) (4…

女人必知 教你认清6种隐性坏男人

周围不乏有女朋友喜欢历数往事、追忆曾擦肩而过的男人&#xff0c;有的说如果不是自己太苛求提早要见他家人引起反感&#xff0c;早就和心爱的人俪影双双甜蜜快乐了&#xff0c;还有的说暗恋的男生那一夜向他表露情感、她万分感动、可男生最后提出上床她拒绝了、因而错失了一段…

c# 编程学习(二)

2019独角兽企业重金招聘Python工程师标准>>> 标识符是对程序中的各个元素进行标识的名称。  只能使用字母(大写和小写)、数字和下划线  标识符必须以字母或下划线开头 变量是容纳值的存储位置。可将变量想象成容纳临时信息的容器 命名变量的建议&#xff1a; …

linux 中的 nohup 命令(设置后台进程): nohup: ignoring input and appending output to ‘nohup.out’

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、Linux 下使用 nohup Unix/Linux下一般比如想让某个程序在后台运行&#xff0c;很多都是使用 & 在程序结尾来让程序自动运行。 …

PowerDesigner表结构和字段大小写转换

原文&#xff1a;https://www.cnblogs.com/zhzhang/p/3946609.html 【转】PowerDesigner表结构和字段大小写转换 【转自】http://blog.csdn.net/xysh1991/article/details/8016192 使用方法&#xff1a;进入PowerDesigner&#xff0c;打开一个PDM&#xff0c;在菜单栏找到&…

解决:Could not find or load main class org.apache.rocketmq.example.quickstart.Producer

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1.情景描述 &#xff1a;我只是想安装运行 rocketmq&#xff0c;执行命令&#xff1a; sh bin/tools.sh org.apache.rocketmq.example.…

深入理解C++ 虚函数表

目录 深入理解C 虚函数表虚函数表概述单继承下的虚函数表派生类未覆盖基类虚函数派生类覆盖基类虚函数多继承下的虚函数表无虚函数覆盖派生类覆盖基类虚函数钻石型虚继承总结几个原则安全性问题深入理解C 虚函数表 ​ C中的虚函数的作用主要是实现了多态的机制。关于多态&#…

react-native-baidu-map使用及注意问题

使用组件&#xff1a; react-native-baidu-map 获取百度地图API_KEY 地址&#xff1a;lbsyun.baidu.com&#xff0c;在控制台成功创建应用后&#xff0c;就可以看到应用的api key了 安装 yarn add react-native-baidu-map 复制代码原生部分 Android配置 react-native link reac…

简单扫清身体垃圾

“我们的身体在被‘设计’之初&#xff0c;就拥有了自主扫除体内垃圾的功能。只不过&#xff0c;这需要我们按照正确的方法去激发它 。”美国畅销书作者乔斯卡曼和朱莉佩莱斯&#xff0c;在她们去年合著的《自我清洁》一书中强调了养成良好生活习惯可为身体排毒的重要性。 近日…

linux (阿里云 CentOS7) 中安装配置 RocketMQ

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 JDK1.8的安装&#xff1a; 1.检查系统的JDK版本 根目录下操作&#xff1a;cd java -version 2.检测JDK安装包 rpm -qa | grep ja…

Bootstrap简介

1.使用准备 1.1 Bootstrap的下载 http://www.bootcss.com&#xff0c;下载用于生产环境的Bootstrap即可。 1.2 Bootstrap包含的内容 ● 全局CSS&#xff1a;基本的 HTML 元素均可以通过 class 设置样式并得到增强效果&#xff1b;还有先进的栅格系统。 ● 组件&#xff1a;无数…

用TortoiseGit时的实用git命令

生成并获取 sshkey&#xff1a; ssh-keygen -t rsa -C "xxxxxxxxxx.com" cat ~/.ssh/id_rsa.pub 克隆仓库&#xff1a; git clone xxxxxx/xxx.git 重命名文件&#xff1a; mv file_name new_file_name git目录区分大小写&#xff1a; git config core.ignorecase fal…

有一种失败叫瞎忙

很多时候&#xff0c;我们都在不知不觉的瞎忙&#xff0c;为了避免这样的瞎忙&#xff0c;特为大家分享一个小的故事。 在一个山谷的禅房里有一位老禅师&#xff0c;他发现自己有一个徒弟非常勤奋&#xff0c;不管是去化缘&#xff0c;还是去厨房洗菜&#xff0c;这个徒弟从…