08_排序

基本概念與分類

假設含有n個記錄的序列為 { r 1 , r 2 , . . . , r n } \{r_1,r_2,...,r_n\} {r1?,r2?,...,rn?},其相應的關鍵字分別為 { k 1 , k 2 , . . . , k n } \{k_1,k_2,...,k_n\} {k1?,k2?,...,kn?},需確定1,2,…,n的一種排列 p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1?,p2?,...,pn?,使其相應的關鍵字滿足 k p 1 ≤ k p 2 ≤ . . . ≤ k p n k_{p1}\leq k_{p2}\leq ... \leq k_{pn} kp1?kp2?...kpn?(非遞減或遞增)關系,即使得序列成為一個按關鍵字有序的序列 { r p 1 , r p 2 , . . . , r p n } \{r_{p1},r_{p2},...,r_{pn}\} {rp1?,rp2?,...,rpn?},這樣的操作稱為排序。

排序的穩定性

假設 r i = r j ( 1 ≤ i ≤ n , i ≤ j ≤ n , i ≠ j ) r_i=r_j(1 \leq i \leq n,i \leq j \leq n,i \neq j) ri?=rj?(1in,ijn,i=j),且在排序前的序列中 r i r_i ri?領先與 r j r_j rj?。如果排序后 r i r_i ri?仍然領先與 r j r_j rj?,則稱所用的排序方法是穩定的;反之則是不穩定的。

內排序與外排序

內排序是在排序整個過程中,待排序的所有記錄全部被就置在內存中 。外排序是由于排序的記錄個數太多 , 不能同時放置在內存,整個排序過程需要在內外存之間多次交換數據才能進行。

排序用到的結構與函數

#define MAXSIZE 10    /* 用于要排序數組個數最大值,可以根據需要修改 */
typedef struct
{int r[MAXSIZE+1]; /* 存儲要排序的數組,r[0]用作哨兵或臨時變量 */int length;       /* 用于記錄順表的長度 */
}SqList;
/* 交換L中數組r的下標為i和j的值 */
void swap(SqList * L,int i,int j) 
{int temp=L->r[i];L->r[i]=L->r[j];L->r[j]=temp;
}

冒泡排序

冒泡排序(Bubble Sort)一種交換排序,它的基本思想是:兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序的記錄為止。

/* 對順序表L作交換排序(冒泡排序初級版) */
void BubbleSort0(SqList *L)
{int i,j;for(i=1;i<L->length;i++){for(j=i+1;j<L->length;j++){if(L->r[i]>L->r[j]){swap(L,i,j);}}}
}
/* 對順序表L作交換排序(冒泡排序改進版) */
void BubbleSort(SqList *L)
{int i,j;for(i=1;i<L->length;i++){for(j=L->length-1;j>=i;j--) /* 注意j是從后向前循環 */{if(L->r[j]>L->r[j+1])   /* 若前者大于后者(注意這里與上一算法的差異) */{swap(L,j,j+1);}}}
}
/* 對順序表L作交換排序(冒泡排序優化版) */
void BubbleSort2(SqList *L)
{int i,j;bool flag = true;				/* flag用來作為標記 */for(i=1;i<L->length && flag ;i++) /* flag為false,則退出循環 */{flag = false;				/* 初始化false */for(j=L->length-1;j>=i;j--) {if(L->r[j]>L->r[j+1])   {swap(L,j,j+1);flag = true; /* 如果有數據交換,則flag為true */}}}
}

