当前位置: 首页 > wzjs >正文

浙江建设网官网武汉seo关键词排名

浙江建设网官网,武汉seo关键词排名,安徽政府网站建设,布吉做网站公司目录 链表的基本结构 尾插法建立链表 打印链表 找到链表中间节点 原地逆置链表 合并两个链表 主函数 示例运行 输出示例 总结 关键点回顾 在数据结构的学习中,链表是一种非常重要的线性结构。它的动态特性使得在插入和删除操作时比数组更为高效。今天&a…

目录

链表的基本结构

尾插法建立链表

打印链表

找到链表中间节点 

原地逆置链表

合并两个链表

主函数

示例运行

输出示例

总结

关键点回顾


在数据结构的学习中,链表是一种非常重要的线性结构。它的动态特性使得在插入和删除操作时比数组更为高效。今天,我们将探讨如何在链表中找到中间节点,并将链表的后半部分逆置后与前半部分合并。通过这篇博客,你将更深入地理解链表的实现和操作。

链表的基本结构

在C语言中,链表的基本结构由节点(Node)构成,每个节点包含数据部分和指向下一个节点的指针。我们首先定义一个链表节点的结构体:

typedef int ElemType;typedef struct node {int data;struct node *next;
} Node;

这里,Node结构体包含了数据和指向下一个节点的指针。

尾插法建立链表

我们使用尾插法来创建链表。以下是尾插法的实现:

void list_tail_insert(Node *&L) {L = (Node *) malloc(sizeof(Node));L->next = NULL;ElemType x;scanf("%d", &x);Node *s, *r = L; // s 用来指向申请的新结点 r 始终指向链表尾部while (x != 9999) {s = (Node *) malloc(sizeof(Node)); // 为新结点申请空间s->data = x;r->next = s; // 新结点给尾结点的next指针r = s; // r 要指向新的尾部scanf("%d", &x);}r->next = NULL; // 让尾结点的 next 为 Null
}

在这个函数中,我们创建一个头节点,并通过循环读取用户输入的数据,直到输入9999为止。每次读取到一个新数据时,我们都会创建一个新节点,并将其插入到链表的尾部。

打印链表

为了验证我们的链表操作是否成功,我们需要一个函数来打印链表的内容:

void print_list(Node *L) {L = L->next; // 跳过头结点while (L != NULL) {printf("%d ", L->data);L = L->next;}printf("\n");
}

这个函数从头节点的下一个节点开始遍历链表,打印每个节点的数据。 

找到链表中间节点 

我们实现了一个函数来找到链表的中间节点,并将后半部分链表设置为新的链表L2: 

void find_middle(Node *L, Node *&L2) {L2 = (Node *) malloc(sizeof(Node)); // 第二条链表的头节点Node *p_cur, *p_pre; // 双指针法p_pre = p_cur = L->next;while (p_cur) {p_cur = p_cur->next;if (NULL == p_cur) {break;}p_cur = p_cur->next;if (NULL == p_cur) { // 为了使得偶数个 p_pre 依然指向中间节点break;}p_pre = p_pre->next;}L2->next = p_pre->next; // L2 头节点指向后面的一半链表p_pre->next = NULL; // 前一半链表的最后一个节点 next 要为 NULL
}

在这个函数中,我们使用双指针法来找到链表的中间节点。p_cur每次移动两步,而p_pre每次移动一步。当p_cur到达链表末尾时,p_pre正好指向中间节点。我们将后半部分链表的头节点指向L2。 

原地逆置链表

接下来,我们实现一个函数来逆置链表L2

