单链表反转(Singly Linked Lists in Java)

本文介绍了一种使用递归方法来反转单链表的实现方式。通过定义一个递归函数,该函数接受链表头节点作为参数,并返回反转后的链表头节点。此外,还提供了一个用于生成测试用例的辅助函数以及链表类的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package dsa.linkedlist;

public class Node<E>{
 E data;
 Node<E> next;
}
 
package dsa.linkedlist;

public class ReverseLinkedListRecursively {

	public static void main(String args[]) {
		ReverseLinkedListRecursively reverser = new ReverseLinkedListRecursively();
		SinglyLinkedList<Integer> originalList = reverser.getLabRatList(10);
		System.out.println("Original List : " + originalList.toString());
		originalList.start = reverser.reverse(originalList.start);
		System.out.println("Reversed List : " + originalList.toString());
	}

	public Node<Integer> reverse(Node<Integer> list) {
		if (list == null || list.next == null)
			return list;
		Node<Integer> nextItem = list.next;
		list.next = null;
		Node<Integer> reverseRest = reverse(nextItem);
		nextItem.next = list;
		return reverseRest;
	}

	private SinglyLinkedList<Integer> getLabRatList(int count) {
		SinglyLinkedList<Integer> sampleList = new SinglyLinkedList<Integer>();
		for (int i = 0; i < count; i++) {
			sampleList.add(i);
		}
		return sampleList;
	}
}
/*
 * SAMPLE OUTPUT Original List : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Reversed List : 9,
 * 8, 7, 6, 5, 4, 3, 2, 1, 0
 */
 
package dsa.linkedlist;

/**
 * This is a singly linked list with no prev pointer.
 * @author Braga
 * @param <E>
 */
public class SinglyLinkedList<E> {
 
 Node<E> start;
 int size;
 
 public SinglyLinkedList(){
  start = null;
  size = 0;
 }
 
 //insertAtLast
 public void add(E data){
  insertAtLast(data);
 }
 
 public void insertAtLast(E data){
  if(size==0){
   start = new Node<E>();
   start.next = null;
   start.data = data;
  }else{
   Node<E> currentNode = getNodeAt(size-1);
   Node<E> newNode = new Node<E>();
   newNode.data = data;
   newNode.next = null;
   currentNode.next = newNode;
  }
  size++;
 }
 
 public void insertAtFirst(E data){
  if(size==0){
   start = new Node<E>();
   start.next = null;
   start.data = data;
  }else{
   Node<E> newNode = new Node<E>();
   newNode.data = data;
   newNode.next = start;
   start = newNode;
  }
  size++;
 }
 
 public Node<E> getNodeAt(int nodePos) throws ArrayIndexOutOfBoundsException{
  if(nodePos>=size || nodePos<0){
   throw new ArrayIndexOutOfBoundsException();
  }
  Node<E> temp = start;//Move pointer to front
  int counter = 0;
  for(;counter<nodePos;counter++){
   temp = temp.next;
  }
  return temp;
 }
 
 public void insertAt(int position, E data){
  if(position == 0){
   insertAtFirst(data);
  }else if(position==size-1){
   insertAtLast(data);
  }else{
   Node<E> tempNode = getNodeAt(position-1);
   Node<E> newNode = new Node<E>();
   newNode.data = data;
   newNode.next = tempNode.next;
   tempNode.next = newNode;
   size++;
  }
 }
 
 public Node<E> getFirst(){
  return getNodeAt(0);
 }
 
 public Node<E> getLast(){
  return getNodeAt(size-1);
 }
 
 public E removeAtFirst(){
  if(size==0){
   throw new ArrayIndexOutOfBoundsException();
  }
  E data = start.data;
  start = start.next;
  size--;
  return data;
 }
 
 public E removeAtLast(){
  if(size==0){
   throw new ArrayIndexOutOfBoundsException();
  }
  Node<E> tempNode = getNodeAt(size-2);
  E data = tempNode.next.data;
  tempNode.next = null;
  size--;
  return data;
 }
 
 public E removeAt(int position){
  if(position==0){
   return removeAtFirst();
  }else if(position == size-1){
   return removeAtLast();
  }else{
   Node<E> tempNode = getNodeAt(position-1);
   E data = tempNode.next.data;
   tempNode.next = tempNode.next.next;
   size--;
   return data;
  }
 }
 
 public int size(){
  return size;
 }
 
