假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,可共享相同的后缀存储空间,例如,“loading”,“being”的存储映像如下图所示。

在这里插入图片描述
假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,可共享相同的后缀存储空间,例如,“loading”,“being”的存储映像如下图所示。
设str1和str2分别指向两个单词所在单链表的头结点,链表结点结构为
data next
请设计一个时间上尽可能高效的算法,找出由str1和str2所指向两个链表共同后缀的起始位置(如图中字符i所在结点的位置p)

算法思想:

1.遍历两个单链表,分别计算出它们的长度。
2.如果两个链表的长度不相同,则将较长的那个链表的头指针往后移,使得两个链表剩余的长度相同。
3.同时遍历两个链表,比较节点是否相同,直至找到第一个相同的节点或遍历到链表的结尾。
4.输出或返回第一个相同节点的位置。

代码:(完整理解此题)

#include <stdio.h>
#include <stdlib.h>

struct ListNode {
    char data;
    struct ListNode* next;
};

struct ListNode* findCommonSuffix(struct ListNode* str1, struct ListNode* str2) {
    int len1 = getListLength(str1);
    int len2 = getListLength(str2);

    // 将较长链表的头指针向后移动,使得两个链表剩余的长度相等
    if (len1 > len2) {
        str1 = moveHead(str1, len1 - len2);
    } else if (len2 > len1) {
        str2 = moveHead(str2, len2 - len1);
    }

    // 同时遍历两个链表,比较节点是否相同
    while (str1 != NULL && str2 != NULL) {
        if (str1 == str2) {
            return str1; // 找到第一个相同的节点
        }
        str1 = str1->next;
        str2 = str2->next;
    }

    return NULL; // 没有找到共同后缀
}

// 获取链表的长度
int getListLength(struct ListNode* head) {
    int length = 0;
    while (head != NULL) {
        length++;
        head = head->next;
    }
    return length;
}

// 将链表的头指针向后移动指定步数
struct ListNode* moveHead(struct ListNode* head, int steps) {
    for (int i = 0; i < steps; i++) {
        head = head->next;
    }
    return head;
}

int main() {
    // 构建示例链表
    struct ListNode* node1 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node1->data = 'l';
    node1->next = NULL;
    struct ListNode* node2 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node2->data = 'o';
    node2->next = NULL;
    struct ListNode* node3 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node3->data = 'a';
    node3->next = NULL;
    struct ListNode* node4 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node4->data = 'd';
    node4->next = NULL;
    struct ListNode* node5 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node5->data = 'i';
    node5->next = NULL;
    struct ListNode* node6 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node6->data = 'n';
    node6->next = NULL;
    struct ListNode* node7 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node7->data = 'g';
    node7->next = NULL;

    // 构建链表结构
    node1->next = node2;
    node2->next = node3;
    node3->next = node4;
    node4->next = node5;
    node5->next = node6;
    node6->next = node7;

    struct ListNode* str1 = node1;

    // 构建示例链表
    struct ListNode* node8 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node8->data = 'b';
    node8->next = NULL;
    struct ListNode* node9 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node9->data = 'e';
    node9->next = NULL;
    struct ListNode* node10 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node10->data = 'i';
    node10->next = NULL;
    struct ListNode* node11 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node11->data = 'n';
    node11->next = NULL;
    struct ListNode* node12 = (struct ListNode*)malloc(sizeof(struct ListNode));
    node12->data = 'g';
    node12->next = NULL;

    // 构建链表结构
    node8->next = node9;
    node9->next = node10;
    node10->next = node11;
    node11->next = node12;

    struct ListNode* str2 = node8;

    // 调用函数查找共同后缀
    struct ListNode* commonSuffix = findCommonSuffix(str1, str2);

    if (commonSuffix != NULL) {
        printf("共同后缀的起始位置为:%c\n", commonSuffix->data);
    } else {
        printf("未找到共同后缀\n");
    }

    // 释放内存
    free(node1);
    free(node2);
    free(node3);
    free(node4);
    free(node5);
    free(node6);
    free(node7);
    free(node8);
    free(node9);
    free(node10);
    free(node11);
    free(node12);

    return 0;
}

{
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值