用c++實現快速排序、最大子段和問題

6.2.2 快速排序

【問題】快速排序(quick?sort)的分治策略如下(圖6-5)。
(1)劃分:(選定一個記錄作為軸值,以軸值為基準將整個序列劃分為兩個子序列,軸值的位置在劃分的過程中確定,并且左側子序列的所有記錄均小于或等于軸值,右側子序列的所有記錄均大于或等于軸值。
(2)?求解子問題:分別對劃分后的每一個子序列進行遞歸處理。
(3)?合并:由于對子序列的排序是就地進行的,所以合并不需要執行任何操作。

【想法】首先對待排序記錄序列進行劃分,刻分的軸值應該遵循平衡子問題的原則,使劃分后兩個子序列的長度盡量相等。軸值的選擇有很多方法,例如,可以隨機選出一個記錄作為軸值,從而期望劃分是較平衡的。假設以第一個記錄作為軸值,圖6-6給出了、個劃分的例子(黑體框代表軸值)。

????????以軸值為基準將待排序序列劃分為兩個子序列后,對每一個子序列分別進行遞歸處理。圖6-7所示是一個快速排序的完整的例子。

【算法實現】設函數Partition實現對序列r[first]~r[end]進行劃分,函數QuickSort實現快速排序,程序如下。

#include <iostream>
using namespace std;


int Partition(int r[ ], int first, int end)
{
int temp, i = first, j = end;
while (i < j)
{
while (i < j && r[i] <= r[j]) j--; //右側掃描
if (i < j)
{
temp = r[i]; r[i] = r[j]; r[j] = temp; //將較小記錄交換到前面
i++;
}
while (i < j && r[i] <= r[j]) i++; //左側掃描
if (i < j)
{
temp = r[i]; r[i] = r[j]; r[j] = temp; //將較大記錄交換到后面
j--;
}
}
return i; //返回軸值記錄的位置
}

void QuickSort(int r[ ], int first, int end) //快速排序
{
if (first < end)
{
int pivot = Partition(r, first, end); //劃分,pivot是軸值的位置
QuickSort(r, first, pivot-1); //對左側子序列進行快速排序
QuickSort(r, pivot+1, end); //對右側子序列進行快速排序
}
}
int main( )
{
int i, n = 8, r[8] = {8,3,2,6,7,1,5,4};
? ? QuickSort(r, 0, n-1);

? ? for (i = 0; i < n; i++)
? ? ? ? std::cout << r[i] << " "; ?// 打印排序后的元素

? ? std::cout << std::endl;

? ? return 0;
}

?

【算法分析】?最好情況下,每次劃分對一個記錄定位后,該記錄的左側子序列與右側子序列的長度相同。在具有n個記錄的序列中,一次劃分需要對整個待劃分序列掃描一遍,所需時間為O(n),則有:


????????最壞情況下,待排序記錄序列正序或逆序,每次劃分只得到一個比上一次劃分少一個記錄的子序列(另一個子序列為空)。此時,必須經過n-1次遞歸調用才能把所有記錄定位,而且第i趟劃分需要經過n-i次比較才能找到第i個記錄的位置,因此,時間復雜度為:

????????平均情況下,設軸值記錄的關鍵碼第k小(1<=k<=n),則有:

????????這是快速排序的平均時間性能,可以用歸納法證明,其數量級也為O(nlog以2為底n)。
????????由于快速排序是遞歸執行的,需要一個工作棧來存放每一層遞歸調用的必要信息,棧
的最大容量與遞歸調用的深度一致。最好情況下要進行[log以2為底n]次遞歸調用,棧的深度為O(log,n);最壞情況下,要進行n-1次遞歸調用,棧的深度為O(n);平均情況下,棧的深度為O(log以2為底n).

6.3.1??最大子段和問題

應用實例
????????國際期貨市場某種商品在某個月的第1,2,...,31天的價格漲幅分別記為a1,?a2,...,a31,若某天的價格下跌,這天的漲幅就是負值。如果想知道在連續哪些天,該商品的價格具有最高漲幅,究竟漲了多少,這個問題就可以抽象為最大子段和問題。

【算法實現】?最大子段和問題是按照位置進行劃分的,設變量?center?表示序列的中間位置,數組a[n]存放整數序列,程序如下。

#include <iostream>
using namespace std;


int MaxSum(int a[ ], int left, int right)
{
int sum = 0, midSum = 0, leftSum = 0, rightSum = 0;
int i, center, s1, s2, lefts, rights;
if (left == right) //如果序列長度為1,直接求解
sum = a[left];
else
{
center = (left + right)/2; //劃分
leftSum = MaxSum(a, left, center); //對應情況①,遞歸求解
rightSum = MaxSum(a, center+1, right); //對應情況②,遞歸求解
s1 = 0; lefts = 0; //以下對應情況③,先求解s1
for (i = center; i >= left; i--)
{
lefts += a[i];
if (lefts > s1) s1 = lefts;
}
s2 = 0; rights = 0; //再求解s2
for (i = center + 1; i <= right; i++)
{
rights += a[i];
if (rights > s2) s2 = rights;
}
midSum = s1 + s2; //計算情況③的最大子段和
if (midSum < leftSum) sum = leftSum; //合并解,取較大者
else sum = midSum;
if (sum < rightSum) sum = rightSum;
}
return sum;
}
int main( )
{
? int max, n = 6, r[6] = {-20, 11, -4, 13, -5, -2};
? ? max = MaxSum(r, 0, n - 1);
? ? cout << "最大子段和是:" << max << endl;
? ? return 0;

}
?

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

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

相關文章

26 分鐘驚訝世界,GPT-4o 引領未來人機交互

前言 原文鏈接&#xff1a;OpenAI最新模型——GPT-4o&#xff0c;實時語音視頻交互&#xff0c;未來人機交互近在眼前 - Kaiho小站 北京時間 5 月 14 日凌晨&#xff0c;OpenAI 發布新一代模型——GPT-4o&#xff0c;僅在 ChatGPT 面世 17 個月后&#xff0c;OpenAI 再次通過…

qt的udp通訊

QString mylocalip; const QList interfaces QNetworkInterface::allInterfaces(); foreach(QNetworkInterface ip, interfaces) { if (ip.humanReadableName() QStringLiteral(“以太網”)) { //if (ip.type() QNetworkInterface::Ethernet) { const QList iplist ip.addr…

【EasyX】快速入門——靜態圖形篇

1.基本說明 EasyX 是針對 C 的圖形庫&#xff0c;可以幫助 C/C 初學者快速上手圖形和游戲編程。 比如&#xff0c;可以基于 EasyX 圖形庫很快的用幾何圖形畫一個房子&#xff0c;或者一輛移動的小車&#xff0c;可以編寫俄羅斯方塊、貪吃蛇、黑白棋等小游戲&#xff0c;可以練…

Go 注釋生成 api文檔

在 Go 語言中&#xff0c;通常會使用 godoc 工具來從注釋中生成 API 文檔。godoc 是 Go 官方提供的文檔生成工具&#xff0c;它可以解析 Go 源代碼中的注釋&#xff0c;并生成在線的、可交互的文檔。 為了使用 godoc 生成 API 文檔&#xff0c;你需要遵循一些特定的注釋格式。…

使用VMware或VirtualBox安裝eNSP Pro并使用CRT連接設備

文章目錄 使用Oracle Virtual Box安裝eNSP Pro創建虛擬機配置網卡配置帶外管理網絡 使用VMware Workstation安裝eNSP Pro轉換文件格式及虛擬磁盤模式配置網卡創建虛擬機配置使用CRT連接管理設備 前一段時間是開放了eNSP Pro的賬號權限&#xff0c;但是在寫博客時&#xff0c;權…

2024OD機試卷-字符串分割(二) (java\python\c++)

題目:字符串分割(二) 題目描述 給定一個非空字符串S,其被N個‘-’分隔成N+1的子串,給定正整數K,要求除第一個子串外,其余的子串每K個字符組成新的子串,并用‘-’分隔。 對于新組成的每一個子串,如果它含有的小寫字母比大寫字母多,則將這個子串的所有 大寫字母轉換為小…

27.哀家要長腦子了!

目錄 1.316. 去除重復字母 - 力扣&#xff08;LeetCode&#xff09; 2. 1209. 刪除字符串中的所有相鄰重復項 II - 力扣&#xff08;LeetCode 哎喲 煩死了 剛剛不小心退出又沒保存 又要寫一遍 煩死了 最近刷題不得勁啊 感覺這腦子沒長一點 1.316. 去除重復字母 - 力扣&am…

(實測驗證)【移遠EC800M-CN 】GNSS功能打開和關閉關閉步驟驗證

引言 本文章使用自研“超小體積TTL轉4GGPS集成模塊”進行實測驗證&#xff1b; 一、打開GNSS功能 步驟一、通過 ATQGPSCFG 配置 GNSS 參數 &#xff08;1&#xff09;該命令用于查詢和配置 GNSS 不同的設置&#xff0c;包括 NMEA 語句輸出端口、NMEA 語句的輸出類型等。 1.1…

NSSCTF | [SWPUCTF 2021 新生賽]easyupload2.0

先傳一個普通的一句話木馬試一試 GIF89a <?php eval($_POST[shell]);?> 可以看到回顯&#xff0c;不允許上傳php文件。 使用Burpsuite抓包只修改ContentType后發現也不能繞過&#xff0c;說明服務器使用了黑名單后綴限制&#xff0c;那么我們可以使用其他的后綴代替ph…

RPA的實施過程通常包括哪些步驟?

RPA&#xff08;Robotic Process Automation&#xff09;的實施過程通常涉及一系列詳細的步驟&#xff0c;旨在確保自動化項目的成功部署和運行。以下是RPA實施過程的一般步驟&#xff1a; ### 1. 需求分析與目標設定 實施RPA的第一步是進行需求分析&#xff0c;明確企業希望通…

電路板維修【四】

【開關電源輸出電壓偏低不穩&#xff0c;用示波器立馬鎖定故障范圍】&#xff1a;https://www.bilibili.com/video/BV1pf421D73K?vd_source3cc3c07b09206097d0d8b0aefdf07958 可以用示波器查看MOS的輸出波形來查看其是否損壞&#xff1a; 電源芯片的供電電壓來回跳變&#xf…

嵌入式C語言與人工智能融合開發高級教程:實現手勢識別系統

目錄 文章主題環境準備人工智能與嵌入式系統基礎代碼示例&#xff1a;實現手勢識別系統應用場景&#xff1a;智能家居與穿戴設備問題解決方案與優化 1. 文章主題 文章主題 本教程將詳細介紹如何在STM32嵌入式系統中使用C語言實現手勢識別系統&#xff0c;特別是如何在資源受…

基于卷積神經網絡CNN,使用二維卷積Conv2D實現MNIST數字識別的四種方法

前言 系列專欄&#xff1a;機器學習&#xff1a;高級應用與實踐【項目實戰100】【2024】?? 在本專欄中不僅包含一些適合初學者的最新機器學習項目&#xff0c;每個項目都處理一組不同的問題&#xff0c;包括監督和無監督學習、分類、回歸和聚類&#xff0c;而且涉及創建深度學…

ROS 2邊學邊練(48)-- 將URDF與robot_state_publisher一起使用

前言 本篇將完成一個行走的機器人&#xff0c;并以tf2消息的方式實時發布機器人狀態&#xff0c;以便我們在Rviz中同步查看。 首先&#xff0c;我們創建描述機器人裝配的URDF模型。接下來&#xff0c;我們編寫一個節點&#xff0c;用于模擬運動并發布JointState和位姿變換。然后…

C-函數的由淺入深

1.函數的定義 數據類型 函數名 &#xff08;【數據類型 形參名&#xff0c;數據類型 形參名&#xff0c; …】&#xff09; 2.函數的傳參 值傳遞 地址傳遞 全局變量 3.函數的調用 嵌套調用 遞歸 4.函數與數組 5.函數與指針 指針函數 函數指針 函數指針數組 函數的定義 #inclu…

醉了,面個功能測試,還問我Python裝飾器

Python 裝飾器是個強大的工具&#xff0c;可幫你生成整潔、可重用和可維護的代碼。某種意義上說&#xff0c;會不會用裝飾器是區分新手和老鳥的重要標志。如果你不熟悉裝飾器&#xff0c;你可以將它們視為將函數作為輸入并在不改變其主要用途的情況下擴展其功能的函數。裝飾器可…

dhcp(接口和全局地址池模式)

接口地址池和全局地址池 dhcp應用 1.全部開啟dhcp功能 2.ar5 0口接口地址池 1口全局地址池 3.ar6和ar7配置&#xff0c;查看能否自動獲取ip 左右不同兩個網絡&#xff0c;接口和全局地址池的區別 部分截圖 ar6 ar7 ar5

(實測驗證)【移遠EC800M-CN 】TCP 透傳

引言 本文章使用自研“超小體積TTL轉4GGPS集成模塊”進行實測驗證&#xff1b; 1、配置移遠EC800M-CN TCP 透傳 串口助手發送&#xff1a; ATQIOPEN1,0,"TCP","36.137.226.30",39755,0,2 //配置服務器地址和端口號&#xff1b; 4G模組返回…

07-Fortran基礎--Fortran指針(Pointer)的使用

07-Fortran基礎--Fortran指針Pointer的使用 0 引言1 指針&#xff08;Poionter&#xff09;的有關內容1.1 一般類型指針1.2 數組指針1.3 派生類(type)指針1.4 函數指針 2 可運行code 0 引言 Fortran是一種廣泛使用的編程語言&#xff0c;特別適合科學計算和數值分析。Fortran 9…

java代碼混淆工具ProGuard混淆插件

java代碼混淆工具ProGuard混淆插件 介紹 ProGuard是一個純java編寫的混淆工具&#xff0c;有客戶端跟jar包兩種使用方式。可以將程序打包為jar&#xff0c;然后用工具進行混淆&#xff0c;也可以在maven中導入ProGuard的插件&#xff0c;對代碼進行混淆。 大家都知道 java代…