自定义链表,队列,栈

链表实现

  1. 在我们数据结构中,单链表非常重要。它里面的数据元素是以结点为单位,每个结点是由数据元素的数据和下一个结点的地址组成,在java集合框架里面
    LinkedList、HashMap(数组加链表)等等的底层都是用链表实现的。
  2. 下面是单链表的几个特点:
    数据元素在内存中存放的地址是不连续的:单链表的结点里面还定义一个结点,它里面保存着下一个结点的内存地址,在实例化对象的时候,jvm会开辟不同内存空间,并且是不连续的。
    添加效率高:添加一个元素时,先找到插入位置的前一个,只需要将1,2个元素的连接断开,将插入结点的next指向第一个元素的next(1),然后将第一个元素的next指向插入结点(2),
    不用在挪动后面元素
    在这里插入图片描述
    删除效率高:删除一个元素时,先找到删除位置,将前一个的next指向删除位置的next,不用在挪动后面元素
    在这里插入图片描述
    查询效率低:查询的时候必须从头开始,依次遍历,而数组因为它的内存是连续的,可以直接通过索引查找。
  3. 下面通过代码来实现单链表结构:
/**
 * @ClassName: TLinkedList
 * @Description: 构建单项链表
 * @author ENO
 * @date 2021年1月12日
 *
 * @param <T>
 */

public class TLinkedList<T> {
	// 链表头部
	private Node head;
	// 链表元素的个数
	private int size;

	public TLinkedList() {
		head = null;
		size = 0;
	}

	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;
		}
	}

	/**
	 * 
	 * @Title: addFirst
	 * @Description: 链表头部添加一个节点
	 * @param @param t
	 * @return void
	 * @throws
	 */
	public void addFirst(T t) {
		Node node = new Node(t);
		node.next = head;
		head = node;
		size++;
	}

	/**
	 * 
	 * @Title: addMid
	 * @Description: 在链表中间添加一个元素
	 * @param @param t
	 * @return void
	 * @throws
	 */
	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++;
	}

	/**
	 * 
	 * @Title: addLast
	 * @Description: 在链表尾部添加一个结点
	 * @param @param t
	 * @return void
	 * @throws
	 */
	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++;
	}

	/**
	 * 
	 * @Title: removeFirst
	 * @Description: 删除头部节点
	 * @param 
	 * @return void
	 * @throws
	 */
	public void removeFirst() {
		head = head.next;
		size--;
	}

	/**
	 * 
	 * @Title: removeMid
	 * @Description: 删除链表的中间元素
	 * @param @param index
	 * @return void
	 * @throws
	 */
	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--;
	}

	/**
	 * 
	 * @Title: removeLast
	 * @Description: 刪除尾部节点
	 * @param 
	 * @return void
	 * @throws
	 */
	public void removeLast() {
		Node mid = head;
		Node qMid = head;
		while (mid.next != null) {
			qMid = mid;
			mid = mid.next;
		}
		qMid.next = null;
		size--;
	}

	/**
	 * 
	 * @Title: get
	 * @Description: 获取链表指定下标的结点
	 * @param @param index
	 * @param @return
	 * @return Node
	 * @throws
	 */
	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. 下面通过链表结构实现栈结构:

public class TStack<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 TStack() {
		head = null;
		size = 0;
	}

	/**
	 * 
	 * @Title: push
	 * @Description: 入栈
	 * @param @param t
	 * @return void
	 * @throws
	 */
	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++;
	}

	/**
	 * 
	 * @Title: push
	 * @Description: 出栈
	 * @param @param t
	 * @return void
	 * @throws
	 */
	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;
	}

	/**
	 * 
	 * @Title: getSize
	 * @Description: 获取栈里面元素的个数
	 * @param @return
	 * @return int
	 * @throws
	 */
	public int getSize() {
		return size;
	}

	/**
	 * 
	 * @Title: peek
	 * @Description:  返回栈顶元素
	 * @param @return
	 * @return T
	 * @throws
	 */
	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();
	}
	
	public static void main(String[] args) {
		TStack<String> stack = new TStack<>();
		stack.push("hello1");
		stack.push("hello2");
		stack.push("hello3");
		System.out.println("-------");
		System.out.println(stack.pop());
		System.out.println(stack.pop());
		System.out.println(stack.pop());
	}
}

队列(Queue)

  1. 队列的特点也用“先进先出”四个字来概括。就是先进去的元素先输出出来。
    在这里插入图片描述
  2. 我们常见的消息队列就是队列结构实现的。
  3. 队列的常见操作如下:
    put(入队):将一个结点插入到尾部。
    pop(出队): 将头结点的下一个结点作为头,然后将原来的头结点删除。
  4. 通过链表结构实现队列:
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;
	}

	/**
	 * 
	 * @Title: put
	 * @Description: 入队
	 * @param @param t
	 * @return void
	 * @throws
	 */
	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++;
	}

	/**
	 * 
	 * @Title: pop
	 * @Description: 出队
	 * @param @return
	 * @return T
	 * @throws
	 */
	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());
		}
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值