4、标准库函数qsort 前面三种排序算法都只是针对单个元素进行排序,但实际应用中,基于某个数值对一个大结构体进行排序,比如wifi信息结构体数组,包括其mac、名称、加密信息、和信号强度,依据信息强度对wifi信息进行排序,每次数据交换意味着两次内存拷贝,这种场景下采用选择排序略优。 相比于自己造轮子,C语言标准库函数也许更合适;qsort函数是C语言自带的排序函数,包含在<stdlib.h>中。
函数原型 void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
base - 指针,数组的第一个元素进行排序 nitems - 数组中的元素数目 size - 数组中的每个元素的大小(以字节为单位) compar - 基于这个函数比较两个元素 返回值:不返回任何值 缺点:对于有多个重复值的数组来说,效率较低不稳定
范例 //qsort要结合compare使用
int compare(const void *value1, const void *value2)
{
//升序或降序在此调整
return (*(int*)value1 - *(int*)value2);
}
int main(void)
{
int data[ARRAY_SIZE] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
log("source", data, ARRAY_SIZE);
qsort(data, ARRAY_SIZE, sizeof(int), compare);
log("sort ", data, ARRAY_SIZE);
return 0;
}
其效果和前面三种算法一样,而且可扩展针对结构体内某个元素值对整体排序,满足前面的wifi信息按信号强度排序的需求。 #include <stdio.h>
#define WIFI_AP_MAX 5
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned short uint16_t;
typedef signed short int16_t;
typedef unsigned int uint32_t;
typedef struct
{
uint32_t bssid_low; // mac address low
uint16_t bssid_high; // mac address high
uint8_t channel; // channel id
int8_t rssi; // signal strength <sort>
} wifiApInfo_t;
//qsort要结合compare使用,按信号强度rssi升序排列
int compare(const void *value1, const void *value2)
{
const wifiApInfo_t *ctx1 = (const wifiApInfo_t *)value1;
const wifiApInfo_t *ctx2 = (const wifiApInfo_t *)value2;
return (ctx1->rssi - ctx2->rssi);
}
static wifiApInfo_t wifiApInfo[WIFI_AP_MAX] =
{
{0x5555, 0x55, 5, -55},
{0x1111, 0x11, 1, -51},
{0x3333, 0x33, 3, -53},
{0x4444, 0x44, 4, -54},
{0x2222, 0x22, 2, -52},
};
void wifi_log(char *head, void *data, int size)
{
unsigned char i;
const wifiApInfo_t *wifi = (wifiApInfo_t *)data;
printf("%s:\r\n", head);
for(i = 0; i < size; i++)
{
printf("%X %X %d [%d] \r\n", wifi[i].bssid_low, wifi[i].bssid_high, wifi[i].channel, wifi[i].rssi);
}
printf("\r\n\r\n");
}
int main(void)
{
wifi_log("source", wifiApInfo, WIFI_AP_MAX);
qsort(wifiApInfo, WIFI_AP_MAX, sizeof(wifiApInfo_t), compare);
wifi_log("sort", wifiApInfo, WIFI_AP_MAX);
return 0;
}
运行结果
source:
5555 55 5 [-55]
1111 11 1 [-51]
3333 33 3 [-53]
4444 44 4 [-54]
2222 22 2 [-52]
//依据信号强度关键字,对wifi信息整体数据同步进行了排序
sort:
5555 55 5 [-55]
4444 44 4 [-54]
3333 33 3 [-53]
2222 22 2 [-52]
1111 11 1 [-51]
|