Java实现单链表、栈、队列三种数据结构

开发 后端
本文介绍了单链表、栈、队列三种数据结构。一起来看看吧。

一、单链表

1、在我们数据结构中,单链表非常重要。它里面的数据元素是以结点为单位,每个结点是由数据元素的数据和下一个结点的地址组成,在java集合框架里面  LinkedList、HashMap(数组加链表)等等的底层都是用链表实现的。

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

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

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

(1),然后将第一个元素的next指向插入结点(2),

不用在挪动后面元素。

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

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

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

  1. package com.tlinkedList;  
  2. /**  
  3. * User:zhang  
  4. * Date:2020/10/26  
  5. **/  
  6. public class TLinkedList<T> {  
  7.   private Node head;//链表头部  
  8.   private int size;//链表元素的个数  
  9.   public TLinkedList(){  
  10.       head=null 
  11.       size=0 
  12.   }  
  13. //    将结点作为内部类。也可以新建一个Node类,作为结点  
  14.   class Node{  
  15.       private Node next;//下一个结点  
  16.       private T t;//结点的数据  
  17.       public Node(T t){  
  18.           tthis.t=t;  
  19.       }  
  20.       public T getT() {  
  21.           return t;  
  22.       }  
  23.       public void setT(T t) {  
  24.           tthis.t = t;  
  25.       }  
  26.   }  
  27. //    在链表头部添加一个结点  
  28.   public void addFirst(T t){  
  29.       Node node = new Node(t);  
  30.       node.next=head 
  31.       head=node 
  32.       size++;  
  33.   }  
  34. //    在链表中间添加一个结点  
  35.   public void addMid(T t,int index){  
  36.       Node node = new Node(t);  
  37.       Node mid=head 
  38.       for (int i = 0; i < index - 1; i++) {  
  39.           midmid=mid.next;  
  40.       }  
  41.       node.next=mid.next;  
  42.       mid.next=node 
  43.       size++;  
  44.   }  
  45. //    在链表尾部添加一个结点  
  46.   public void addLast(T t){  
  47.       Node node = new Node(t);  
  48.       Node last=head 
  49.       while (last.next!=null){  
  50.           lastlast=last.next;  
  51.       }  
  52.       last.next=node 
  53.       node.next=null 
  54.       size++;  
  55.   }  
  56. //    删除链表的头结点  
  57.   public void removeFirst(){  
  58.       headhead=head.next;  
  59.       size--;  
  60.   }  
  61. //    删除链表的中间元素  
  62.   public void removeMid(int index){  
  63.       Node mid=head 
  64.       if (index==0){  
  65.           removeFirst();  
  66.           return;  
  67.       }  
  68.       int j=0 
  69.       Node qMid=head 
  70.       while (j<index){  
  71.           qMid=mid 
  72.           midmid=mid.next;  
  73.           j++;  
  74.       }  
  75.       qMid.next=mid.next;  
  76.       size--;  
  77.   }  
  78. //    删除链表的尾结点  
  79.   public void removeLast(){  
  80.       Node mid=head 
  81.       Node qMid=head 
  82.       while (mid.next!=null){  
  83.            qMid=mid 
  84.            midmid=mid.next;  
  85.       }  
  86.       qMid.nextnull 
  87.       size--;  
  88.   }  
  89. //    获取链表指定下标的结点  
  90.   public Node get(int index){  
  91.       Node mid=head 
  92.       if (index==0){  
  93.           return head;  
  94.       }  
  95.       int j=0 
  96.       while (j<index){  
  97.           midmid=mid.next;  
  98.           j++;  
  99.       }  
  100.       return mid;  
  101.   }  
  102.   public static void main(String[] args) {  
  103.       TLinkedList<String> linkedList = new TLinkedList<>();  
  104.       linkedList.addFirst("hello1");  
  105.       linkedList.addFirst("hello2");  
  106.       linkedList.addFirst("hello3");  
  107.       for (int i = 0; i < linkedList.size; i++) {  
  108.           System.out.println(linkedList.get(i).getT());  
  109.       }  
  110. //        linkedList.removeLast();  
  111. //        linkedList.removeFirst();  
  112. //        linkedList.addLast("hello4");  
  113.       linkedList.addMid("hello",2);  
  114.       System.out.println("--------------");  
  115.       for (int i = 0; i < linkedList.size; i++) { 
  116.           System.out.println(linkedList.get(i).getT());  
  117.       }  
  118.   }  

结果如下:

二、栈(Stack)

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

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

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

  •  push(入栈):将一个数据元素从尾部插入
  •  pop(出栈):将一个数据元素从尾部删除
  •  peek(返回栈顶元素):将栈顶元素的数据返回

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

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

  1. package com.tStack;  
  2. /**  
  3. * User:zhang  
  4. * Date:2020/10/26  
  5. **/  
  6. public class Test_Stack<T> {  
  7.   private Node head;//栈的头结点  
  8.   private int size;//栈的元素个数  
  9.   class Node{  
  10.       private Node next;//下一个结点  
  11.       private T t;//结点的数据  
  12.       public Node(T t){  
  13.           tthis.t=t;  
  14.       }  
  15.       public T getT() {  
  16.           return t; 
  17.       }  
  18.       public void setT(T t) {  
  19.           tthis.t = t;  
  20.       }  
  21.   }  
  22.   public Test_Stack() {  
  23.       head=null 
  24.       size=0 
  25.   }  
  26.   public static void main(String[] args) {  
  27.       Test_Stack<String> TStack = new Test_Stack<>();  
  28.       TStack.push("hello1");  
  29.       TStack.push("hello2");  
  30.       TStack.push("hello3");  
  31.       for (int i = 0; i < 3; i++) {  
  32.           System.out.println(TStack.pop());  
  33.       }  
  34.   }  
  35. //    入栈  
  36.   public void push(T t){  
  37.       Node node = new Node(t);  
  38.       if (size==0){  
  39.           node.next=head 
  40.           head=node 
  41.           size++;  
  42.           return;  
  43.       }  
  44.       if (size==1){  
  45.           head.next=node 
  46.           node.next=null 
  47.           size++;  
  48.           return;  
  49.       }  
  50.       Node lastNode=head 
  51.       while (lastNode.next!=null){  
  52.            lastNodelastNode=lastNode.next;  
  53.       }  
  54.       lastNode.next=node 
  55.       node.next=null 
  56.       size++;  
  57.   }  
  58. //    出栈  
  59.   public T pop(){  
  60.       if (size==0){  
  61.           System.out.println("栈内无值");  
  62.           return null;  
  63.       }  
  64.       if (size==1){  
  65.           T t = head.getT();  
  66.           head=null 
  67.           size--;  
  68.           return t;  
  69.       }  
  70.       Node lastNode=head 
  71.       Node qNode=head 
  72.       while (lastNode.next!=null){  
  73.           qNode=lastNode 
  74.           lastNodelastNode=lastNode.next;  
  75.       }  
  76.       T t = lastNode.getT();  
  77.       qNode.next=null 
  78.       size--;  
  79.       return t;  
  80.   }  
  81. //    获取栈里面元素的个数  
  82.   public int getSize(){  
  83.       return size;  
  84.   }  
  85. //    返回栈顶元素  
  86.   public T peek(){  
  87.       if (size==0){  
  88.           System.out.println("栈内无值");  
  89.           return null;  
  90.       }  
  91.       if (size==1){  
  92.           return head.getT();  
  93.       }  
  94.       Node lastNode=head 
  95.       while (lastNode.next!=null){  
  96.           lastNodelastNode=lastNode.next;  
  97.       }  
  98.       return lastNode.getT();  
  99.   }  

结果:

三、队列(Queue)

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

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

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

  •  put(入队):将一个结点插入到尾部。
  •  pop(出队):将头结点的下一个结点作为头,然后将原来的头结点删除。

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

  1. package com.tQueue;  
  2. /**  
  3.  * User:zhang  
  4.  * Date:2020/10/26  
  5.  **/  
  6. public class TQueue<T> {  
  7.     private Node front;//头结点  
  8.     private Node tail;//尾结点  
  9.     private int size;//队列中元素的个数  
  10.     class Node {  
  11.         private Node next;//下一个结点  
  12.         private T t;//结点的数据  
  13.         public Node(T t) {  
  14.             tthis.t = t; 
  15.         }  
  16.         public T getT() {  
  17.             return t;  
  18.         }  
  19.         public void setT(T t) {  
  20.             tthis.t = t;  
  21.         }  
  22.     }  
  23.     public int getSize() {  
  24.         return size;  
  25.     }  
  26.     public void setSize(int size) {  
  27.         this.size = size;  
  28.     }  
  29.     public TQueue() {  
  30.         front = tail = null;  
  31.     }  
  32.     //    入队  
  33.     public void put(T t) {  
  34.         Node node = new Node(t);  
  35.         if (size == 0) {  
  36.             front = tail = node;  
  37.             size++;  
  38.             return; 
  39.          }  
  40.         Node lastNode = front 
  41.         while (lastNode.next != null) {  
  42.             lastNodelastNode = lastNode.next;  
  43.         }  
  44.         lastNode.next = node 
  45.         tail = node 
  46.         size++;  
  47.     }  
  48.     //    出队  
  49.     public T pop() {  
  50.         if (size == 0) {  
  51.             System.out.println("队列中无值");  
  52.             return null;  
  53.         }  
  54.         T t = front.getT();  
  55.         frontfront=front.next;  
  56.         size--;  
  57.         return t;  
  58.     }   
  59.     public static void main(String[] args) {  
  60.         TQueue<String> tQueue = new TQueue<>();  
  61.         tQueue.put("Hello1");  
  62.         tQueue.put("Hello2");  
  63.         tQueue.put("Hello3");  
  64.         for (int i = 0; i < 3; i++) {  
  65.             System.out.println(tQueue.pop());  
  66.         }  
  67.     }  

结果:

 

 

责任编辑:庞桂玉 来源: Java知音
相关推荐

2023-03-06 08:40:43

RedisListJava

2021-07-13 07:52:03

Python数据结构

2012-05-16 17:05:33

Java数据结构

2023-04-11 08:00:56

Redis类型编码

2020-12-17 10:12:33

数据结构算法队列

2012-02-02 10:21:05

单链表nexthead

2021-03-10 08:42:19

Java数据结构算法

2020-12-28 10:35:38

前端数据技术

2020-03-27 14:29:30

数据结构

2019-10-29 08:59:16

Redis底层数据

2021-08-03 10:24:59

数据跳跃链表结构

2010-09-26 16:31:13

随机查询语句

2011-04-11 11:23:17

队列数据结构

2023-09-06 13:16:00

数据库数据

2021-03-01 23:31:48

队列实现栈存储

2021-05-12 14:09:35

链表数据结构线性结构

2023-09-25 12:23:18

Python

2020-11-06 12:48:16

数据结构算法分析

2021-03-29 08:01:20

JavaScript数据结构

2016-01-27 10:25:31

数据分析数据架构数据价值
点赞
收藏

51CTO技术栈公众号