網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
C語(yǔ)言結(jié)構(gòu)體快排算法
代碼:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Stu{
char name[100]; //名字
char xue[100]; //學(xué)號(hào)
int c; //成績(jī)
}stu[10010];
int comp(const void* a,const void* b)
{
struct Stu *aa = (struct Stu *)a;
struct Stu *bb = (struct Stu *)b;
return ((aa->c)-(bb->c)); //aa->c為結(jié)構(gòu)體的成員,bb->c也為結(jié)構(gòu)體的成員
}
int main()
{
int n;
int i,j;
scanf("%d",&n);
getchar();
for(i=0;i<n;i++)
{
scanf("%s%s%d",&stu[i].name,&stu[i].xue,&stu[i].c);
}
printf("\n");
qsort(stu,n,sizeof(stu[0]),comp); //參數(shù)1:結(jié)構(gòu)體數(shù)組名,個(gè)數(shù),首地址的字符數(shù),自定義比較函數(shù)名
for(i=0;i<n;i++)
printf("%s %s %d\n",stu[i].name,stu[i].xue,stu[i].c);
return 0;
}
基于結(jié)構(gòu)體數(shù)組的快速排序
用普通的數(shù)組快速排序,改造成任意數(shù)據(jù)的排序,比如結(jié)構(gòu)體數(shù)組、鏈表、棧的排序等。只需要在排序中調(diào)用自己的compare函數(shù),在其中把想要排序的值做一個(gè)比較即可,代碼如下:
#include <stdio.h>
#include <strings.h>
typedef int (*Z_COMPARE)(void* obj1, int obj1size, void* obj2, int obj2size);
typedef struct
{
char name[20];
char brief_name[20];
char desc[20];
}ROOM_INFO;
int room_info_cmp(void* obj1, int obj1size, void* obj2, int obj2size)
{
ROOM_INFO* item1 = (ROOM_INFO*)obj1;
ROOM_INFO* item2 = (ROOM_INFO*)obj2;
if(atoi(item1->brief_name) < atoi(item2->brief_name))
{
return 1;
}
else if(atoi(item1->brief_name) > atoi(item2->brief_name))
{
return 0;
}
return -1;
}
int quicksort(ROOM_INFO* room_info, int left, int right, Z_COMPARE cmp)
{
ROOM_INFO tmp = {0};
ROOM_INFO f = {0};
int rtemp,ltemp;
ltemp = left;
rtemp = right;
if(ltemp >= rtemp)
{
return 0;//排序結(jié)束
}
memcpy(&f, &room_info[left], sizeof(ROOM_INFO));//保存基準(zhǔn)值
while(ltemp < rtemp)
{
while(cmp(&room_info[rtemp], sizeof(ROOM_INFO), &f, sizeof(ROOM_INFO)) == 0 && ltemp < rtemp)
{
--rtemp;
}
if(ltemp != rtemp)
{
memcpy(&room_info[ltemp], &room_info[rtemp], sizeof(ROOM_INFO));
ltemp++;
}
while(cmp(&room_info[ltemp], sizeof(ROOM_INFO), &f, sizeof(ROOM_INFO)) == 1 && ltemp < rtemp)
{
++ltemp;
}
if(ltemp != rtemp)
{
memcpy(&room_info[rtemp], &room_info[ltemp], sizeof(ROOM_INFO));
rtemp--;
}
}
memcpy(&room_info[ltemp], &f, sizeof(ROOM_INFO));
if(left < rtemp)
{
quicksort(room_info, left, ltemp-1, cmp);
}
if(ltemp < right)
{
quicksort(room_info, rtemp+1, right, cmp);
}
return 0;
}
int main()
{
ROOM_INFO room_info[10] = {0};
int i = 0;
srand(time(NULL));
for(i = 0; i < 10; i++)
{
snprintf(room_info[i].brief_name, sizeof(room_info[i].brief_name), "%d", rand()%100);
}
for(i = 0; i < 10; i++)
{
printf("111111,room_info[%d].brief_name=%s\n",i, room_info[i].brief_name);
}
printf("\n\n");
quicksort(room_info, 0, 9, room_info_cmp);
for(i = 0; i < 10; i++)
{
printf("222222,room_info[%d].brief_name=%s\n",i, room_info[i].brief_name);
}
return 0;
}
運(yùn)行結(jié)果如下:
如果是鏈表的排序,只需要把quicksort函數(shù)的第一個(gè)參數(shù)換成鏈表的指針,然后在排序中換成相應(yīng)獲取鏈表里的數(shù)據(jù)即可。
另外,C語(yǔ)言提供一個(gè)庫(kù)函數(shù),已經(jīng)封裝好了快速排序的算法:
void qsort(
void *base,
size_t nmemb,
size_t size,
int (*compar)(const void *, const void *)
);
具體的信息如下:Copy from baidu
- 參數(shù)base - base指向數(shù)組的起始地址,通常該位置傳入的是一個(gè)數(shù)組名
- 參數(shù)nmemb - nmemb表示該數(shù)組的元素個(gè)數(shù)
- 參數(shù)size - size表示該數(shù)組中每個(gè)元素的大小(字節(jié)數(shù))
- 參數(shù)(*compar)(const void *, const void *) - 此為指向比較函數(shù)的函數(shù)指針,決定了排序的順序。
函數(shù)返回值:無(wú)
注意:如果兩個(gè)元素的值是相同的,那么它們的前后順序是不確定的。也就是說(shuō)qsort()是一個(gè)不穩(wěn)定的排序算法。
compar參數(shù)
- compar參數(shù)指向一個(gè)比較兩個(gè)元素的函數(shù)。比較函數(shù)的原型應(yīng)該像下面這樣。
- 注意兩個(gè)形參必須是const void *型,同時(shí)在調(diào)用compar 函數(shù)(compar實(shí)質(zhì)為函數(shù)指針,這里稱它所指向的函數(shù)也為compar)時(shí),
- 傳入的實(shí)參也必須轉(zhuǎn)換成const void *型。在compar函數(shù)內(nèi)部會(huì)將const void *型轉(zhuǎn)換成實(shí)際類型,見(jiàn)下文。
int compar(const void *p1, const void *p2);
- 如果compar返回值小于0(< 0),那么p1所指向元素會(huì)被排在p2所指向元素的前面
- 如果compar返回值等于0(= 0),那么p1所指向元素與p2所指向元素的順序不確定
- 如果compar返回值大于0(> 0),那么p1所指向元素會(huì)被排在p2所指向元素的后面
因此,如果想讓qsort()進(jìn)行從小到大(升序)排序,那么一個(gè)上面的compar函數(shù)可以寫(xiě)成這樣:
int room_info_cmp(void* obj1, void* obj2)
{
ROOM_INFO* item1 = (ROOM_INFO*)obj1;
ROOM_INFO* item2 = (ROOM_INFO*)obj2;
if(atoi(item1->brief_name) < atoi(item2->brief_name))
{
return -1;
}
else if(atoi(item1->brief_name) > atoi(item2->brief_name))
{
return 1;
}
return 0;
}
原文鏈接:https://blog.csdn.net/qq_27494201/article/details/100120431
相關(guān)推薦
- 2023-02-25 pandas?loc?iloc?ix用法詳細(xì)分析_python
- 2023-04-01 Pytorch基礎(chǔ)之torch.randperm的使用_python
- 2022-09-26 數(shù)據(jù)庫(kù)基本增刪改查語(yǔ)法和多表鏈接查詢的方式
- 2022-07-17 android?studio實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器小功能_Android
- 2022-10-15 C語(yǔ)言中數(shù)據(jù)如何存儲(chǔ)進(jìn)內(nèi)存揭秘_C 語(yǔ)言
- 2023-01-07 SafeList?in?Flutter?and?Dart小技巧_Android
- 2022-05-13 C++ 減少臨時(shí)字符串對(duì)象的產(chǎn)生
- 2022-08-13 electron功能實(shí)現(xiàn)---添加全局快捷鍵、開(kāi)機(jī)自啟、選擇安裝路徑
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支