 public String toString(){
  if(size==0){
   return "";
  }else{
   StringBuilder output = new StringBuilder();
   Node<E> tempNode = start;
   while(tempNode.next!=null){
    output.append(tempNode.data).append(", ");
    tempNode = tempNode.next;
   }
   output.append(tempNode.data);
   return output.toString();
  }
 }
 
}
<think>嗯,用户给了一段C语言的结构体定义,还附带了注释,想要了解这个看门狗定时器结构的内部表示。首先,我需要仔细看一下代码和注释内容。 结构体名字是wdog_s,看起来是用于看门狗定时器的。注释里提到要小心结构体的顺序,不能直接修改,因为它会和work_s结构体以联合体(union)的形式结合,而且工作队列在取消任务时会操作这个结构体。这说明这个结构体的布局非常重要,任何改动都可能影响到其他部分的代码,尤其是联合体的其他成员。 结构体成员包括next指针,指向下一个wdog_s,这可能用于链表管理。arg是回调函数的参数,func是到期时执行的函数。如果有CONFIG_PIC定义,还会有picbase,可能是位置无关代码相关的基地址。最后是lag,表示延迟的时间。 用户的需求是解析这段代码,可能需要解释每个成员的作用,以及结构体的使用场景和注意事项。因为用户提到系统级指令,需要确保回答结构清晰,用中文,并且正确使用LaTeX格式的数学表达式,不过这里可能不需要数学公式,但要注意技术术语的正确性。 可能需要强调结构体在联合体中的使用,这样不同的结构体可以共享同一块内存,但修改其中一个会影响另一个。因此,注释中的警告非常重要,不能随意调整成员顺序,否则会导致联合体中的其他结构出现错误。 还要解释看门狗定时器的作用,比如管理系统中的定时任务,超时处理等。成员变量如func是回调函数,arg是传递给它的参数,lag是定时的时间间隔。next指针可能用于将多个定时器组织成链表,方便管理。 此外,CONFIG_PIC的条件编译说明这个结构体在不同配置下可能有不同的内存布局,需要注意PIC(位置无关代码)的支持情况,picbase的作用可能是帮助定位函数地址。 最后,需要提醒开发者在使用这个结构体时遵循注意事项,避免直接修改结构体顺序,以免引发不可预见的错误,尤其是在工作队列操作时。</think>以下是对 `struct wdog_s` 的逐层解析: --- ### 一、结构体核心作用 此结构体是看门狗定时器(Watchdog Timer)的内部表示,用于管理系统中的定时任务。其设计需 `struct work_s` 通过**联合体(union)**共享内存,因此成员顺序不可随意修改。 --- ### 二、成员变量详解 1. **`FAR struct wdog_s *next`** - **作用**:单链表指针,用于将多个看门狗定时器组织成链表。 - **关键点**:`FAR` 可能表示远指针(内存分段架构下使用),用于访问不同内存段。 2. **`wdparm_t arg`** - **作用**:回调函数的参数,类型 `wdparm_t` 通常是 `void*` 或整型,用于传递上下文信息。 3. **`wdentry_t func`** - **作用**:定时器到期时执行的回调函数,类型 `wdentry_t` 定义类似: ```c typedef void (*wdentry_t)(wdparm_t arg); ``` 4. **`FAR void *picbase`** - **条件编译**:仅在 `CONFIG_PIC`(位置无关代码)启用时存在。 - **作用**:存储 PIC 基地址,确保回调函数在动态加载时能正确寻址。 5. **`sclock_t lag`** - **作用**:定时器的延迟时间,单位通常是系统时钟周期。 - **类型**:`sclock_t` 可能是有符号整型,支持超时值的正负计算。 --- ### 三、关键设计约束 1. **联合体兼容性** 此结构体 `struct work_s` 共用同一内存空间(通过 `union`),因此: - **成员顺序必须严格对齐**:若修改 `wdog_s` 的成员顺序,会导致 `work_s` 解析错误。 - **内存布局不可变**:外部代码(如 `kwork` 模块)依赖此布局进行链表操作(如 `wqueue` 的 `work_qcancel()`)。 2. **线程安全生命周期** - 看门狗定时器可能被中断上下文或任务上下文访问,需确保操作(如添加/删除)是原子的。 - 回调函数 `func` 应避免阻塞,否则可能影响其他定时任务。 --- ### 四、典型使用场景 ```c // 创建定时器 struct wdog_s mydog; mydog.func = my_callback; mydog.arg = (wdparm_t)&my_data; mydog.lag = 100; // 延迟 100 个时钟周期 // 添加到系统定时器队列 wd_start(&mydog); ``` --- ### 五、注意事项 1. **禁止直接修改成员顺序**:需考虑联合体 `union` 中 `work_s` 的依赖。 2. **PIC 兼容性**:若启用 `CONFIG_PIC`,需确保 `picbase` 正确初始化为模块加载地址。 3. **回调函数限制**:避免在 `func` 中执行耗时操作,防止阻塞定时器线程。 如有具体使用问题(如超时计算、链表操作),可进一步讨论!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值