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

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;
}
  • 6
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

每天进步一点丶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值