冒泡排序與其C語言通用連續類型排序代碼

冒泡排序與其C語言通用連續類型排序代碼

  • 冒泡排序
    • 冒泡排序為交換排序的一種:
    • 動圖展示:
    • 冒泡排序的特性總結:
    • 冒泡排序排整型數據參考代碼(VS2022C語言環境):
  • 冒泡排序C語言通用連續類型排序代碼
    • 對比較的方式更改:
    • 對交換的方式更改:
    • 結果驗證:
      • 內置類型:
      • 自定義類型:
    • 注意:

冒泡排序

冒泡排序為交換排序的一種:

  1. 基本思想:所謂交換,就是根據序列中兩個記錄鍵值的比較結果來對換這兩個記錄在序列中的位置。
  2. 交換排序的特點是:將鍵值較大的記錄向序列的尾部移動,鍵值較小的記錄向序列的前部移動。

而冒泡排序升序時每遍歷一次會將未排好的集合中大的值移動到后面(或小的移到前面),直到排好序。

動圖展示:

在這里插入圖片描述

冒泡排序的特性總結:

  1. 冒泡排序是一種非常容易理解的排序
  2. 時間復雜度:O(N ^ 2)
  3. 空間復雜度:O(1)
  4. 穩定性:穩定

冒泡排序排整型數據參考代碼(VS2022C語言環境):

#include <stdio.h>
#include <stdbool.h>void swap(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;
}//			要排序的數組	 數組大小
int bubbleSort(int* arr, int sz)
{// 1.n個數中,每次交換前需要比較兩個數字,則比較次數為n - 1for (int i = 0; i < sz - 1; ++i){bool flag = true;						// 3.檢查是否有序// 2.在 “1.” 的基礎之上,i每循環一次,必定有一個數排好到后面,則 “- i" 來優化for (int j = 0; j < sz - 1 - i; ++j){if (arr[j] > arr[j + 1]){flag = false;					// 3.表示無序swap(&arr[j], &arr[j + 1]);}}if (flag == true)						// 3.有序直接退出循環{break;}}
}int main()
{int arr[10] = { 3, 9, 2, 7, 8, 5, 6, 1, 10, 4 };int sz = 10;bubbleSort(arr, sz);for (int i = 0; i < sz; ++i){printf("%d ", arr[i]);}return 0;
}

冒泡排序C語言通用連續類型排序代碼

上述C語言冒泡排序代碼只支持整型排序,這里將其擴展為通用的連續類型排序代碼。

參考C語言內置的qsort排序:
在這里插入圖片描述

可以得到函數為:
在這里插入圖片描述

void swap(char* a, char* b, size_t width)
{for (int i = 0; i < width; ++i){char temp = *(a + i);*(a + i) = *(b + i);*(b + i) = temp;}
}//			要排序的數組	   數組大小	   每個元素寬度		比較的函數指針
int bubbleSort(void* base, size_t sz, size_t width, int (*compare)(const void* e1, const void* e2))
{// 1.n個數中,每次交換前需要比較兩個數字,則比較次數為n - 1for (int i = 0; i < sz - 1; ++i){bool flag = true;						// 3.檢查是否有序// 2.在 “1.” 的基礎之上,i每循環一次,必定有一個數排好到后面,則 “- i" 來優化for (int j = 0; j < sz - 1 - i; ++j){if (compare((char*)base + j * width, (char*)base + j * width + width) > 0){flag = false;					// 3.表示無序swap((char*)base + j * width, (char*)base + j * width + width, width);}}if (flag == true)						// 3.有序直接退出循環{break;}}
}

事實上,我們只需要對其兩個地方大幅度更改,就可以得到通用的排序:

對比較的方式更改:

