【数据结构】对单链表进行简单选择排序,使结点元素递增

文章介绍了如何使用C语言实现单链表的简单选择排序算法,包括算法思想、定义链表结构体、函数实现过程以及测试用例。在函数实现部分,通过工作指针找到每一轮的最小值并进行交换,最后展示了创建和排序链表的完整代码。

1.算法思想

  1. 循环创建单链表
  2. 使用简单选择排序找到当前最小的结点的值
  3. 交换最小值与当前值
  4. 重复2,3两步,直到排序完成

2.定义结构体

只使用到单链表的数据结构:

  • data: 存放数据元素
  • next: 用于指向下一个结点的指针
typedef struct LNode {
    int data;
    struct LNode *next;
} LNode, *LinkList;

3.函数实现

工作指针:

  • min: 指向每一轮比较完成后的最小结点
  • p: 指向当前结点,每次比较完成后都将与min比较是否交换数据元素
  • q: 用于遍历链表,每次都从p的下一个结点开始,查找当前轮的最小结点

简单选择排序的基本思想:

  1. 将最小值min设置为当前结点p,从p的下一个结点q开始查找,如果遇到比最小值结点min还小的值,则修改min,让其指向q
  2. 交换p和min指向的数据。使用中间变量tmp暂存p的值。完成后p指针后移
  3. 重复1,2两步,直至排序完成
void ChooseSort(LinkList &A) {
    //工作指针,min指向最小结点,p指向当前结点,q为工作指针,用于每轮的遍历
    LNode *min,*p,*q;
    int tmp;//暂存当前结点值,用于交换数据
    if(!A->next) {
        printf("链表为空!\n");
        return;
    }
    for(p=A->next; p!=NULL; p=p->next) {
        min = p;//每一轮最小结点指向当前结点
        q = p->next;//从当前结点的下一个节点开始比较
        while(q) {
            if(q->data < min->data) {//如果工作结点比最小值还小
                min = q;
            }
            q = q->next;
        }
        tmp = p->data;
        p->data = min->data;
        min->data = tmp;
    }
}

4.测试用例

创建链表A,并定义数据元素数组a,然后循环创建每个结点,使用尾插法将每次创建的结点插入到链表中。

  • sizeof(a) / sizeof(a[0]): 用于计算数组a的数据个数,创建结点
  • 指针s: 用于指向每次创建的新结点
  • 指针tail: 指向链表的尾结点,初始指向头结点A

每次循环时创建新结点,然后将数据元素插入到新结点中,再使用尾插法将新结点插入到链表尾部,并修改tail指针指向新的尾结点。

 LinkList A = (LinkList)malloc(sizeof(LNode));
    int a[] = {4,5,3,1,2};
    LNode *s = NULL;
    LNode *tail = A;//tail指向尾结点
    //循环创建链表
    for(int i=0; i < sizeof(a) / sizeof(a[0]); i++) {
        s = (LNode *)malloc(sizeof(LNode));//创建新结点
        s->data = a[i];
        s->next = NULL;
        tail->next = s;
        tail = tail->next;
    }

测试结果如下:
简单选择排序升序

5.完整代码

#include <iostream>
using namespace std;

//定义结构体
typedef struct LNode {
    int data;
    struct LNode *next;
} LNode, *LinkList;

//简单选择排序(升序)
void ChooseSort(LinkList &A) {
    //工作指针,min指向最小结点,p指向当前结点,q为工作指针,用于每轮的遍历
    LNode *min,*p,*q;
    int tmp;//暂存当前结点值,用于交换数据
    if(!A->next) {
        printf("链表为空!\n");
        return;
    }
    for(p=A->next; p!=NULL; p=p->next) {
        min = p;//每一轮最小结点指向当前结点
        q = p->next;//从当前结点的下一个节点开始比较
        while(q) {
            if(q->data < min->data) {//如果工作结点比最小值还小
                min = q;
            }
            q = q->next;
        }
        tmp = p->data;
        p->data = min->data;
        min->data = tmp;
    }
}

int main() {
    //创建单链表
    LinkList A = (LinkList)malloc(sizeof(LNode));
    int a[] = {4,5,3,1,2};
    LNode *s = NULL;
    LNode *tail = A;//tail指向尾结点
    //循环创建链表
    for(int i=0; i<sizeof(a) / sizeof(a[0]); i++) {
        s = (LNode *)malloc(sizeof(LNode));//创建新结点
        s->data = a[i];
        s->next = NULL;
        tail->next = s;
        tail = tail->next;
    }
    LinkList p = A->next;
    printf("A链表的数据为:\n");
    while(p) {
        printf("%d\t", p->data);
        p = p->next;
    }
    printf("\n");
    ChooseSort(A);
    LinkList q = A->next;
    printf("修改后后A链表的数据为:\n");
    while(q) {
        printf("%d\t", q->data);
        q = q->next;
    }

    return 0;
}
### 合并两个有序单链表 以下是使用 C++ 实现的 `merge_sorted_lists` 函数代码,用于合并两个带头结点递增有序单链表,并保持递增有序: ```cpp #include <iostream> using namespace std; // 定义单链表节点结构 struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; // 合并两个有序单链表 ListNode* merge_sorted_lists(ListNode* list1, ListNode* list2) { // 创建一个虚拟头结点 ListNode dummy(0); ListNode* tail = &dummy; // 遍历两个链表,将较小的节点添加到新链表中 while (list1 != nullptr && list2 != nullptr) { if (list1->val <= list2->val) { tail->next = list1; list1 = list1->next; } else { tail->next = list2; list2 = list2->next; } tail = tail->next; } // 将剩余部分直接连接到新链表 if (list1 != nullptr) { tail->next = list1; } else { tail->next = list2; } return dummy.next; // 返回合并后的链表结点 } ``` 上述代码通过创建一个虚拟头结点来简化合并过程。在遍历两个链表时,始终选择当前值较小的节点进行连接,最终返回合并后的链表结点[^5]。 --- ### 使用简单选择法对单链表进行排序 以下是使用 C++ 实现的 `List_sort` 函数代码,基于简单选择法对带头结点单链表进行排序: ```cpp // 简单选择法对单链表进行排序 void List_sort(ListNode* head) { if (head == nullptr || head->next == nullptr) return; // 如果链表为空或只有一个节点,则无需排序 ListNode* current = head->next; // 从第一个实际节点开始 while (current != nullptr) { ListNode* minNode = current; // 假设当前节点为最小值节点 ListNode* temp = current->next; // 遍历后续节点寻找最小值 // 寻找最小值节点 while (temp != nullptr) { if (temp->val < minNode->val) { minNode = temp; } temp = temp->next; } // 如果找到更小的值,则交换当前节点与最小值节点的数据 if (minNode != current) { swap(minNode->val, current->val); } current = current->next; // 移动到下一个节点 } } ``` 上述代码实现了简单选择排序逻辑。对于每个节点,遍历其后续节点以找到最小值,并通过交换节点值的方式完成排序。由于只交换节点值而不改变节点指针,因此该方法适用于单链表排序[^6]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步一点丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值