一、单链表

1、在我们数据结构中,单链表非常重要。它里面的数据元素是以结点为单位,每个结点是由数据元素的数据和下一个结点的地址组成,在java集合框架里面

LinkedList、HashMap(数组加链表)等等的底层都是用链表实现的。

2、下面是单链表的几个特点:

数据元素在内存中存放的地址是不连续的:单链表的结点里面还定义一个结点,它里面保存着下一个结点的内存地址,在实例化对象的时候,jvm会开辟不同内存空间,并且是不连续的。

添加效率高:添加一个元素时,先找到插入位置的前一个,只需要将1,2个元素的连接断开,将插入结点的next指向第一个元素的next(1),然后将第一个元素的next指向插入结点(2),

不用在挪动后面元素。



删除效率高:删除一个元素时,先找到删除位置,将前一个的next指向删除位置的next,不用在挪动后面元素。



查询效率低:查询的时候必须从头开始,依次遍历,而数组因为它的内存是连续的,可以直接通过索引查找。

3、下面通过代码来实现单链表结构:

  package com.tlinkedList;

/**
* User:zhang
* Date:2020/10/26
**/
public class TLinkedList<T> {
private Node head;//链表头部
private int size;//链表元素的个数
public TLinkedList(){
head=null;
size=0;
}
// 将结点作为内部类。也可以新建一个Node类,作为结点
class Node{
private Node next;//下一个结点
private T t;//结点的数据
public Node(T t){
this.t=t;
} public T getT() {
return t;
} public void setT(T t) {
this.t = t;
}
}
// 在链表头部添加一个结点
public void addFirst(T t){
Node node = new Node(t);
node.next=head;
head=node;
size++;
}
// 在链表中间添加一个结点
public void addMid(T t,int index){
Node node = new Node(t);
Node mid=head;
for (int i = 0; i < index - 1; i++) {
mid=mid.next;
}
node.next=mid.next;
mid.next=node;
size++;
}
// 在链表尾部添加一个结点
public void addLast(T t){
Node node = new Node(t);
Node last=head;
while (last.next!=null){
last=last.next;
}
last.next=node;
node.next=null;
size++;
}
// 删除链表的头结点
public void removeFirst(){
head=head.next;
size--;
}
// 删除链表的中间元素
public void removeMid(int index){
Node mid=head;
if (index==0){
removeFirst();
return;
}
int j=0;
Node qMid=head;
while (j<index){
qMid=mid;
mid=mid.next;
j++;
}
qMid.next=mid.next;
size--;
}
// 删除链表的尾结点
public void removeLast(){
Node mid=head;
Node qMid=head;
while (mid.next!=null){
qMid=mid;
mid=mid.next;
}
qMid.next= null;
size--;
}
// 获取链表指定下标的结点
public Node get(int index){
Node mid=head;
if (index==0){
return head;
}
int j=0;
while (j<index){
mid=mid.next;
j++;
}
return mid;
}
public static void main(String[] args) {
TLinkedList<String> linkedList = new TLinkedList<>();
linkedList.addFirst("hello1");
linkedList.addFirst("hello2");
linkedList.addFirst("hello3");
for (int i = 0; i < linkedList.size; i++) {
System.out.println(linkedList.get(i).getT());
}
// linkedList.removeLast();
// linkedList.removeFirst();
// linkedList.addLast("hello4");
linkedList.addMid("hello",2);
System.out.println("--------------");
for (int i = 0; i < linkedList.size; i++) {
System.out.println(linkedList.get(i).getT());
}
}
}

结果如下:

二、栈(Stack)

1、一提到栈我们脑海就会浮现四个字“先进后出”,没错,它就是栈的最大特点。



2、栈的应用场景也非常多,比如将字符串反转、jvm里面的栈区等等。

3、栈里面的主要操作有:

push(入栈):将一个数据元素从尾部插入

pop(出栈):将一个数据元素从尾部删除

peek(返回栈顶元素):将栈顶元素的数据返回

相当于只有一个开口就是尾部,只能从尾进,从尾出。

4、下面通过链表结构实现栈结构:

