排序---快速排序的4次優化

前言

個人小記


一、代碼

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_ARR 10000000
#define SCOPE 16
#define swap(a,b)\
{\__typeof(a) __c=a;\a=b,b=__c;\
}
#define TEST(func,arr,l,r)\
{\printf("test: %s\n",#func);\int n=r-l;\int* t=(int*)malloc(sizeof(int)*n);\memcpy(t,arr,n);\long long a=clock();\func(t,l,r);\long long b=clock();\if(check(t,n))printf("OK %lldms\n",(b-a)*1000/CLOCKS_PER_SEC);\else printf("FAIL\n");\free(t);\
}int check(int* t,int n)
{for(int i=1;i<n;i++){if(t[i-1]>t[i])return 0;}return 1;
}int* init_arr(int n)
{int* arr=(int*)malloc(sizeof(int)*n);for(int i=0;i<n;i++)arr[i]=rand()%10000000;return arr;
}void quick_sort(int* arr,int l,int r)
{if(r-l<=2){if(r-l<=1)return ;if(arr[l]>arr[r-1])swap(arr[l],arr[r-1]);return ;}int x=l,y=r-1,z=arr[l];while(y>x){while(y>x&&arr[y]>z)y--;if(y>x)arr[x++]=arr[y];while(y>x&&arr[x]<z)x++;if(y>x)arr[y--]=arr[x];}arr[x]=z;quick_sort(arr,l,x);quick_sort(arr,x+1,r);return ;
}void quick_sort_1(int* arr,int l,int r)
{if(r-l<=2){if(r-l<=1)return ;if(arr[l]>arr[l+1])swap(arr[l],arr[l+1]);return;}int x=l,y=r-1,z=arr[l];while(y>x){while(y>x&&arr[y]>=z)y--;if(y>x)arr[x++]=arr[y];while(y>x&&arr[x]<=z)x++;if(y>x)arr[y--]=arr[x];}arr[x]=z;quick_sort_1(arr,l,x);quick_sort_1(arr,x+1,r);return ;
}void quick_sort_v1(int *arr,int l,int r)
{if(r-l<=2){if(r-l<=1)return ;if(arr[l]>arr[l+1])swap(arr[l],arr[l+1]);return ;}int x=l,y=r-1,z=arr[l];do{while(arr[y]>z)y--;while(arr[x]<z)x++;if(x<=y){swap(arr[x],arr[y]);x++,y--;}}while(x<=y);quick_sort_v1(arr,l,y+1);quick_sort_v1(arr,x,r);
return ;
}int middle(int a,int b,int c)
{if(a>b)swap(a,b);if(a>c)swap(a,c);if(b>c)swap(a,c);return b;
}void quick_sort_v2(int *arr,int l,int r)
{if(r-l<=2){if(r-l<=1)return ;if(arr[l]>arr[l+1])swap(arr[l],arr[l+1]);return ;}int x=l,y=r-1,z=middle(arr[l],arr[r-1],arr[(l+r)/2+1]);do{while(arr[y]>z)y--;while(arr[x]<z)x++;if(x<=y){swap(arr[x],arr[y]);x++,y--;}}while(x<=y);quick_sort_v2(arr,l,y+1);quick_sort_v2(arr,x,r);
return ;
}void quick_sort_v3(int *arr,int l,int r)
{while(r>l){int x=l,y=r-1,z=middle(arr[l],arr[r-1],arr[(l+r)/2+1]);do{while(arr[y]>z)y--;while(arr[x]<z)x++;if(x<=y){swap(arr[x],arr[y]);x++,y--;}}while(x<=y);quick_sort_v3(arr,l,y+1);l=x;}
return ;
}void __quick_sort_v4(int *arr,int l,int r)
{while(r-l>SCOPE){int x=l,y=r-1,z=middle(arr[l],arr[r-1],arr[(l+r)/2+1]);do{while(arr[y]>z)y--;while(arr[x]<z)x++;if(x<=y){swap(arr[x],arr[y]);x++,y--;}}while(x<=y);__quick_sort_v4(arr,l,y+1);l=x;}
return ;
}void UC_insert_sort(int *arr,int l,int r)
{int min=l;for(int i=l;i<r;i++){if(arr[min]>arr[i])min=i;}while(min>l){swap(arr[min],arr[min-1]);min=min-1;}for(int i=l+2;i<r;i++){int j=i;while(arr[j]<arr[j-1]){swap(arr[j],arr[j-1]);j=j-1;}}return ;
}void quick_sort_v4(int *arr,int l,int r)
{__quick_sort_v4(arr,l,r);UC_insert_sort(arr,l,r);return ;
}int main()
{srand((unsigned)time(0));int* arr=init_arr(MAX_ARR);TEST(quick_sort,arr,0,MAX_ARR);//TEST(quick_sort_1,arr,0,MAX_ARR);TEST(quick_sort_v1,arr,0,MAX_ARR);TEST(quick_sort_v2,arr,0,MAX_ARR);TEST(quick_sort_v3,arr,0,MAX_ARR);TEST(quick_sort_v4,arr,0,MAX_ARR);free(arr);return 0;
}

二、測試結果

test: quick_sort
OK 856ms
test: quick_sort_v1
OK 868ms
test: quick_sort_v2
OK 895ms
test: quick_sort_v3
OK 964ms
test: quick_sort_v4
OK 791ms

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/23497.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23497.shtml
英文地址,請注明出處:http://en.pswp.cn/web/23497.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

父組件調用子組件方法(組合式 API版)

在 Vue 3 中&#xff0c;defineExpose 是一個用于在組合式 API (Composition API) 中暴露組件內部方法或屬性的函數。它允許父組件通過 ref 引用子組件實例&#xff0c;并調用子組件暴露的方法或訪問其屬性。 以下是子組件和父組件如何使用 defineExpose 和 ref 的詳細解釋和示…

如何快速分析并將一個簡單的前后端分離項目跑起來

一、前言 主要是前一段時間有小伙伴問我說自己剛入坑學后端不久&#xff0c;在開源網站上找了個簡單的前后端分離項目&#xff0c;但是自己不會跑起來&#xff0c;讓我給他說說&#xff0c;介于這玩意三兩句話不是很好說清楚&#xff0c;而且不清楚那個小伙伴的知識到何種地步…

規則引擎LiteFlow發布v2.12.1版本,決策路由特性

個人博客&#xff1a;無奈何楊&#xff08;wnhyang&#xff09; 個人語雀&#xff1a;wnhyang 共享語雀&#xff1a;在線知識共享 Github&#xff1a;wnhyang - Overview 簡介 標題其實是不準確的&#xff0c;了解過的會知道在LiteFlow的2.12.0已經有了決策路由的特性&…

【TB作品】MSP430 G2553 單片機口袋板,讀取單片機P1.4電壓顯示,ADC,電壓表

功能 讀取P1.4電壓&#xff0c;顯示到口袋板顯示屏&#xff0c;電壓越高亮燈越多。 部分程序 while (1){ADC10CTL0 | ENC ADC10SC; // Sampling and conversion startLPM0;adcvalue ADC10MEM; //原始數據 0到1023adtest (float) adcvalue / 1024.…

【算法訓練 day48 零錢兌換、完全平方數】

目錄 一、零錢兌換-LeetCode 322思路實現代碼問題總結 二、完全平方數-LeetCode 279思路實現代碼問題總結 一、零錢兌換-LeetCode 322 Leecode鏈接: leetcode 322 文章鏈接: 代碼隨想錄 視頻鏈接: B站 給你一個整數數組 coins &#xff0c;表示不同面額的硬幣&#xff1b;以及…

每一個企業,都值得擁有自己專屬的AI大模型!

前言 在數字化浪潮席卷全球的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是遙不可及的科幻概念&#xff0c;而是成為了企業創新、轉型、升級的必備工具。尤其是AI大模型&#xff0c;憑借其強大的數據處理能力和深度學習能力&#xff0c;正在為企業帶來前所未有…

【2024最新華為OD-C/D卷試題匯總】[支持在線評測] 字符串序列判定(100分) - 三語言AC題解(Python/Java/Cpp)

?? 大家好這里是清隆學長 ,一枚熱愛算法的程序員 ? 本系列打算持續跟新華為OD-C/D卷的三語言AC題解 ?? ACM銀牌??| 多次AK大廠筆試 | 編程一對一輔導 ?? 感謝大家的訂閱? 和 喜歡?? ??在線評測鏈接 字符串序列判定(100分) ?? 評測功能需要訂閱專欄后私信聯系…

Leetcode:四數之和

題目鏈接&#xff1a;18. 四數之和 - 力扣&#xff08;LeetCode&#xff09; 普通版本&#xff08;排序 雙指針&#xff09; 主旨&#xff1a;類似于三數之和的解法&#xff0c;但需要多加一些限制&#xff0c;同時為了防止多個數組元素的相加之和出現整型溢出問題還要將整型…

基于python可伸縮JSON格式列表實現

對于消息體為一個json格式列表&#xff0c;列表長度變化的代碼設計&#xff0c;如下實現可供參考。 1、python語言實現(直接取值) #codingutf-8n 2 # 行項目數 productCode [11111,222222,333333] unit [H06,H07,H08] qty [6,7,8] items []for i in range(0, n):item …

數據分析每周挑戰——心衰患者特征數據集

這是一篇關于醫學數據的數據分析&#xff0c;但是這個數據集數據不是很多。 背景描述 本數據集包含了多個與心力衰竭相關的特征&#xff0c;用于分析和預測患者心力衰竭發作的風險。數據集涵蓋了從40歲到95歲不等年齡的患者群體&#xff0c;提供了廣泛的生理和生活方式指標&a…

spring事務實現原理

Spring事務的實現原理主要是基于AOP&#xff08;面向切面編程&#xff09; 事務的開啟與提交/回滾 開啟事務&#xff1a;當Spring容器中的AOP代理檢測到一個匹配的切點方法被調用時&#xff0c;它會首先開啟一個新的事務或者加入到現有的事務中&#xff08;這取決于事務傳播行…

【讀腦儀game】

讀腦儀&#xff08;Brain-Computer Interface&#xff0c;BCI&#xff09;游戲是一種利用腦電信號來控制游戲的新型交互方式。這類游戲通常需要專業的硬件設備來讀取用戶的腦電信號&#xff0c;并將這些信號轉化為游戲中的控制信號。編寫這樣的游戲代碼涉及到多個方面&#xff…

瀚高數據庫相關設置

瀚高數據庫相關設置 一、配置瀚高數據庫局域網訪問 需要修改兩個文件&#xff1a;postgresql.conf和pg_hba.conf 1&#xff09;在postgresql.conf中找到下述配置&#xff0c;把listen_addresses前面的注釋去掉&#xff0c;值修改為* # - Connection Settings -#listen_addresse…

IO進程線程(九)線程的同步 進程間通信

文章目錄 一、 線程的同步&#xff08;一&#xff09;無名信號量sem1. 定義和初始化2.獲取信號量3.釋放信號量4. 銷毀5. 使用示例 &#xff08;二&#xff09;條件變量1. 定義和初始化2. 獲取條件變量3. 釋放條件變量4. 銷毀條件變量 二、進程間通信&#xff08;一&#xff09;…

web-上傳項目文件夾到Git遠程倉庫

Git初識 概念&#xff1a;一個免費開源&#xff0c;分布式的代碼版本控制系統&#xff0c;幫助開發團隊維護代碼 作用&#xff1a;記錄代碼內容&#xff0c;切換代碼版本&#xff0c;多人開發時高效合并代碼內容 檢驗成功 打開bash終端&#xff08;git專用&#xff09;命令…

12. MySQL 日志

文章目錄 【 1. 日志的基本原理 】【 2. 錯誤日志 Error Log 】2.1 啟動和設置錯誤日志2.2 查看錯誤日志2.3 刪除錯誤日志 【 3. 二進制日志 Binary Log 】3.1 啟動和設置二進制日志3.2 查看二進制日志3.3 刪除二進制文件刪除所有二進制日志刪除小于指定編號的二進制日志刪除創…

【vue3+pinia+uniapp項目問題:使用pinia狀態管理時store的數據更新,模板渲染視圖不能實時更新】

在這里選擇不同的學校后&#xff0c;發現store里面的數據打印出來能更新&#xff0c;但是使用store的數據打印出來并未實時更新且渲染在模板上&#xff0c;必須手動刷新視圖才能更新。 原因是因為使用了解構賦值傳入參數 解決方法 1.使用computed 現在視圖能進行實時更新…

分享一個 .Net core Console 項目使用 SqlSugar 的詳細例子

前言 SqlSugar 是一款老牌的 .NET 開源 ORM 框架&#xff0c;性能高&#xff0c;功能全面&#xff0c;使用簡單&#xff0c;支持 .NET FrameWork、.NET Core3.1、.NET5、.NET6、.NET7、.NET8、.NET9 等版本&#xff0c;線上論壇非常活躍&#xff0c;今天給大伙分享一個 .Net c…

查看遠程桌面端口,查看服務器的遠程桌面端口的方法

如果你正在尋找一種方法來檢查服務器的遠程桌面端口&#xff0c;那么請務必按照以下步驟操作&#xff0c;以確保準確且安全地獲取所需信息。這不僅是一個技術問題&#xff0c;更是一個關于效率和安全性的重要議題。 首先&#xff0c;你需要明確&#xff0c;遠程桌面端口通常是…

回溯算法之遞增子數列

題目&#xff1a; 給你一個整數數組 nums &#xff0c;找出并返回所有該數組中不同的遞增子序列&#xff0c;遞增子序列中 至少有兩個元素 。你可以按 任意順序 返回答案。 數組中可能含有重復元素&#xff0c;如出現兩個整數相等&#xff0c;也可以視作遞增序列的一種特殊情…