范范 2020-10-28
一、单链表
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){ tthis.t=t; } public T getT() { return t; } public void setT(T t) { tthis.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++) { midmid=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){ lastlast=last.next; } last.next=node; node.next=null; size++; } // 删除链表的头结点 public void removeFirst(){ headhead=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; midmid=mid.next; j++; } qMid.next=mid.next; size--; } // 删除链表的尾结点 public void removeLast(){ Node mid=head; Node qMid=head; while (mid.next!=null){ qMid=mid; midmid=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){ midmid=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、栈里面的主要操作有:
相当于只有一个开口就是尾部,只能从尾进,从尾出。
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){ tthis.t=t; } public T getT() { return t; } public void setT(T t) { tthis.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){ lastNodelastNode=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; lastNodelastNode=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){ lastNodelastNode=lastNode.next; } return lastNode.getT(); } }
结果:
三、队列(Queue)
1、队列的特点也用“先进先出”四个字来概括。就是先进去的元素先输出出来。
2、我们常见的消息队列就是队列结构实现的。
3、队列的常见操作如下:
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) { tthis.t = t; } public T getT() { return t; } public void setT(T t) { tthis.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) { lastNodelastNode = lastNode.next; } lastNode.next = node; tail = node; size++; } // 出队 public T pop() { if (size == 0) { System.out.println("队列中无值"); return null; } T t = front.getT(); frontfront=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()); } } }