思路
选择排序算法通过选择和交换来实现排序,其排序流程如下:
(1)首先从原始数组中选择最小的1个数据,将其和位于第1个位置的数据交换。
(2)接着从剩下的n-1个数据中选择次小的1个元素,将其和第2个位置的数据交换
(3)然后,这样不断重复,直到最后两个数据完成交换。最后,便完成了对原始数组的从小到大的排序
关于链表的实现有两点疑问:
1,带头结点的单链表如何交换两个元素
A,B两个元素要设4个指针分别指向A、B的前后节点。交换时,分AB相邻和不相邻两种情况:
A,相邻只需要更改3个节点指向
AB
A的前置指向B,B指向A,A指向B的后置
B,不相邻要更改4个节点指向
A前置 A A后置 。。。。B前置 B B后置
A的前置指向B,B指向A的后置
B的前置指向A,A指向B的后置
2,简单选择排序中,链表如何区分两个元素
在数组的排序中,值是用下标来标识不同的元素,即使值相同也可区分。
在链表的排序中,在之前的遍历中已经找到的是<min的元素,找到的元素一定和min的值不相同,故可以用p->data != min->data作为条件。或者结构体中加一个id来区分不同的元素。
代码
#include<stdio.h>
#include "malloc.h"
#include<stdlib.h>
//定义链表结构体
typedef struct Listnode
{
int data;
struct Listnode* next;
}Listnode;
//交换链表中两个数据
void swap(Listnode* p, Listnode* min, Listnode* pre, Listnode* lmin, Listnode* bmin)
{
if (p->next == min)//min就在p后一位,交换相邻的两个节点
{
pre->next = min;
p->next = lmin;
min->next = p;
}
else//交换不相邻的两个节点
{
pre->next = min;
min->next = p->next;
p->next = lmin;
bmin->next = p;
}
};
void select_sort(Listnode* head)//简单选择排序(升序)
{
Listnode* pre = head;
Listnode* p = pre->next;
Listnode* bmin = pre, * min, * lmin;//bmin是min前一个节点,lmin是min后一个节点
Listnode* bq, * q; //bq记录q的前一个节点
while (p->next)//从第一个元素开始遍历到n-1个元素
{
min = p;//从第一个元素开始遍历
lmin = min->next;//min的后一个节点
bq = p;//p的前一个节点
q = p->next;//p从第二个元素开始遍历
while (q)//循环在min后面到第n个元素,找到最小值节点
{
if (q->data < min->data)
{ //记录min及其前后两个节点
bmin = bq;
min = q;
lmin = min->next;
}
bq = q;
q = q->next;//遍历
}
if (p->data != min->data)//在min后找到更小的值就交换
{
swap(p, min, pre, lmin, bmin);
}
pre = pre->next;
p = pre->next;
}
}
//输出链表节点
void print(Listnode* L)
{
Listnode* p = L;
for (int i = 0; i< L->data; ++i)//L为头结点不能动 否则每次遍历就会改变条件
{
printf("%d ", p->next->data);
p = p->next;
}
}
void test()
{
//建立链表
Listnode* L = (Listnode *) malloc(sizeof(Listnode));
if (L == NULL) {
printf("内存分配不成功!\n");
}
else
{
L->data = 10;
Listnode* p = L;
for (int i = 0; i < L->data; ++i)
{
p->next = (Listnode*)malloc(sizeof(Listnode));
if (p->next) {
p = p->next;
p->data = rand() % 100;//取0-99的随机数 0-99,都为原值,100-199为0-99,以此类推
}
}
p->next = NULL;
printf("原始序列为:\n");
print(L);
select_sort(L);
printf("\n排序后为:\n");
print(L);
}
}
int main()
{
test();
return 0;
}