当前位置: 代码迷 >> 综合 >> 链表进阶操作一:调换相邻节点的位置 以及 让节点所有奇偶位置互换(图文演示,通俗易懂)
  详细解决方案

链表进阶操作一:调换相邻节点的位置 以及 让节点所有奇偶位置互换(图文演示,通俗易懂)

热度:96   发布时间:2023-11-29 13:17:16.0

关于链表有很多可以实现的操作,接下来讲讲一些关于链表的进阶操作。

我们先来讲讲相邻节点是如何调换的

一、先创建一条链表

直接上代码(不知道如何创建链表的同学可以看看我上一篇文章)

//需要的两个头文件
#include<stdio.h>
#include<stdlib.h>//定义结构体(包含指针域和数据域)
typedef struct Node
{
    int data;struct Node *next;} Node;int main(){
    Node *p1,*p2;      //定义两个指针进行各种操作(可看我的上一篇文章)Node *head;       //定义head指针标记头结点int x; 	head = NULL;printf("请输入创建多少个链表:"); scanf("%d",&x);// 创建链表节点并连接 for(int i=1;i<=x;i++){
    p1 = (Node *)malloc(sizeof (Node));if(head == NULL){
    head = p1;p2 = p1;}else{
    p2->next =p1;p2 = p1;}}p2->next = NULL;    //把尾结点标记为NULLp = head;

此时该链表图为:

在这里插入图片描述

链表的顺序已经是固定的了。要想实现调换链表中临近节点的位置,如调换2和3节点,我们该如何做呢?如何用两个指针实现呢?

二、先试着调换第2、第3节点的位置

调换后的位置为1→3→2→4→…即我们需要把1节点指向3的位置,2节点指向4的位置,然后2,3节点反转一下,就实现了2,3节点调换。

操作如图:
在这里插入图片描述

貌似这图也不是很直观。。要是没看懂还是需要自己画图多想想,其实就是1→2→3→4变成1→3→2→4

直接上代码:

为方便理解,我们先定义三个指针*p,*p1,*p2分别指向1,23的位置
即:p = head;p1 = p->next;p2 = p1->next;
调换位置的操作:p->next = p2;                1指向3的位置p1->next = p2->next;         2指向4的位置p2->next = p1;               3又指向2的位置

三、输入输出数据,检测操作是否正确

输入数据int q=1;while (p != NULL){
    p->data = q;q++;printf("%d ",p->data);p = p->next;} printf("\n");
输出数据:p = head;while (p != NULL){
    printf("%d ",p->data);p = p->next;} 

运行结果:


请输入创建多少个链表:4
1 2 3 4
1 3 2 4
--------------------------------
Process exited after 4.014 seconds with return value 0
请按任意键继续. . .

调换2,3位置的操作成功了

如何实现链表中所有节点奇数和偶数的位置互换呢?

这是室友的一道题,大概就是实现1和2的位置互换,3和4的位置互换,我研究了半小时,想发出来给大家分享一下想法。

讲讲我的思路

其实就是我刚刚讲的那个相邻位置互换的进阶操作。多加一个循环来实现就可以。定义三个指针的好处就是,p指针来标记位置,p1和p2用来实现调换位置的功能。

由于上面所讲可以看出,要想调换两个节点的位置,我们至少需要知道调换节点的前一个的位置。也就是说,要想调换2,3节点的位置,必须要知道1节点的位置,否则,1节点无法指向3节点的位置致使操作失败。

注意:只要调换1,2节点的位置时不需要标记前一个节点的位置,所以我们要进行特殊化处理(先调换这两个的位置)

一、先调换1,2节点的位置

代码如下: p1=head;                 p1指向1 节点的位置 p2=head->next;           p2指向2 节点的位置head=p2;                 因为2节点要变成头结点,所以p2标记为headp1->next = p2->next;     1指向3p2->next = p1;           2指向1已经完成了1,2节点位置的调换

二、设计循环 调换之后节点的位置

我们发现,p节点需要标记偶数节点的位置。即,调换3,4要标记2节点,调换5,6要标记4节点。

由于始终为p1从奇数变为偶数。所以只需要在调换完成后用p来标记p1的位置即可。

直接上代码:

调换:p = p1;                              标记上一次调换完成后p1的位置for(a=1;a<=(x/2)-1;a++)              for循环语句,由于已经调换了1,2,所以循环次数-1
{
    p1 = p->next;                    p2 = p1->next;                   p→p1→p2           p->next = p2;                   p1->next = p2->next;             进行调换奇数偶数节点的调换p2->next = p1;p=p1;                            标记调换完成后p1的位置
}

三、输出链表的数据,检测操作是否正确

代码如下:p = head;while(p != NULL){
    printf("%d ",p->data);p = p->next;}

运行结果:


请输入创建多少个链表:9
反转前:1 2 3 4 5 6 7 8 9
反转后:2 1 4 3 6 5 8 7 9
--------------------------------
Process exited after 2.78 seconds with return value 0
请按任意键继续. . .

以后会不定时更新进阶操作的哦,希望大家可以点个赞,点个关注收藏~
大家有啥问题可以一起讨论哦,谢谢观看

  相关解决方案