动手自定义一个String双向链表

什么是双向链表?由多个节点组成的存储结构,每个节点包含三部分,头指针、数据、尾指针。通过头指针和尾指针我们可以找到存储在不同位置的相邻节点。
我们先自定义一个节点类:

class Node {
	String data;//存放的字符串
	Node front;//头指针
	Node next;//尾指针

	// 重写构造方法
	public Node(String data) {
		this.data = data;
	}
}

 然后定义一个链表类,联系我们熟悉的集合知道,集合在内存中不是连续的,使用他一定需要知道头节点,操作链表也经常用到尾节点,链表大小。链表一般有 添加,删除,取值,修改的方法。代码如下:

public class LinkList {

	private Node fail;// 用来保存尾节点
	private Node head;// 用来保存头节点
	private int count = 0;//用来统计元素数量

	// 1.在链表后面添加节点数据
	public void add(String data) {}
	// 2.向链表指定索引位置插入值
	public void add(int index, String data) {}
	// 3.移除指定索引元素
	public void remove(int index) {}
	// 4.修改节点数据
	public void set(int index, String newData) {

	// 5.显示链表长度
	public int size() {}
	// 6.得到指定索引位置字符串
	public String get(int index) {}

	//自定义的一个工具方法,用于根据索引找节点
	private Node getOneNode(int index) {}

}

 以上就是我们要准备一些工具,和要实现功能的规划
1.在链表后面添加节点数据。
  如何将一个String字符串存入链表?向链表添加数据成功了,我们肯定可以通过遍历链表的方式找到他,如

何遍历?通过每个节点的指针我们可以找到下一个节点。反过来看,我们要向链表存储数据需要第一:我们需要先将字符串封装到一个Node对象里面,第二:将它与链表里的其他节点发生联系,即让最后一个节点指向该节点。注意如果链表为空,这个添加的节点就是这个链表的头,也是尾,但他的头指针,尾指针都为空。实现代码如下:

// 在后面添加节点数据
	public void add(String data) {
		Node n = new Node(data);
		// 没有头就没有尾,所以先检查是否有头节点
		// 注意 节点有3部分,除非 头尾指针指向null否则不要漏掉
		if (head == null) {
			head = n;
		} else {
			// 将尾节点的尾指针指向新节点
			fail.next = n;
			//将新节点的头指针指向尾节点
			n.front = fail;
		}
		//注意:每操作一次链表他的头尾指针,大小都有可能变化,一定要记得!
		//如果头存在,节点就是尾
		fail = n;
		count++;
	}

 2.向链表指定索引位置插入值
 向链表指定位置插入值我们需要,第一:先找到索引位对应的节点,由于根据索引找节点会经常用到,所以我把他提取成了一个方法,代码如下:

// 得到链表指定节点
	private Node getOneNode(int index) {
		//从第一个位置开始计数
		int sum = 0;
		//索引位节点必须存在
		if (index < 0 || index >= size()) {
			throw new RuntimeException("指定下边越界!");
		}
		//从第一个节点开始遍历查找到索引位
		Node n = head;
		while (sum < index) {
			n = n.next;
			sum++;
			// System.out.println("得到元素:"+n+","+sum);
		}
		return n;

	}

 第二,我们要将该索引位节点前一个节点尾指针指向新节点,索引位头指针指向新节点。注意如果索引位节点比较特殊,是头节点,将新节点做为头节点,以前的头节点的头指针指向该节点即可。

// 向链表指定索引位置添加插入值
	public void add(int index, String data) {
		// 先找到索引位节点,将新节点接到索引位节点的前一个节点n0的后面,在将新节点接到索

引位节点的前面
		Node n = getOneNode(index);
		// 得到索引位前一个节点
		Node n0 = n.front;
		// 创建新节点
		Node newNode = new Node(data);
		// 如果n为头,新节点为头
		if (n0 == null) {
			//head是全局变量,记得重置
			head = newNode;
		} else {
			//新节点的头指针指向前一个节点
			newNode.front=n0;
			//前一个节点的尾指针指向新节点
			n0.next = newNode;
			
		}
		//将索引位节点头指针指向新节点
		n.front = newNode;
		// 将新节点属性补齐!
		newNode.next = n;
		// 链表长度加一,切记!
		count++;
	}