將比較方式改為函數指針的方式,這樣使用者使用時可以自己寫比較的類型函數(不僅包含內置類型,struct 定義的也可以,但前提是連續的
在這里插入圖片描述

在這里插入圖片描述
如果使用者對整型排序,則自己寫的compare為(只供參考,方法不唯一):

int cmp(const void* e1, const void* e2)
{// (int*)e1 表示將泛型指針轉為整型指針// *((int*)e1) 表示對整型指針解引用從而得到整型的數 // 兩整型的數相減,為正則e1大,為負則e2大,為0則相等return *((int*)e1) - *((int*)e2);
}

對交換的方式更改:

這里只需將交換方式改為一個字節一個字節的方式交換即可。
在這里插入圖片描述
在這里插入圖片描述
則swap應改為:

void swap(char* a, char* b, size_t width)
{// a 和 b 表示兩個數開始的地址// a + i 表示 a 元素第 i 塊字節的地址,同理于b// *(a + i) 表示 a 元素第 i 塊字節的內容,同理于b// 通過一個字節一個字節的交換,確保內容不會丟失for (int i = 0; i < width; ++i){char temp = *(a + i);*(a + i) = *(b + i);*(b + i) = temp;}
}

結果驗證:

內置類型:

在這里插入圖片描述
在這里插入圖片描述

完整代碼:

#include <stdio.h>
#include <stdbool.h>void swap(char* a, char* b, size_t width)
{for (int i = 0; i < width; ++i){char temp = *(a + i);*(a + i) = *(b + i);*(b + i) = temp;}
}//			要排序的數組	   數組大小	   每個元素寬度		比較的函數指針
int bubbleSort(void* base, size_t sz, size_t width, int (*compare)(const void* e1, const void* e2))
{// 1.n個數中,每次交換前需要比較兩個數字,則比較次數為n - 1for (int i = 0; i < sz - 1; ++i){bool flag = true;						// 3.檢查是否有序// 2.在 “1.” 的基礎之上,i每循環一次,必定有一個數排好到后面,則 “- i" 來優化for (int j = 0; j < sz - 1 - i; ++j){if (compare((char*)base + j * width, (char*)base + j * width + width) > 0){flag = false;					// 3.表示無序swap((char*)base + j * width, (char*)base + j * width + width, width);}}if (flag == true)						// 3.有序直接退出循環{break;}}
}int cmp(const void* e1, const void* e2)			// 對整形
{return *((int*)e1) - *((int*)e2);
}int cmp1(const void* e1, const void* e2)		// 對字符
{return *((char*)e1) - *((char*)e2);
}int cmp2(const void* e1, const void* e2)		// 對浮點
{double num1 = *(double*)e1;double num2 = *(double*)e2;// double 返回與 int 沖突會影響,只需更改一下返回邏輯return num1 > num2 ? 1 : -1;
}int main()
{int arr[10] = { 3, 9, 2, 7, 8, 5, 6, 1, 10, 4 };int sz = 10;bubbleSort(arr, sz, sizeof(int), cmp);for (int i = 0; i < sz; ++i){printf("%d ", arr[i]);}printf("\n");char arr1[10] = { 3, 9, 2, 7, 8, 5, 6, 1, 10, 4 };double arr2[10] = { 3.1, 9.4, 2.9, 7.8, 8.8, 5.1, 6.2, 1.0, 10.1, 4.4 };bubbleSort(arr1, sz, sizeof(char), cmp1);bubbleSort(arr2, sz, sizeof(double), cmp2);for (int i = 0; i < sz; ++i){printf("%d ", arr1[i]);}printf("\n");for (int i = 0; i < sz; ++i){printf("%.2lf ", arr2[i]);}printf("\n");return 0;
}

自定義類型:

在這里插入圖片描述

在這里插入圖片描述
完整代碼:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>void swap(char* a, char* b, size_t width)
{for (int i = 0; i < width; ++i){char temp = *(a + i);*(a + i) = *(b + i);*(b + i) = temp;}
}//			要排序的數組	   數組大小	   每個元素寬度		比較的函數指針
int bubbleSort(void* base, size_t sz, size_t width, int (*compare)(const void* e1, const void* e2))
{// 1.n個數中,每次交換前需要比較兩個數字,則比較次數為n - 1for (int i = 0; i < sz - 1; ++i){bool flag = true;						// 3.檢查是否有序// 2.在 “1.” 的基礎之上,i每循環一次,必定有一個數排好到后面,則 “- i" 來優化for (int j = 0; j < sz - 1 - i; ++j){if (compare((char*)base + j * width, (char*)base + j * width + width) > 0){flag = false;					// 3.表示無序swap((char*)base + j * width, (char*)base + j * width + width, width);}}if (flag == true)						// 3.有序直接退出循環{break;}}
}typedef struct Student
{char name[20];int age;char id[10];
} Student;int cmpAge(const void* e1, const void* e2)
{return ((Student*)e1)->age - ((Student*)e2)->age;
}int cmpId(const void* e1, const void* e2)
{return strcmp(((Student*)e1)->id, ((Student*)e2)->id);
}int main()
{Student arr[5] = {{.name = "張三", .age = 20, .id = "1" },{.name = "李四", .age = 21, .id = "2" },{.name = "王二", .age = 18, .id = "3" },{.name = "麻子", .age = 30, .id = "4" } };int sz = 4;bubbleSort(arr, sz, sizeof(Student), cmpAge);printf("以年齡排序:\n");for (int i = 0; i < sz; ++i){printf("%s ", arr[i].name);printf("%d ", arr[i].age);printf("%s\n", arr[i].id);}printf("\n");bubbleSort(arr, sz, sizeof(Student), cmpId);printf("以ID排序:\n");for (int i = 0; i < sz; ++i){printf("%s ", arr[i].name);printf("%d ", arr[i].age);printf("%s\n", arr[i].id);}printf("\n");return 0;
}

注意:

上述代碼對不連續的數據無效,如鏈表的每個元素是以指針連接存儲的,compare函數 和 swap函數 需要更改來解決。

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

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

相關文章

法律行業守護神:知識庫+AI大模型,解鎖企業知識全周期管理

在法律行業中&#xff0c;搭建一個有效的知識庫并進行企業知識全生命周期管理確實是一項不小的挑戰。法律環境的復雜性和不斷變化的法規要求企業必須持續更新和維護其知識庫&#xff0c;以確保所有信息的準確性和實時性。 這種系統化的信息管理不僅有助于提高律師和法律顧問的…

打卡第9天-----字符串

我在自學的時候,看了卡爾的算法公開課了,有些題目我就照葫蘆畫瓢寫了一遍js代碼,差不多都寫出來了,有暴力解法,有卡爾推薦的思路和方法。話不多說,直接上題上代碼吧: 一、翻轉字符串里的單詞 leetcode題目鏈接:151. 反轉字符串中的單詞 題目描述: 給你一個字符串 s…

5個自動化面試題,助你過關斬將!

面試時&#xff0c;自動化是軟件測試高頻面試內容&#xff0c;通過學習和準備面試題&#xff0c;你會對可能遇到的問題有所準備&#xff0c;從而減輕面試時的緊張感&#xff0c;讓你在面試中穩操勝券&#xff01; 今天&#xff0c;分享一些在面試中可能會遇到的自動化測試面試…

軟件架構之測評方法

軟件架構之測評方法 第 11 章&#xff1a;測試評審方法11.1 測試方法11.1.1 軟件測試階段11.1.2 白盒測試和黑盒測試11.1.3 缺陷的分類和級別11.1.4 調試 11.2 評審方法11.3 驗證與確認11.4 測試自動化11.5 面向對象的測試 第 11 章&#xff1a;測試評審方法 軟件測試與評審是…

大學生暑假“三下鄉”社會實踐工作新聞投稿指南請查收!

近年來&#xff0c;大學生暑期“三下鄉”社會實踐工作方興未艾&#xff0c;越來越多的大學生通過參與“三下鄉”實踐工作&#xff0c;走出校園&#xff0c;深入基層&#xff0c;體驗農村生活&#xff0c;服務農民&#xff0c;促進農村經濟社會發展&#xff0c;實現了理論與實踐…

算能科技,致力于成為全球領先的通用算力供應商

算能致力于成為全球領先的定制算力提供商&#xff0c;專注于RISC-V、TPU處理器等算力產品的研發和推廣應用。公司遵循全面開源開放的生態理念&#xff0c;攜手行業伙伴推動RISC-V高性能通用計算產業落地&#xff1b;打造覆蓋“云、邊、端”的全場景產品矩陣&#xff0c;為數據中…

【eNSP模擬實驗】三層交換機實現VLAN通信

實驗需求 讓PC1和PC2能夠互相通訊&#xff0c;其中PC1在vlan10中&#xff0c;PC2在vlan20中。 實驗操作 首先把PC1和PC2都配置好ip&#xff0c;配置好之后&#xff0c;點擊右下角的應用 然后&#xff0c;在S2交換機&#xff08;S3700&#xff09;上做如下配置 #進入系統 <…

mvvm模式

MVVM&#xff08;Model-View-ViewModel&#xff09;模式是一種軟件設計模式&#xff0c;特別適用于構建用戶界面&#xff08;UI&#xff09;應用程序&#xff0c;尤其是使用WPF&#xff08;Windows Presentation Foundation&#xff09;、Silverlight和其他XAML技術的應用程序。…

【Redis】Redis十大類型

文章目錄 前言一、string字符串類型二、List列表類型三、 Hash表四、 Set集合五、 ZSet有序集合六、 GEO地理空間七、 HyperLogLog基數統計八、Bitmap位圖九、bitfield位域十、 Stream流10.1 隊列指令10.2 消費組指令10.3 ACK機制 前言 redis是k-v鍵值對進行存儲&#xff0c;k…

Mac上pyenv的安裝及使用

Mac上pyenv的安裝及使用 安裝 brew update brew install pyenv 報錯 git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallowgit -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow那就執行這2句 還報錯 git -C /…

【最經典的79個】軟件測試面試題(內含答案)提前備戰“金九銀十”

001.軟件的生命周期(prdctrm) 計劃階段(planning)-〉需求分析(requirement)-〉設計階段(design)-〉編碼(coding)->測試(testing)->運行與維護(running maintrnacne) 測試用例 用例編號 測試項目 測試標題 重要級別 預置條件 輸入數據 執行步驟 預期結果 0002.問&…

“論軟件維護方法及其應用”寫作框架,軟考高級論文,系統架構設計師論文

論文真題 軟件維護是指在軟件交付使用后&#xff0c;直至軟件被淘汰的整個時間范圍內&#xff0c;為了改正錯誤或滿足 新的需求而修改軟件的活動。在軟件系統運行過程中&#xff0c;軟件需要維護的原因是多種多樣的&#xff0c; 根據維護的原因不同&#xff0c;可以將軟件維護…

CVE-2024-34351 漏洞復現

CVE-2024-34351&#xff0c;由Next.js異步函數createRedirectRenderResult導致的SSRF。 影響版本&#xff1a;13.4.0< Next.js < 14.1.1 參考文章&#xff1a; Next.js Server-Side Request Forgery in Server Actions CVE-2024-34351 GitHub Advisory Database Gi…

數據庫Doris的手動分桶和自動分桶

在Doris中,分桶(Bucketing)是為了更好地管理和查詢數據,將數據分成多個小的邏輯單元。分桶可以通過手動或自動的方式進行配置,每種方式各有其特點和適用場景。 Doris 支持兩層的數據劃分。第一層是分區(Partition),支持 Range 和 List 的劃分方式。第二層是Bucket(Tab…

RK3568平臺開發系列講解(內存篇)Linux進程內存的消耗統計

??返回專欄總目錄 文章目錄 一、VSS(Virtual Set Size)二、RSS(Resident Set Size)三、PSS(Proportional Set Size)四、USS(Unique Set Size)五、其他工具Linux 提供了多種進程內存占用的度量指標, 它們反映了不同的內存使用特征: VSS 反映進程虛擬內存總需求, 包括未…

2.python條件語句與循環

1.概述 通過條件語句來判斷&#xff0c;條件成立執行某些代碼&#xff0c;條件不成立則不執行這些代碼 2.if語句 if條件&#xff1a;條件成立執行的代碼...... 下方代碼沒有縮進到if語句塊&#xff0c;所以和if條件無關if…else if條件&#xff1a;條件成立執行的代碼.....…

Nature Communications|柔性無感智能隱形眼鏡(柔性傳感/可穿戴電子/柔性電子)

南京大學徐飛(Fei Xu)、陸延青(Yanqing Lu)、陳燁(Ye Chen)和江蘇省人民醫院袁松濤(Songtao Yuan)團隊,在《Nature Communications》上發布了一篇題為“Frequency-encoded eye tracking smart contact lens for human–machine interaction”的論文。論文內容如下: 一、 摘…

常見的load_file()讀取的敏感信息

常見的load_file()讀取的敏感信息 在編程中或者sql注入時&#xff0c;load_file() 函數通常用于讀取文件內容&#xff0c;而敏感信息的泄露往往是由于不當的使用這個函數或缺乏足夠的安全措施。下面是一些常見的敏感信息及其可能的具體位置&#xff1a; 配置文件&#xff1a; …

一起了解開發表單設計器的幾大優勢

實現提質、降本、增效的辦公效率&#xff0c;可以隨時來了解低代碼技術平臺、開發表單設計器。它們可視化操作界面、更靈活、好維護的優勢特點&#xff0c;使得其在激烈的市場競爭中擁有更多強勁的市場競爭力&#xff0c;是提升辦公效率的理想武器。今天&#xff0c;小編就向大…

BGP第二日

上圖為今日所用拓撲 &#xff0c;其中R1和R4&#xff0c;R3和R5為EBGP鄰居&#xff0c;R1和R3為IBGP鄰居&#xff0c;AS200區域做OSPF動態路由 一.BGP建立鄰居的六種狀態 1.idle 空閑狀態&#xff1a;建立鄰居最初的狀態 2.Connect 連接狀態&#xff1a;在…