4.4链表常规例题

1. 单向链表反转:查看4.2节

2. 查找链表的中间值

  // 通过快慢指针,按照1:2的比例,找到中间结点
  public  static  String getMid(Node<String> first){
        Node slow=first;
        Node fast=first;
        while (fast!=null && fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return (String) slow.item;
    }

3.判断链表中是否有环

      /**
         * 判断链表中是否有环
         * @param first 链表首结点
         * @return ture为有环,false为无环
         * 通过快慢指针,如果有环,一定会相遇
         */
    public static boolean isCircle(Node<String> first) {
        Node<String> slow = first;
        Node<String> fast = first;
        while(fast!=null && fast.next!=null) {
            fast = fast.next.next;
            slow = slow.next;
          if(fast.equals(slow)){
              return true;
          }
        }
        return false;
    }

4.查找有环链表中环的入口结点

/** 当快慢指针相遇时,我们可以判断到链表中有环,这时重新设定一个新指针指向链表的起点,且步长与慢指针一样为1,则慢指针与“新”指针相遇的地方就是环的入口。*/
    public static Node getEntrance(Node<String> first) {
        Node<String> slow = first;
        Node<String> fast = first;
        Node<String> temp = null;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow=slow.next;
            if (fast.equals(slow)){
                temp = first;
                continue;
            }
            if (temp!=null){
                temp=temp.next;
                if (temp.equals(slow)){
                    return temp;
                }
            }
        }
        return null;
    }

5.约瑟夫问题

       /**
         * 传说有这样一个故事,在罗马人占领乔塔帕特后,39 个犹太人与约瑟夫及他的朋友躲到一个洞中,39个犹太人决
         * 定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,第一个人从1开始报数,依次往
         * 后,如果有人报数到3,那么这个人就必须自杀,然后再由他的下一个人重新从1开始报数,直到所有人都自杀身亡
         * 为止。然而约瑟夫和他的朋友并不想遵从。于是,约瑟夫要他的朋友先假装遵从,他将朋友与自己安排在第16个与
         * 第31个位置,从而逃过了这场死亡游戏 。
         */
        Node first = null;
        //记录前一个结点
        Node<Integer> pre = null;
        for (int i = 1; i < 42; i++) {
            if (i == 1) {
                first = new Node(1, null);
                pre = first;
                continue;
            }
            Node node = new Node(i, null);
            pre.next = node;
            pre = pre.next;
            if (i == 41) {
                pre.next = first;
            }
        }
        int count = 0;
        Node<Integer> n = first;
        // 记录被删除的前一个结点
        Node<Integer> before = null;
        while (n != n.next) {
            count++;
            if (count == 3) {
                before.next=n.next;
                System.out.print(n.item+",");
                count=0;
                n=n.next;
            } else {
                before = n;
                n = n.next;
            }
        }
        System.out.println(n.item);
    }
// 打印结果: 3,6,9,12,15,18,21,24,27,30,33,36,39,1,5,10,14,19,23,28,32,37,41,7,13,20,26,34,40,8,17,29,38,11,25,2,22,4,35,16,31

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个C语言的双向循环链表例题: ```c #include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node* next; struct Node* prev; }; void insert(struct Node** head, int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; if (*head == NULL) { newNode->next = newNode; newNode->prev = newNode; *head = newNode; } else { struct Node* tail = (*head)->prev; newNode->next = *head; (*head)->prev = newNode; newNode->prev = tail; tail->next = newNode; } } void display(struct Node* head) { if (head == NULL) { printf("List is empty.\n"); return; } struct Node* current = head; do { printf("%d ", current->data); current = current->next; } while (current != head); printf("\n"); } int main() { struct Node* head = NULL; // 插入节点 insert(&head, 1); insert(&head, 2); insert(&head, 3); // 显示链表 display(head); return 0; } ``` 这个例题演示了如何创建并打印一个双向循环链表。首先,我们创建了一个结构体 `Node`,其中包含数据 `data`、下一个节点指针 `next` 和前一个节点指针 `prev`。然后,我们定义了一个插入函数 `insert`,用于将新节点插入到链表中。最后,我们定义了一个显示函数 `display`,用于打印链表中的所有节点。在 `main` 函数中,我们创建一个空链表,然后插入了三个节点,并使用 `display` 函数打印链表的内容。 这个例题只是对双向循环链表的基本操作进行了演示,你可以根据需要修改和扩展这个代码来实现更复杂的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [链表图解(双向、循环链表+链表增删)](https://blog.csdn.net/qq_52189899/article/details/121552785)[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_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值