 3.移除指定的索引元素
怎么移除元素?我们知道元素移除节点后我们遍历链表是找不到它的,为什么找不到呢?因为链表节点没有节点是指向他的,我们就找不到他了。所以,移除节点指向将指向他的指针,指向别的位置。
步骤:和向指定位置插入数据类似,我们需要这么做:第一,先找到索引位对应的节点,通过调用我们前面已

经写好的工具方法即可做到。第二,将索引位节点的前一个节点指向后一个节点,注意考虑特殊情况。头节点

没有前一个节点,我们移除他只需将索引位后一个节点设为头节点,将头指针指向空;尾节点没有后一个节点

,我们只需将索引位前一个节点尾指针指向null,将其设为尾节点。代码如下:

// 移除指定索引元素
	public void remove(int index) {
		Node n = getOneNode(index);
		// 除了头和尾 将该节点的前一个节点与他的后一个节点连起来
		Node n0 = n.front;
		Node n2 = n.next;

		if (n0 == null) {
			//前一个节点为空,即索引位节点为头节点
			n2.front = null;
			head = n2;
		} else if (n2 == null) {
			//后一个节点为空,即索引位为尾节点
			n0.next = null;
			fail = n0;
		} else {
			//中间节点将索引位前一个节点与后一个节点连起来即可
			n0.next = n2;
			n2.front = n0;
		}
		// 链表长度减1
		count--;
	}

 4.修改节点数据
步骤:第一,找到索引对应的节点;第二,修改该节点数据。代码如下:

// 修改节点数据
	public void set(int index, String newData) {
		// 先找到指定索引位置的节点
		Node n = getOneNode(index);
		//将该节点的数据修改即可
		n.data=newData;
	}

 5.显示链表长度
时时查看count的值即可。代码如下:

// 显示链表长度
	public int size() {
		return count;
	}

 6.得到指定索引位置字符串。
步骤:第一,先找到索引位对应的节点;第二,取出节点属性。代码如下:

// 得到指定索引位置字符串
	public String get(int index) {
		String s = getOneNode(index).data;
		return s;
	}

 

在Java中,我们可以自定义双向链表来实现一些特定的需求。双向链表是一种数据结构,它的每个节点都包含一个指向前一个节点和后一个节点的指针。这使得在双向链表中进行插入和删除操作非常高效,因为只需要修改前后节点的指针就可以完成。另外,访问节点可能会比较慢,因为需要从第一个节点开始遍历表。但是,Java的LinkedList类提供了丰富的方法,可以模拟式队列、式堆栈等数据结构,为用户提供了极大的方便。 下面是一个简单的自定义双向链表的Java代码示例: ```java // 定义节点类 class HeroNode2 { public int no; public String name; public String nickname; public HeroNode2 next; // 指向下一个节点,默认为null public HeroNode2 pre; // 指向上一个节点,默认为null // 构造器 public HeroNode2(int no, String name, String nickname) { this.no = no; this.name = name; this.nickname = nickname; } @Override public String toString() { return "HeroNode2{" + "no=" + no + ", name='" + name + '\'' + ", nickname='" + nickname + '\'' + '}'; } } // 自定义双向链表类 class DoubleLinkedList { private HeroNode2 head; // 头节点 // 构造器 public DoubleLinkedList() { head = new HeroNode2(0, "", ""); } // 在表尾部添加节点 public void add(HeroNode2 node) { HeroNode2 temp = head; while (temp.next != null) { temp = temp.next; } temp.next = node; node.pre = temp; } // 遍历表 public void display() { HeroNode2 temp = head.next; while (temp != null) { System.out.println(temp); temp = temp.next; } } // 在某个节点后面插入新节点 public void insertAfter(HeroNode2 newNode, HeroNode2 afterNode) { HeroNode2 temp = head; while (temp != null) { if (temp == afterNode) { newNode.next = temp.next; if (temp.next != null) { temp.next.pre = newNode; } newNode.pre = temp; temp.next = newNode; break; } temp = temp.next; } } // 删除某个节点 public void delete(HeroNode2 node) { HeroNode2 temp = head; while (temp != null) { if (temp == node) { temp.pre.next = temp.next; if (temp.next != null) { temp.next.pre = temp.pre; } break; } temp = temp.next; } } } ``` 以上是一个简单的自定义双向链表的实现。你可以根据需要添加其他方法或功能来满足具体需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Java双向链表的实现](https://download.csdn.net/download/weixin_38669628/11056304)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Java 自定义双向链表](https://blog.csdn.net/ana35287/article/details/102111857)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Java实现双向链表](https://blog.csdn.net/m0_63732435/article/details/127195219)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值