选择排序
//选择排序
#include <stdio.h>
#include <stdlib.h>
typedef struct student{
int num; // 学号
double grade; // 成绩
struct student *next; // 指向下一个学生的指针
} student;
student *merge(student *a, student *b)
{
// 先合并,后排序
student *head = a; // 头指针指向链表a的第一个节点
while (a->next != NULL) // 找到链表a的最后一个节点
{
a = a->next;
}
a->next = b; // 将链表b接在链表a的最后一个节点后面
// 选择排序,每次选最小的,放在未排序的链表头部
student *p;
p = head; // p指向未排序部分的头节点
while (p->next != NULL) // 当还有未排序的节点时
{
a = p->next; // a指向未排序部分的第一个节点
while (a != NULL) // 遍历未排序部分的节点
{
if (p->num > a->num) // 如果p节点的学号大于a节点的学号,则交换两个节点的数据
{
int num = p->num;
double grade = p->grade;
p->num = a->num;
p->grade = a->grade;
a->num = num;
a->grade = grade;
}
a = a->next; // a指向下一个节点
}
p = p->next; // p指向下一个未排序部分的头节点
}
return head; // 返回排序后的链表的头指针
}
int main()
{
student a[3] = { { 1, 79 }, { 4, 36 }, { 5, 79 } }; // 创建数组a,存储学生信息
for (int i = 0; i < 2; i++) // 将数组a中的节点连接起来
{
a[i].next = &a[i + 1];
}
student b[2] = { { 2, 38 }, { 6, 98 } }; // 创建数组b,存储学生信息
for (int i = 0; i < 1; i++) // 将数组b中的节点连接起来
{
b[i].next = &b[i + 1];
}
student *combine = merge(a, b); // 合并并排序链表a和链表b
while (combine != NULL) // 遍历合并后的链表并输出学生信息
{
printf("%d -> %.2lf\n", combine->num, combine->grade);
combine = combine->next; // 指向下一个节点
}
return 0;
}
插入排序
//插入排序
#include <stdio.h>
#include <stdlib.h>
typedef struct student{
int num; // 学号
double grade; // 成绩
struct student *next; // 指向下一个学生的指针
} student;
student* insertSort(student* head)//链表的插入排序
{
if (head == NULL || head->next == NULL) //1,检查链表长度:如果链表为空或者只有一个节点,则不需要进行排序,直接返回链表头指针head
{
return head;
}
student temp; //2,创建辅助节点:用于处理链表头部的插入情况
temp.next = head;//将辅助节点的next指针指向链表头指针head
student* lastSorted = head; //3,初始化已排序部分: 创建一个指针lastSorted,指向已排序部分的最后一个节点
student* current = head->next;//4,遍历链表:指向链表头指针head的下一个节点,即第二个节点
while (current != NULL)//然后进入循环,遍历整个链表,直到当前节点current为空
{
//5,寻找插入位置:在每次循环中,判断当前节点current的学号num是否小于已排序部分的最后一个节点的学号lastSorted->num,如果是,说明当前节点需要插入到已排序部分,需要找到正确的插入位置
if (current->num < lastSorted->num)
{
//6,使用prev指针寻找插入位置:创建一个指针prev,初始时指向辅助节点dummy
student* prev = &temp;
//通过循环遍历已排序部分,直到找到合适的插入位置,即prev->next->num >= current->num
while (prev->next->num < current->num)
{
prev = prev->next;
}
lastSorted->next = current->next; //7,节点插入操作:将当前节点current从已排序部分断开,即lastSorted->next = current->next
current->next = prev->next; //然后将当前节点插入到prev指针的后面,即current->next = prev->next和prev->next = current。
prev->next = current;
current = lastSorted->next;//8,更新当前节点:将当前节点指针current更新为已排序部分的下一个节点,即current = lastSorted->next
}
//9,更新已排序部分指针:如果当前节点current的学号不小于已排序部分的最后一个节点的学号,则将已排序部分指针lastSorted和当前节点指针current都向后移动一位
else
{
lastSorted = lastSorted->next;
current = current->next;
}
}
return temp.next;//10,返回排序后的链表头指针:最终返回辅助节点temp的next指针作为排序后的链表头指针
}
student* merge(student* a, student* b)
{//1,检查输入链表:首先,函数通过检查输入的两个链表指针a和b是否为空来判断需要合并的链表情况
//如果其中一个链表为空,则直接返回另一个链表作为结果
if (a == NULL)
{
return b;
}
if (b == NULL)
{
return a;
}
student dummy;//2,创建辅助节点:创建了一个名为dummy的辅助节点,用于构建合并后的链表
student* tail = &dummy;//同时创建一个指针tail,指向dummy节点,用于记录合并后链表的尾部
dummy.next = NULL;//3,初始化dummy节点:将辅助节点dummy的next指针置为NULL,表示初始时合并后的链表为空
//4,合并两个链表:进入循环,在循环中比较两个链表的节点,并将较小的节点插入到合并后的链表中
while (a != NULL && b != NULL)
{
if (a->num < b->num)//5,比较节点值:在每次循环中,比较两个链表当前节点a和b的学号num大小
{
//6,节点插入操作:如果节点a的学号小于节点b的学号,则将节点a插入到合并后链表的尾部
tail->next = a;
a = a->next; //然后将指针a向后移动一位
}
else //否则,将节点b插入到合并后链表的尾部,然后将指针b向后移动一位
{
tail->next = b;
b = b->next;
}
tail = tail->next;//最后将tail指针也向后移动一位,指向合并后链表的新尾部。
//7,处理剩余节点:当其中一个链表的节点全部插入到合并后的链表中后,可能还会有另一个链表中的节点未处理完毕
//此时,需要将剩余的节点直接连接到合并后链表的尾部
if (a != NULL)
{
tail->next = a;
}
else
{
tail->next = b;
}
}
//8,返回合并后的链表头指针:最终返回辅助节点dummy的next指针作为合并后的链表头指针
return dummy.next;
}
int main()
{
student a[3] = { { 1, 79, NULL }, { 4, 36, NULL }, { 5, 79, NULL } };
for (int i = 0; i < 2; i++)
{
a[i].next = &a[i + 1];
}
student b[2] = { { 2, 38, NULL }, { 6, 98, NULL } };
for (int i = 0; i < 1; i++)
{
b[i].next = &b[i + 1];
}
student* combined = merge(a, b);
student* sorted = insertSort(combined);
student* current = sorted;
while (current != NULL)
{
printf("%d -> %.2lf\n", current->num, current->grade);
current = current->next;
}
return 0;
}