package com.tStack;

/**
* User:zhang
* Date:2020/10/26
**/
public class Test_Stack<T> {
private Node head;//栈的头结点
private int size;//栈的元素个数
class Node{
private Node next;//下一个结点
private T t;//结点的数据
public Node(T t){
this.t=t;
} public T getT() {
return t;
} public void setT(T t) {
this.t = t;
}
} public Test_Stack() {
head=null;
size=0;
} public static void main(String[] args) {
Test_Stack<String> TStack = new Test_Stack<>();
TStack.push("hello1");
TStack.push("hello2");
TStack.push("hello3");
for (int i = 0; i < 3; i++) {
System.out.println(TStack.pop());
}
}
// 入栈
public void push(T t){
Node node = new Node(t);
if (size==0){
node.next=head;
head=node;
size++;
return;
}
if (size==1){
head.next=node;
node.next=null;
size++;
return;
}
Node lastNode=head;
while (lastNode.next!=null){
lastNode=lastNode.next;
}
lastNode.next=node;
node.next=null;
size++;
}
// 出栈
public T pop(){
if (size==0){
System.out.println("栈内无值");
return null;
}
if (size==1){
T t = head.getT();
head=null;
size--;
return t;
}
Node lastNode=head;
Node qNode=head;
while (lastNode.next!=null){
qNode=lastNode;
lastNode=lastNode.next;
}
T t = lastNode.getT();
qNode.next=null;
size--;
return t;
}
// 获取栈里面元素的个数
public int getSize(){
return size;
}
// 返回栈顶元素
public T peek(){
if (size==0){
System.out.println("栈内无值");
return null;
}
if (size==1){
return head.getT();
}
Node lastNode=head;
while (lastNode.next!=null){
lastNode=lastNode.next;
}
return lastNode.getT();
}
}

结果:

三、队列(Queue)

1、队列的特点也用“先进先出”四个字来概括。就是先进去的元素先输出出来。

2、我们常见的消息队列就是队列结构实现的。

3、队列的常见操作如下:

put(入队):将一个结点插入到尾部。

pop(出队): 将头结点的下一个结点作为头,然后将原来的头结点删除。

4、通过链表结构实现队列:

package com.tQueue;

/**
* User:zhang
* Date:2020/10/26
**/
public class TQueue<T> {
private Node front;//头结点
private Node tail;//尾结点
private int size;//队列中元素的个数
class Node {
private Node next;//下一个结点
private T t;//结点的数据 public Node(T t) {
this.t = t;
} public T getT() {
return t;
} public void setT(T t) {
this.t = t;
}
}
public int getSize() {
return size;
} public void setSize(int size) {
this.size = size;
} public TQueue() {
front = tail = null;
} // 入队
public void put(T t) {
Node node = new Node(t);
if (size == 0) {
front = tail = node;
size++;
return;
}
Node lastNode = front;
while (lastNode.next != null) {
lastNode = lastNode.next;
}
lastNode.next = node;
tail = node;
size++;
} // 出队
public T pop() {
if (size == 0) {
System.out.println("队列中无值");
return null;
}
T t = front.getT();
front=front.next;
size--;
return t;
} public static void main(String[] args) {
TQueue<String> tQueue = new TQueue<>();
tQueue.put("Hello1");
tQueue.put("Hello2");
tQueue.put("Hello3");
for (int i = 0; i < 3; i++) {
System.out.println(tQueue.pop());
}
}
}

结果:

文章有不足之处,欢迎大家留言指正,谢谢大家啦!