void reverse(Node *L2) {Node *r, *s, *t;r = L2->next;if (NULL == r) {return; // 链表为空}s = r->next;if (NULL == s) {return; // 链表只有一个节点}t = s->next;while (t) {s->next = r; // 原地逆置r = s; // 更新指针s = t;t = t->next; // 移动到下一个节点}s->next = r; // 最后一个节点指向原链表的头L2->next->next = NULL; // 逆置后,链表第一个节点的 next 要为 NULLL2->next = s; // s 是链表的第一个节点,L2 指向它
}

在这个reverse函数中,我们使用三个指针rst来实现链表的原地逆置。r指向当前逆置后的链表的头,s指向当前正在处理的节点,t指向下一个节点。通过不断更新这些指针,我们可以将链表的顺序反转。 

合并两个链表

最后,我们实现一个函数来合并两个链表LL2

void merge(Node *L, Node *L2) {Node *p_cur, *p, *q;p_cur = L->next; // p_cur 始终指向组合后的链表的链表尾p = p_cur->next; // p 指向 L 的第二个节点q = L2->next; // q 指向 L2 第一个节点while (p != NULL && q != NULL) {p_cur->next = q; // 将 L2 的节点连接到合并链表q = q->next; // q 指向下一个p_cur = p_cur->next; // 更新合并链表的尾部p_cur->next = p; // 将 L 的节点连接到合并链表p = p->next; // p 指向下一个p_cur = p_cur->next; // 更新合并链表的尾部}// 处理剩余的节点if (p != NULL) {p_cur->next = p; // 如果 L 还有剩余节点,连接到合并链表}if (q != NULL) {p_cur->next = q; // 如果 L2 还有剩余节点,连接到合并链表}
}

在这个merge函数中,我们通过指针p_curpq来合并两个链表。p_cur始终指向合并后的链表的尾部,p指向链表L的当前节点,q指向链表L2的当前节点。我们交替将两个链表的节点连接到合并链表中,直到一个链表遍历完。

主函数

最后,我们在main函数中调用这些操作,构建链表并进行合并操作:

int main() {Node *L; // 链表头 是结构体指针类型list_tail_insert(L); // 尾插法输入数据print_list(L); // 打印链表// 寻找中间节点 并返回第二条链表Node *L2 = NULL;find_middle(L, L2); // 将后半部分链表设置为 L2printf("-------------------------------------\n");print_list(L); // 打印前半部分链表reverse(L2); // 逆置后半部分链表print_list(L2); // 打印逆置后的后半部分链表printf("-------------------------------------\n");merge(L, L2); // 合并两个链表free(L2); // 释放 L2 的内存print_list(L); // 打印合并后的链表return 0;
}

main函数中,我们首先定义一个链表L,然后调用list_tail_insert函数来填充链表。接着,我们使用print_list函数打印链表的内容,以验证插入操作的正确性。

示例运行

假设用户输入以下数据来创建链表:

1
2
3
4
5
9999

在这种情况下,链表的初始状态为:1 -> 2 -> 3 -> 4 -> 5。接着,我们进行以下操作:

  1. 找到中间节点并将后半部分链表设置为L2,此时L2将包含4 -> 5
  2. 逆置L2,结果为5 -> 4
  3. 合并LL2,最终链表将变为:`1 ->2 -> 3 -> 5 -> 4

输出示例

假设用户输入了上述数据,程序的输出将类似于:

1 2 3 4 5 
-------------------------------------
1 2 3 
5 4 
-------------------------------------
1 2 3 5 4 

在这个输出中,我们可以看到:

  1. 初始链表:用户输入的链表为1 2 3 4 5
  2. 分割后的链表:在找到中间节点后,前半部分链表为1 2 3,后半部分链表L24 5,经过逆置后变为5 4
  3. 合并后的链表:最终合并后的链表为1 2 3 5 4,展示了合并操作的结果。

总结

通过这篇博客,我们深入探讨了链表的基本操作,包括尾插法、打印链表、找到中间节点、逆置链表和合并两个链表。链表的灵活性使得它在许多应用中都非常有用,尤其是在需要频繁插入和删除操作的场景中。

关键点回顾

  1. 双指针法:使用双指针法有效地找到链表的中间节点,避免了多次遍历。
  2. 原地逆置:通过指针操作实现链表的原地逆置,节省了额外的空间。
  3. 合并操作:交替合并两个链表,确保合并后的链表保持顺序。

希望这篇文章能帮助你更好地理解链表的实现和操作。如果你有任何问题或想法,欢迎在评论区留言讨论!链表的世界充满了可能性,继续探索吧!

http://www.dtcms.com/wzjs/48918.html

相关文章:

  • 网站服务费做管理费用seo建站要求
  • wordpress为什么那么卡怎么优化整站
  • 网站建设的自查报告百度云在线登录
  • 设计制作数字电压表长春网站优化平台
  • 一个app下载网站今日关键词
  • 西城网站建设公司提升关键词
  • 购物网站建设要多少钱百度搜索指数查询
  • 嘉兴做网站的公司有哪些营销型企业网站建设步骤
  • seo蒙牛伊利企业网站专业性诊断网站seo优化方案设计
  • 做视频网站需要多大的带宽泉州网站建设优化
  • 公司备案证查询网站查询cps广告联盟平台
  • H5平台网站建设东莞seo建站推广费用
  • 网站建设美文正规职业技能培训机构
  • 销售产品网站有哪些企业网站建设案例
  • 建立网站服务的公司网站怎么做线上销售
  • 中国工商银行app下载电脑系统优化软件排行榜
  • 网站备案 新网seo网络排名优化
  • 公司简介100字范文长沙seo优化推广公司
  • 服务质量好的crm系统seo关键词排名优化推荐
  • 装饰网站建设公司江苏短视频seo搜索
  • web网站建设应遵循的原则seo外包资讯
  • 厦门建网站多少钱深圳网络推广团队
  • 俄语培训网站建设手机cpu性能增强软件
  • wordpress科技网站模板宁波seo行者seo09
  • 一级a做网站免费腾讯广告官网
  • 宜宾建功路桥建设有限公司网站子域名在线查询
  • 湘潭网站建设磐石网络百度小说风云榜首页
  • 免备案的网站产品运营推广方案
  • ftp上传网站之后怎么做代发关键词包收录
  • 网站改版的影响优化深圳seo