java实现带头结点的单链表的插入、删除、求长度

前段时间知乎面试,面试官出了一道题目实现单链表的插入、删除、计算长度,当时勉强写出来了,但是不是用的面向对象的思路写的,面试官叫我改成面向对象的方式。当时突然想到AQS的底层实现方式,就想仿照改一下。结果面试官说时间原因,就不写了。。。。。

AQS里面有一个头结点head和一个尾节点tail,刚开始head和tail都是没有初始化的,后面第一个进入阻塞对的第一个节点会在enq方法中初始化head,AQS中阻塞队列是不算head节点,head节点可以理解为当前拥有锁的节点。想了解更多的可以去看看AQS和ReentrantLock的源码。

思想我们也可以借鉴AQS,实现一个带头结点的单链表(注意头结点是不算在链表中),具体的代码如下:

package cn.cqupt.linked;

class Node {
	int data;
	Node next;

	Node() {
	}

	Node(int data) {
		this.data = data;
		this.next = null;
	}
}

public class LinkedOp {
	// 头结点
	private  Node head;
	// 链表的长度
	private  int size;
	
	// 构造函数初始化头结点,也可以在插入第一个节点的时候初始化
	LinkedOp(){
		head = new Node();
	}
	// 头插法
	public void insertFromHead(int data){
		// 将data封装为Node节点
		Node node = new Node(data);
		// 如果链表为空,直接跟在head后面
		if(head.next == null){
			head.next = node;
			size++;
		}else{
			// 链表不为空,头插法插入节点
			node.next = head.next;
			head.next = node;
			size++;
		}
	}
	// 尾插法
	public void insertFromLast(int data) {
		Node node = new Node(data);
		if (head.next == null) {
			head.next = node;
			size++;
		} else {
			// 这里要注意的是,while的判断是current.next是否为空
			// 意思 就是current最后肯定是指向链表的最后一个节点
			Node current = head.next;
			while (current.next != null) {
				current = current.next;
			}
			// 直接跟到最后
			current.next = node;
			// 长度+1
			size++;
		}
	}
	// 获取链表长度
	public int getSize(){
		return size;
	}
	// 删除节点
	public void remove(int data) {
		if (head.next == null){
			System.out.println("当前链表为空");
			return;
		}
		Node current = head;
		while (current.next != null) {
			if(current.next.data == data){
//				current.next = current.next.next;
				Node removeNode = current.next;
				current.next = removeNode.next;
				removeNode = null;//help GC
				size--;
				return;
			}else{
				current = current.next;
			}
		}
		if(current.next == null){
			System.out.println("该链表中没有这个节点");
		}
	}
	// 删除指定下标的节点
	public void removeIndex(int index){
		if(index < 0 || index > size){
			System.out.println("请输入正确的下标");
			return;
		}
		if (head.next == null){
			System.out.println("当前链表为空");
			return;
		}
		int startIndex = 1;
		Node current = head;
		while(current.next != null && startIndex < index){
			current = current.next;
			startIndex++;
		}
		// 删除节点
		Node removeNode = current.next;
		current.next = removeNode.next;
		removeNode = null;//help GC
		size--;
	}
	// 遍历链表
	public void printNode() {
		if (head.next == null) {
			System.out.println("链表为空!");
			return;
		}
		Node current = head.next;
		while (current.next != null) {
			System.out.print(current.data + "--->");
			current = current.next;
		}
		System.out.println(current.data);
		System.out.println("链表长度为:"+size);
	}
	
	public static void main(String[] args) {
		// 创建一个链表对象,创建时候会初始化头结点
		LinkedOp link = new LinkedOp();
		// 先打印链表
		link.printNode();
		// 头插法插入1、2
		link.insertFromHead(1);
		link.insertFromHead(2);
		
		// 尾插法插入3、4
		link.insertFromLast(3);
		link.insertFromLast(4);
		
		// 打印链表
		link.printNode();
		//System.out.println(link.getSize());
		// 删除节点为4的
		link.remove(4);
		link.printNode();
		// 删除第二个节点,节点从1开始
		link.removeIndex(2);
		link.printNode();
	}
}

java实现带头结点的单链表的插入、删除、求长度_第1张图片

你可能感兴趣的:(数据结构)