【id:22】【20分】B. DS单链表--结点交换

题目描述

用C++实现含头结点的单链表,然后实现单链表的两个结点交换位置。

注意不能简单交换两个结点包含数据,必须通过修改指针来实现两个结点的位置交换

交换函数定义可以参考:

swap(int pa, int pb) //pa和pb表示两个结点在单链表的位置序号

swap (ListNode * p, ListNode * q) //p和q表示指向两个结点的指针

输入

第1行先输入n表示有n个数据,接着输入n个数据

第2行输入要交换的两个结点位置

数据结构单链表合并有多种实现方法,以下为你详细介绍: ### 方法一:通过比较元素大小合并 此方法是比较两个链表当前元素大小,将较小元素依次连接到新链表,最后处理剩余元素。 ```c struct node *merge(struct node *La, struct node *Lb) { struct node *pa, *pb, *pc; pa = La->next; // pa 指向表 La 的首结点 pb = Lb->next; // pb 指向表 Lb 的首结点 pc = La; // 使用表 La 的头结点,pc 为尾指针 free(Lb); // 释放 表Lb的头结点 // 比较 Pa 和 Pb 指向结点的数据域值大小 while(pa && pb) { // 表 La,Lb 均有结点 if(pa->data <= pb->data) { // 取表La 的一个结点 pc->next = pa; // 插在表Lc的尾结点之后 pc = pa; // 变为表Lc 新的尾结点 pa = pa->next; // 移向表La 下一个结点 } else { // 取表Lb 的一个结点 pc->next = pb; // 插在表Lc的尾结点之后 pc = pb; // 变为表Lc 新的尾结点 pb = pb->next; // 移向表Lb 下一个结点 } } if(pa) pc->next = pa; // 插入表La的剩余段(如果Lb已遍历) else pc->next = pb; // 插入表Lb的剩余段 return La; } ``` 这种方法的核心在于利用三个指针`pa`、`pb`、`pc`别扫描两个原始链表和构建新链表,每次比较两个链表当前元素大小,将较小元素连接到新链表,最后把剩余元素直接连接到新链表末尾[^3]。 ### 方法二:另一种比较元素大小合并方式 该方法同样比较元素大小,但使用`malloc`创建新头结点,过程与上一种类似。 ```c typedef struct ListNode { int val; struct ListNode *next; } ListNode; typedef ListNode* PNodeList; PNodeList mergeTwoList(PNodeList l1, PNodeList l2) { if (l1 == NULL) return l2; if (l2 == NULL) return l1; PNodeList head = NULL, tail = NULL; head = tail = (PNodeList)malloc(sizeof(ListNode)); while (l1 && l2) { if (l1->val < l2->val) { tail->next = l1; tail = tail->next; l1 = l1->next; } else { tail->next = l2; tail = tail->next; l2 = l2->next; } } if (l1) { tail->next = l1; } if (l2) { tail->next = l2; } return head->next; } ``` 此方法先创建新头结点,然后在循环中比较`l1`和`l2`当前元素大小,将较小元素连接到新链表,最后处理剩余元素,返回合并后链表的首结点[^2]。 ### 方法三:循环单链表合并 该方法适用于循环单链表,通过找到第一个链表尾结点,连接第二个链表首结点,再找到第二个链表尾结点构成循环。 ```c typedef struct LinkList { int data; struct LinkList *next; } LinkList; void Merge(LinkList* ha, LinkList* hb, LinkList* hc) { LinkList* p = ha->next; hc = ha; while (p->next != ha) { p = p->next; // 找到尾结点 } p->next = hb->next; while (p->next != hb) { p = p->next; // 找到hb的尾结点 } p->next = hc; free(hb); // 释放hb单链表的头结点 } ``` 这种方法针对循环单链表,先找到第一个链表尾结点,将其`next`指向第二个链表首结点,再找到第二个链表尾结点,使其`next`指向第一个链表头结点,最后释放第二个链表头结点[^4]。 ### 展示合并后链表 以下是展示合并后链表的代码: ```c #include <iostream> using namespace std; typedef struct List { int data; struct List *next; } List; void showList(List *head) { List *p; p = head->next; while (p != NULL) { cout << p->data << " "; p = p->next; } cout << endl; } ``` 此代码通过遍历链表,依次输出每个结点的数据,可用于验证合并结果[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值