设以不带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针。编写相应的入队和出队程序。
Java
package com.programmercarl.linkedlist.homework;
import lombok.AllArgsConstructor;
import lombok.Builder;
/**
* @ClassName ListNode
* @Descriotion 单链表的结点
* @Author nitaotao
* @Date 2022/5/2 17:24
* @Version 1.0
**/
@AllArgsConstructor
@Builder
public class ListNode {
/**
* 结点的值
*/
public Integer val;
/**
* 下一个结点
*/
public ListNode next;
/**
* 无参构造
*/
public ListNode() {
}
/**
* 带参构造 1
*/
public ListNode(int val) {
this.val = val;
}
/**
* 带参构造 2
*/
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
@Override
public String toString() {
ListNode cur = this;
while (cur.next != null&&cur.next!=this) {
System.out.print(cur.val+" ");
cur=cur.next;
}
System.out.println(cur.val);
return null;
}
}
package com.programmercarl.linkedlist.homework;
/**
* @ClassName Queue
* @Descriotion TODO
* @Author nitaotao
* @Date 2022/5/5 16:20
* @Version 1.0
**/
public class Queue {
public static void main(String[] args) {
ListNode node5 = ListNode.builder().val(5).build();
ListNode node4 = ListNode.builder().val(4).next(node5).build();
ListNode node3 = ListNode.builder().val(3).next(node4).build();
ListNode node2 = ListNode.builder().val(2).next(node3).build();
ListNode node1 = ListNode.builder().val(1).next(node2).build();
node5.next = node1;
ListNode node6 = ListNode.builder().val(6).build();
put(node5, node6);
System.out.println(node1);
pop(node6, node3);
System.out.println(node1);
}
/**
* 入队
*
* @param targetQueueEnd 队尾指针
* @param node
*/
public static void put(ListNode targetQueueEnd, ListNode node) {
//先加入新结点
node.next = targetQueueEnd.next;
//再断开原结点
targetQueueEnd.next = node;
}
/**
* 出队
*
* @param targetQueueEnd 队尾指针
* @param node
* @return
*/
public static void pop(ListNode targetQueueEnd, ListNode node) {
//当前指针
ListNode cur = targetQueueEnd.next;
if (cur.val == node.val) {
targetQueueEnd.next = targetQueueEnd.next.next;
return;
}
while (targetQueueEnd != cur) {
if (cur.next.val.equals(node.val)) {
//断开连接
cur.next = cur.next.next;
return;
}
cur = cur.next;
}
}
}
C实现
//
// Created by nitaotao on 2022/5/8.
//
#include <malloc.h>
#include <stdio.h>
//单链表的就地逆置
//定义结点
typedef struct ListNode {
int val;
struct ListNode *next;
} Node, *ListNode;
/**
* 入队
*
* @param targetQueueEnd 指向目标队列的尾部
* @param node
*/
void put(ListNode targetQueueEnd, ListNode node) {
//先加入新结点
node->next = targetQueueEnd->next;
//再断开原结点
targetQueueEnd->next = node;
}
/**
* 出队
*
* @param targetQueueEnd 指向目标队列的尾部
* @return
*/
void pop(ListNode targetQueueEnd) {
//因为是循环队列,尾结点下一个就是头结点
// 如果当前队列只有一个元素
if (targetQueueEnd->next == NULL) {
targetQueueEnd = NULL;
} else if (targetQueueEnd->next->next == NULL) {
//只有两个元素
targetQueueEnd->next = NULL;
} else {
targetQueueEnd->next = targetQueueEnd->next->next;
}
}
void showPoint(ListNode node) {
ListNode cur = node;
//循环链表遍历时不可以直接在原指针上操作。需要虚拟指向指针
while (cur->next != NULL && cur->next != node) {
printf("%d", cur->val);
cur = cur->next;
}
//当没有下一个元素了
printf("%d\n", cur->val);
}
int main() {
ListNode node5 = (ListNode) malloc(sizeof(ListNode));
node5->val = 5;
node5->next = NULL;
ListNode node4 = (ListNode) malloc(sizeof(ListNode));
node4->val = 4;
node4->next = node5;
ListNode node3 = (ListNode) malloc(sizeof(ListNode));
node3->val = 3;
node3->next = node4;
ListNode node2 = (ListNode) malloc(sizeof(ListNode));
node2->val = 2;
node2->next = node3;
ListNode node1 = (ListNode) malloc(sizeof(ListNode));
node1->val = 1;
node1->next = node2;
//循环队列
node5->next = node1;
ListNode node6 = (ListNode) malloc(sizeof(ListNode));
node6->val = 6;
printf("%s", "原指针序列:");
showPoint(node1);
//node5为队尾
put(node5, node6);
printf("%s", "加入结点后指针序列:");
showPoint(node1);
//node6为队尾
pop(node6);
printf("%s", "弹出结点后后指针序列:");
showPoint(node2);
return 0;
}