考研代码题
今天分享一道某985计算机23年考研的代码题,欢迎小伙伴讨论。
一、题目
1到n个节点的单链表, n为偶数。编写一个函数adjust(),使得整个奇数序列在前,偶数序列在后。
二、解题思路
- 定义两个指针,分别指向单链表的头和尾节点
- 再定义两个指针,分别表示奇数序列排完之后的最后一个节点和偶数序列排完之后的最后一个节点
- 从头开始遍历单链表,把奇数节点挂到奇数序列的最后,偶数节点挂到偶数序列的最后
- 待遍历完整个单链表之后,再将奇数序列的下一个节点指向偶数序列的头节点
- 将偶数序列的下一个节点指向NULL即可
用到的算法和数据结构:
在本题的解题思路中,需要用到指针和链表的数据结构。算法无需使用高级算法,只需使用基础的遍历和指针操作即可。
三、C语言代码实现:
#include <stdio.h>
#include <stdlib.h>
/* 定义单链表节点结构体 */
struct ListNode {
int val;
struct ListNode *next;
};
void adjust(struct ListNode* head) {
if (head == NULL || head->next == NULL) { // 检查链表是否为空或只有一个节点
return;
}
struct ListNode *oddTail = head; // 奇数序列的最后一个节点
while (oddTail->next != NULL && oddTail->next->val % 2 != 0) { // 找到奇数序列的最后一个节点
oddTail = oddTail->next;
}
if (oddTail->next == NULL) { // 如果奇数节点全都在前面,直接返回
return;
}
struct ListNode *evenTail = oddTail->next; // 偶数序列的最后一个节点
struct ListNode *cur = evenTail->next; // 遍历链表的指针
while (cur != NULL) { // 遍历链表,按顺序把节点分别挂在奇数和偶数序列的末尾
if (cur->val % 2 != 0) { // 挂在奇数序列末尾
evenTail->next = cur->next; // 需要记录下一个节点,否则会丢失链表
cur->next = oddTail->next;
oddTail->next = cur;
oddTail = cur;
cur = evenTail->next;
} else { // 挂在偶数序列末尾
evenTail = cur;
cur = cur->next;
}
}
evenTail->next = NULL; // 将偶数序列的下一个节点指向NULL
}
/* 初始化链表 */
struct ListNode* initList(int n) {
struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *p = head;
srand(0);
for (int i = 0; i < n; i++) {
p->next = (struct ListNode*)malloc(sizeof(struct ListNode));
p->next->val = rand() % 100;
p = p->next;
}
p->next = NULL;
return head;
}
/* 打印链表 */
void printList(struct ListNode *head) {
struct ListNode *p = head->next;
while (p != NULL) {
printf("%d ", p->val);
p = p->next;
}
printf("\n");
}
int main() {
struct ListNode *head = initList(10); // 创建一个单链表,节点个数为10
printf("原链表:");
printList(head);
adjust(head); // 调整链表
printf("新链表:");
printList(head);
return 0;
}
当然在初试的时候,同学可以不必在试卷上写那么详细,表达清楚主体函数和注释思路即可。