java实现单链表、栈、队列三种数据结构的更多相关文章

  1. 剑指offer—单链表反转的三种实现方法

    单链表的反转可以用递归.非递归和栈的方法实现 链表节点定义: struct ListNode{ int val; Node* next; ListNode(int x):val(x),next(nul ...

  2. Java实现单链表的各种操作

    Java实现单链表的各种操作 主要内容:1.单链表的基本操作 2.删除重复数据 3.找到倒数第k个元素   4.实现链表的反转   5.从尾到头输出链表 6.找到中间节点 7.检测链表是否有环 8.在 ...

  3. Java中获取键盘输入值的三种方法

    Java中获取键盘输入值的三种方法     Java程序开发过程中,需要从键盘获取输入值是常有的事,但Java它偏偏就没有像c语言给我们提供的scanf(),C++给我们提供的cin()获取键盘输入值 ...

  4. java实现单链表的增删功能

    JAVA 实现单链表的增删功能 package linked; class LinkedTable{ } public class LinkedTableTest { public static vo ...

  5. "《算法导论》之‘栈’":栈的三种实现(静态数组、动态数组及指针)

    本文有关栈的介绍部分参考自网站数据结构. 1. 栈  1.1 栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底( ...

  6. java Data、String、Long三种日期类型之间的相互转换

    java Data.String.Long三种日期类型之间的相互转换      // date类型转换为String类型   // formatType格式为yyyy-MM-dd HH:mm:ss// ...

  7. Java反射获取class对象的三种方式,反射创建对象的两种方式

    Java反射获取class对象的三种方式,反射创建对象的两种方式 1.获取Class对象 在 Java API 中,提供了获取 Class 类对象的三种方法: 第一种,使用 Class.forName ...

  8. 使用java实现单链表(转载自:https://www.cnblogs.com/zhongyimeng/p/9945332.html)

    使用java实现单链表----(java中的引用就是指针)转载自:https://www.cnblogs.com/zhongyimeng/p/9945332.html ? 1 2 3 4 5 6 7 ...

  9. java实现单链表常见操作

    一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...

随机推荐

  1. 关于windows服务器wsus客户端配置的修改

    本文环境如下: 服务器:Windows Server 2012 R2 Standard 由于公司服务器是加了域环境的,又需要将wsus客户端指向另一台wsus服务器,修改本地组策略.可能会被域控给修改 ...

  2. 纯粹极简的react状态管理组件unstated

    简介 unstated是一个极简的状态管理组件 看它的简介:State so simple, it goes without saying 对比 对比redux: 更加灵活(相对的缺点是缺少规则,需要 ...

  3. 中心极限定理(为什么y服从高斯分布)

    因为每一条数据都服从IID原则: 根据中心极限定理,当数据增加的时候,样本均值的分布慢慢变成正态分布 不管分布式什么分布,累加起来都是高斯分布 As sum increases, sum of non ...

  4. 实验一 使用sklearn的决策树实现iris鸢尾花数据集的分类

    使用sklearn的决策树实现iris鸢尾花数据集的分类 要求: 建立分类模型,至少包含4个剪枝参数:max_depth.min_samples_leaf .min_samples_split.max ...

  5. C++逐字输出函数

    void fun(string a) { for(int i=0;i<a.length();i++) { cout<<a[i]; usleep(10000); } cout<& ...

  6. 商品现货数据不好拿?商品季节性难跟踪?一键解决没烦恼的Python爬虫分享

    更多精彩内容,欢迎关注公众号:数量技术宅.探讨数据分析.量化投资问题,请加技术宅微信:sljsz01 季节性在大宗商品的交易中至关重要 大宗商品交易中,特别是在期货市场,由于商品价格周期的存在,季节性 ...

  7. 023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之——自增自减运算符

    023 01 Android 零基础入门 01 Java基础语法 03 Java运算符 03 算术运算符之--自增自减运算符 本文知识点:Java算术运算符中的自增自减运算符 自增自减运算符 之前我们 ...

  8. C++中的In 和 Out用法

    参考:https://zhidao.baidu.com/question/541219383.html In 这是一个宏,它的实际意义就是告诉你,这个变量或参数是输入值,即你必须给这个变量填写好以后提 ...

  9. JavaFX ComboBox的选中事项

    参考1:https://blog.csdn.net/mexel310/article/details/37909205 参考2:https://blog.csdn.net/maosijunzi/art ...

  10. Win10安装MongoDB

    1. 下载安装包:mongodb-win32-x86_64-2012plus-4.2.7-signed.msi 2. 安装,注意选择安装目录 3. 新建配置文件mongo.conf: ​``` #数据 ...