冒泡排序算法的時間復雜度:KaTeX parse error: Expected group after '_' at position 5: \sum_?\limits{i=2}^{n…,總的時間復雜度為 O ( n 2 ) O(n^2) O(n2)

簡單選擇排序

簡單選擇排序法(Simple Selection Sort)就是通過 n ? i n-i n?i 次關鍵字間的比較,從 n ? i + 1 n-i+1 n?i+1 記錄中選出關鍵字最小的記錄,并和第 i ( 1 ≤ i ≤ n ) i(1\leq i \leq n) i(1in) 個記錄交換。

/* 對順序表L作簡單選擇排序 */
void SelectSort(SqList * L) {int i,j,min;for(i=1;i<L->length;i++){min = i;     				   /* 將當前下標定義為最小值下標 */for(j = i+1;j<=L->length;j++){ /* 循環之后的數據 */if(L->r[min]>L->r[j])      /* 如果有小于當前最小值的關鍵字 */min = j;   			   /* 將此關鍵字的下標賦值給min */}if(i != min)				   /* 若min不等于i,說明找到最小值,交換 */swap(L,i,min)			   /* 交換L->r[i]與L->r[min]的值 */}
}

簡單選擇排序算法的時間復雜度:KaTeX parse error: Expected group after '_' at position 5: \sum_?\limits{i=1}^{n…,總的時間復雜度為 O ( n 2 ) O(n^2) O(n2)

盡管與冒泡排序同為 O ( n 2 ) O(n^2) O(n2),但簡單選擇排序的性能上還是略優于冒泡排序。

直接插入排序

直接插入排序(Straight Insertion Sort)的基本操作是將一個記錄插入到已經排好序的有序表中,從而得到一個新的、記錄數增加1的有序表。

/* 對順序表L作直接插入排序 */
void InsertSort(SqList * L) {int i,j;for(i=2;i<L->length;i++){if(L->r[i] < L->r[i-1]){ /* 需將L->r[i]插入有序子表 */L->r[0]=L->r[i];	 /* 設置哨兵 */for(j=i-1;L->r[j]>L->r[0];j--)L->r[j+1] = L->r[j]; /* 記錄后移 */L->r[j+1] = L->r[0];     /* 插入到正確位置 */}}
}

最好情況(有序表本身有序)下的算法復雜度: n ? 1 ( ∑ i = 2 n 1 ) n-1(\sum_{i=2}^n1) n?1(i=2n?1) ,時間復雜度為O(n)

最壞情況(有序表是逆序)下的算法復雜度:比較 KaTeX parse error: Expected group after '_' at position 5: \sum_?\limits{(i=2)}^…次,記錄移動KaTeX parse error: Expected group after '_' at position 5: \sum_?\limits{i=2}^{n…

如果排序記錄是隨機的,那么根據概率相同的原則,平均比較和移動次數約為 n 2 4 \frac{n^2}4 4n2?。直接插入排序法的時間復雜度為 O ( n 2 ) O(n^2) O(n2) ,直接插入排序法比冒炮和簡單選擇排序的性能要好一些。

希爾排序算法

  1. 將原本有大量記錄數的記錄進行分組,分割成若干個子序列。

  2. 在這些子序列內進行插入排序,當整個序列基本有序時,再對全體記錄進行一次直接插入排序

    所謂的基本有序,就是小的關鍵字基本在前面,大的基本在后面,不大不小的基本在中間。

/* 對順序表L作希爾排序 */
void ShellSort(SqList * L)
{int i,j;int increment = L->length;do{increment = increment/3 +1;  /*增量序列*/for(i = increment +1;i<=L->length;i++){if(L->r[i] < L->r[i-increment]){/* 需將L->r[i] 插入有序增量子表 */L->r[0] = L->r[i]; /* 暫存在L->r[0] */for(j=i-increment;j>0 && L->r[0]< L->r[j];j-=increment)L->r[j+increment] = L->r[j]; /* 記錄后移,查找插入位置 */L->r[j+increment] = L->r[0]; /* 插入 */}}        }while(increment > 1);
}

希爾排序的關鍵并不是隨便分組后各自排序,而是將相隔某個"增最’'的記錄組成一個子序列, 實現跳躍式的移動,使得排序的效率提高 。

這里"增量"的選取就非常關鍵,當增量序列為 d l t a [ k ] = 2 t ? k + 1 ? 1 ( 0 ≤ k ≤ t ≤ [ l o g 2 ( n + 1 ) ] ) dlta[k] = 2^{t-k+1}-1 (0\leq k \leq t \leq [log_2(n+1)]) dlta[k]=2t?k+1?1(0kt[log2?(n+1)]) 時,可以獲得不錯的效率。

希爾排序并不是一直穩定排序,時間復雜度為 O ( n 3 / 2 ) O(n^{3/2}) O(n3/2)

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

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

相關文章

微服務: Nacos部署安裝與properties配置

Nacos 是阿里巴巴開源的一款用于動態服務發現、配置管理和服務管理的基礎設施。Nacos 這個名稱源自于 “Dynamic Naming and Configuration Service”。它主要是用于解決微服務架構中服務發現和配置管理的問題。 Nacos 單機模式的部署安裝 1. 安裝(Windows環境) Nacos是Java…

Java線程基礎知識總結

基礎概念 Java 線程是并發編程的基礎&#xff0c;涉及到線程的創建、管理、同步以及通信。理解和掌握線程的使用對于編寫高效和響應快速的應用程序至關重要。 1. 線程基礎 線程是程序中的執行流。每個Java程序至少有一個線程 — 主線程&#xff08;main&#xff09;。通過使…

從入門到深入,Docker新手學習教程

編譯整理&#xff5c;TesterHome社區 作者&#xff5c;Ishaan Gupta 以下為作者觀點&#xff1a; Docker 徹底改變了我們開發、交付和運行應用程序的方式。它使開發人員能夠將應用程序打包到容器中 - 標準化的可執行組件&#xff0c;將應用程序源代碼與在任何環境中運行該代碼…

InspireFace-商用級的跨平臺開源人臉分析SDK

InspireFace-商用級的跨平臺開源人臉分析SDK InspireFaceSDK是由insightface開發的?款?臉識別軟件開發?具包&#xff08;SDK&#xff09;。它提供了?系列功能&#xff0c;可以滿?各種應?場景下的?臉識別需求&#xff0c;包括但不限于閘機、?臉?禁、?臉驗證等。 該S…

ubuntu22 sshd設置

專欄總目錄 一、安裝sshd服務 sudo apt updatesudo apt install -y openssh-server 二、配置sshd 使用文本編輯器打開/etc/ssh/sshd_config sudo vi /etc/ssh/sshd_config &#xff08;一&#xff09;配置sshd服務的偵聽端口 建議將ssh的偵聽端口改為7000以上的端口&#…

【bazel】快速下載教程

bazel下載鏈接&#xff1a; https://github.com/bazelbuild/bazel/releases?page11 直接在github上下載&#xff0c;會因為網絡不穩定&#xff0c;而頻繁下載錯誤 這里提供一個超級快速的方法&#xff01;&#xff01;&#xff01; 用迅雷下載&#xff01; 1.從github上復…

cpp http server/client

httplib 使用httplib庫 basedemo server.cpp #include "httplib.h" #include <iostream> using namespace httplib;int main(void) {Server svr;svr.Get("/hello", [](const Request& req, Response& res) {std::cout << "lo…

實現Java Web應用的高性能負載均衡方案

實現Java Web應用的高性能負載均衡方案 大家好&#xff0c;我是微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在高并發的網絡環境中&#xff0c;負載均衡是確保Web應用程序高性能和可靠性的關鍵策略之一。本文將探討如何…

【力扣 - 每日一題】3115. 質數的最大距離(一次遍歷、頭尾遍歷、空間換時間、埃式篩、歐拉篩、打表)Golang實現

原題鏈接 題目描述 給你一個整數數組 nums。 返回兩個&#xff08;不一定不同的&#xff09;質數在 nums 中 下標 的 最大距離。 示例 1&#xff1a; 輸入&#xff1a; nums [4,2,9,5,3] 輸出&#xff1a; 3 解釋&#xff1a; nums[1]、nums[3] 和 nums[4] 是質數。因此答…

算法系列--分治排序|再談快速排序|快速排序的優化|快速選擇算法

前言:本文就前期學習快速排序算法的一些疑惑點進行詳細解答,并且給出基礎快速排序算法的優化版本 一.再談快速排序 快速排序算法的核心是分治思想,分治策略分為以下三步: 分解:將原問題分解為若干相似,規模較小的子問題解決:如果子問題規模較小,直接解決;否則遞歸解決子問題合…

策略模式的應用

前言 系統有一個需求就是采購員審批注冊供應商的信息時&#xff0c;會生成一個供應商的賬號&#xff0c;此時需要發送供應商的賬號信息&#xff08;賬號、密碼&#xff09;到注冊填寫的郵箱中&#xff0c;通知供應商賬號信息&#xff0c;當時很快就寫好了一個工具類&#xff0…

Python 學習中什么是字典,如何操作字典?

什么是字典 字典&#xff08;Dictionary&#xff09;是Python中的一種內置數據結構&#xff0c;用于存儲鍵值對&#xff08;key-value pair&#xff09;。字典的特點是通過鍵來快速查找值&#xff0c;鍵必須是唯一的&#xff0c;而值可以是任何數據類型。字典在其他編程語言中…

vue實現搜索文章關鍵字,滑到指定位置并且高亮

1、輸入搜索條件&#xff0c;點擊搜索按鈕 2、滑到定位到指定的搜索條件。 <template><div><div class"search_form"><el-inputv-model"searchVal"placeholder"請輸入關鍵字查詢"clearablesize"small"style&quo…

HashMap的底層實現原理詳解

HashMap是Java中最常用的集合類之一&#xff0c;其基于哈希表的Map接口實現&#xff0c;提供了快速的鍵值對存儲和檢索功能。深入理解HashMap的底層實現原理&#xff0c;對于提升編程技能、應對技術面試以及優化程序性能都具有重要意義。以下從技術難點、面試官關注點、回答吸引…

數據庫作業day3

創建一個student表用于存儲學生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); 向student表中添加一條新記錄 記錄中id字段的值為1&#xff0c;name字段的值為"monkey"&#xff0c;grade字段的值為98.5 insert into …

對于老百姓而言VR到底能做什么?

VR技術自誕生以來不斷發展&#xff0c;已經廣泛應用于教育、醫療、工程、軍事、航空、航海、影視、娛樂等方面&#xff0c;譬如&#xff0c;大型工程或軍事活動VR預演可以大幅度減少人力物力投入&#xff1b;在航空領域&#xff0c;航天飛行員在訓練艙中面對屏幕進行各種駕駛操…

mysql修改密碼失敗報錯無法登錄解決辦法

mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user root@localhost (using password: YES) 這個問題是因為在嘗試使用命令行連接MySQL時,使用了明文密碼,這是不安全的。同時,由于某種原因,您…

Kylin中的查詢引擎:大數據查詢加速的引擎解析

Kylin中的查詢引擎&#xff1a;大數據查詢加速的引擎解析 Apache Kylin是一個開源的分布式分析引擎&#xff0c;專為大規模數據集提供快速的SQL查詢和多維分析&#xff08;OLAP&#xff09;能力。在Kylin的架構中&#xff0c;查詢引擎&#xff08;Query Engine&#xff09;扮演…

【Linux進階】文件系統4——文件系統特性

1.磁盤組成與分區的復習 首先說明一下磁盤的物理組成&#xff0c;整塊磁盤的組成主要有&#xff1a; 圓形的碟片&#xff08;主要記錄數據的部分&#xff09;&#xff1b;機械手臂&#xff0c;與在機械手臂上的磁頭&#xff08;可擦寫碟片上的數據);主軸馬達&#xff0c;可以…

打開瀏覽器控制臺,點擊應用,瀏覽器崩潰

調試的時候&#xff0c;打開控制臺&#xff0c;點擊 “應用” 立馬瀏覽器奔潰&#xff0c;但是點擊別的沒問題 調查發現是因為manifest.json這個文件引起的 manifest.json 最主要的原因是因為沒有設置這個sizes字段 Google瀏覽器更新大概到126之后的版本會有問題&#xff0c;之…