日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

十种基本排序算法

發布時間:2024/4/11 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 十种基本排序算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

十種基本排序算法

文章目錄

    • 十種基本排序算法
    • 一、復雜度分析
    • 二、實現
      • 插入排序
      • 希爾排序
      • 選擇排序
      • 堆排
      • 冒泡排序
      • 快速排序hoare版本
      • 快速排序挖坑版本
      • 快速排序雙指針版本
      • 快排非遞歸版本
      • 歸并排序
      • 計數排序

一、復雜度分析

二、實現

插入排序

class Solution { public:vector<int> sortArray(vector<int>& nums) {/*插入排序:主要思想:假定一個位置end,end位置之前(包括end位置)的所有元素已經有序,end位置后的元素待判斷;1:如果end之后位置的元素比end位置的元素大,不用往前插2:如果end之后位置的元素比end位置的元素小,需要往前插入到一個合適的位置(斗地主)*///排除特殊情況if(nums.empty()){return {};}//遍歷,每次比較當前元素和下一個元素,所以只需要到size - 1即可for(size_t i = 0;i < nums.size() - 1;i++){//end 為完成排序到最后一個元素下表,即end包括end之前到所有元素已經是有序的int end = i;//temp為end下一個位置的元素,即待判斷的元素(判斷temp元素和有序序列最后一個//位置的元素的大小)int temp = nums[end + 1];//1.temp剛好大于等于end位置的元素,我們求的是升序,滿足情況,不進循環,執行://nums[i + 1] = temp,相當于什么也沒做,因為temp 也等于 nums[i+ 1]//2.temp剛好小于end位置的元素,代表后一個位置的元素小于前一個位置的元素,我們求的//是升序,不滿足情況,進入循化;把當前end位置的元素往end + 1位置進行搬移//,繼續判斷是否滿足情況,直到找到一個temp大于等于end位置元素的情況,即://nums[?] < 或者 <= temp,直接把nums[end + 1]位置的元素值為temp即可,//(因為走到end這個位置,說明原來nums中end + 1位置的元素是大于等于temp的,//所以原來end + 1位置的元素肯定已經完成拷貝,所以可以直接復制)while(end >= 0 && nums[end] > temp){nums[end + 1] = nums[end];end--;}nums[end + 1] = temp;}return nums;} };

希爾排序

class Solution { public:vector<int> sortArray(vector<int>& nums) {/*希爾排序:主要思想:在插入排序的基礎上加一個組gap,對每個gap進行插入排序。gap的值是動態遞減的,直到gap = 1時就是插入排序*/if(nums.empty()){return {};}//不能直接些gap = nums.size() / 3 - 1int gap = nums.size();//不能寫成大于 0,因為 gap的值始終>=1while(gap > 1){//只有gap 最后為1, 才能保證最后有序//所以這里要加1gap = gap / 3 + 1;//這里只是把插入排序的1 換成gap 即可//但是這里不是排序完一個分組, 再去排序另一個分組, 而是整體只過一遍//這樣每次對于每組數據只排一部分//整個循環結束之后, 所有組的數據排序完成//結束條件由size - 1變為size - gap,因為組的大小就是gap早size - gap時已經完成//size - 1位置元素的判斷for (int i = 0; i < nums.size() - gap;++i){//同樣標記最后一個有序元素的下標int end = i;//同組帶判斷的下一個元素int temp = nums[end +gap]; while (end >= 0 && nums[end] >temp){nums[end + gap] = nums[end];end -= gap;} nums[end + gap] = temp; } }return nums;} };

選擇排序

class Solution { public:vector<int> sortArray(vector<int>& nums) {/*選擇排序(優化版)主要思想:一趟遍歷選擇一個最大的元素和一個最小的元素,并把最小的元素放在該趟排序的開始位置,把最大元素放在該趟排序的結束位置*/if(nums.empty()){return {};}//每趟循環查找的開始和結束位置int begin = 0;int end = nums.size() - 1;while(begin < end){//每趟循化結束后,最大和最小元素的下標int max_data_index = begin;int min_data_index = begin;for(int i = begin;i <= end;i++){//找最大元素下標if(nums[max_data_index] < nums[i]){max_data_index = i;}//找最小元素下標if(nums[min_data_index] > nums[i]){min_data_index = i;}}//把最小元素下標位置的元素放到該趟循化的開始位置swap(nums[begin],nums[min_data_index]);//有一種特殊情況,剛好最大元素的下標在該趟循化的開始位置//經過上面的交換之后,最大元素的下標被交換到min_data_index處,//需要注意if(max_data_index == begin){max_data_index = min_data_index;}//把最大元素下標位置的元素放到該趟循化的結束位置swap(nums[end],nums[max_data_index]);begin++;end--;}return nums;} };

堆排

class Solution { public://堆排的向下調整,beign代表在哪里開始調整void AdjustDown(vector<int>& nums,int begin){//父親下標索引int parent = begin;//孩子下標索引int child = parent * 2 + 1;while(child < nums.size()){//找到左右孩子中最大的一個下標if(child + 1 < nums.size() && nums[child] < nums[child + 1]){child = child + 1;}//判斷孩子是否大于父親//大于就交換if(nums[child] > nums[parent]){swap(nums[child],nums[parent]);parent = child;child = parent * 2 + 1;}//小于說明已經是一個堆了,可以直接return,因為我們在建堆的時候是//從下往上建的else {break;}}}vector<int> sortArray(vector<int>& nums) {/*堆排:主要思想:升序建大堆,每次把大堆的堆頂元素和堆中最后一個位置的元素交換(可以保證堆頂元素一定是所有元素中最大的,但是不能保證最后一個元素是對中最小的,所以才用這種交換方式進行排序)*/if(nums.empty()){return {};}//根據nuns中的元素建大堆//在數組中://根據孩子索引下標推父親索引下標:parent = (child - 1) / 2;//根據父親索引下標推孩子索引下標:child = parent * 2 + 1 / parent * 2 + 2//建堆是從下往上建造的,即先找到最后一個非葉子結點在數組中的下標,即://根據子推父:parent = (nums.size() - 1 - 1) / 2;//逐漸往上建,直到nuns[0]for(int i = (nums.size() - 1 - 1) / 2;i >= 0;i--){AdjustDown(nums,i);}//最后一個元素的位置int end = nums.size() - 1;//保存結果vector<int> ret(nums.size());//當nums中還有元素時while(end > 0){//把第一個和最后一個元素進行交換swap(nums[0],nums[end]);//把最大的元素加入結果集ret[end] = nums[end];//不讓最大的元素參加向下調整,因為其已經有序nums.pop_back();AdjustDown(nums,0);end-- ;}ret[0] = nums[0];return ret;} };

冒泡排序

class Solution { public:vector<int> sortArray(vector<int>& nums) {/*冒泡排序:主要思想:冒泡冒泡:顧名思義,一次冒出一個大的元素,其實和選擇排序差不多*/if(nums.empty()){return {};}//避免有序的情況bool flag = true;//i代表每次循化的終點,i即i之后的元素是有序的,每次從前秒找到一個最大的放到i - 1處for(size_t i = nums.size();i > 0;i--){//從0到i - 1中找最大for(size_t j = 1;j < i;j++){if(nums[j - 1] > nums[j]){flag = false;swap(nums[j - 1],nums[j]);}}//如果沒有進行一次交換說明nums本身就是有序的,直接beak掉if(flag){break;}}return nums;} };

快速排序hoare版本

class Solution { public://三數取中,避免有序的情況int GetMidIndex(vector<int>& nums, int begin, int end){int mid = begin + (end - begin) / 2;if(nums[begin] < nums[mid]){if(nums[mid] < nums[end]){return mid;}else if(nums[begin] > nums[end]){return begin;}else {return end;}}else {if(nums[mid] > nums[end]){return mid;}else if(nums[begin] < nums[end]){return begin;}else {return end;}}}//快速排序hoare版本int PartSort(vector<int>& nums, int begin, int end){//找到合適的keyint mid = GetMidIndex(nums,begin,end);swap(nums[mid],nums[begin]);int key = nums[begin];int start = begin;while(begin < end){//從后往前找比key小的while(begin < end && nums[end] >= key){end--;}//從前往后找比key大的while(begin < end && nums[begin] <= key){begin++;}//交換swap(nums[begin],nums[end]);}//交換,將nums[start]放到正確的位置swap(nums[start],nums[begin]);return begin;}//快排void QuickSort(vector<int>& nums, int left, int right){if(left >= right){return ;}//if(right - left + 1 < 10)//{// 插入排序//}//else {int mid = PartSort(nums,left,right);QuickSort(nums,left,mid - 1);QuickSort(nums,mid + 1,right);}}vector<int> sortArray(vector<int>& nums) { if(nums.empty()){return {};}QuickSort(nums,0,nums.size() - 1);return nums; } };

快速排序挖坑版本

class Solution { public://三數取中,避免有序的情況int GetMidIndex(vector<int>& nums, int begin, int end){int mid = begin + (end - begin) / 2;if(nums[begin] < nums[mid]){if(nums[mid] < nums[end]){return mid;}else if(nums[begin] > nums[end]){return begin;}else {return end;}}else {if(nums[mid] > nums[end]){return mid;}else if(nums[begin] < nums[end]){return begin;}else {return end;}}}//快速排序挖坑版本int PartSort(vector<int>& nums, int begin, int end){//找到合適的keyint mid = GetMidIndex(nums,begin,end);swap(nums[mid],nums[begin]);int key = nums[begin];while(begin < end){//從后往前找比key小的while(begin < end && nums[end] >= key){end--;}nums[begin] = nums[end];//從前往后找比key大的while(begin < end && nums[begin] <= key){begin++;}nums[end] = nums[begin];}//將key放到正確的位置nums[begin] = key;return begin;}//快排void QuickSort(vector<int>& nums, int left, int right){if(left >= right){return ;}//if(right - left + 1 < 10)//{// 插入排序//}//else {int mid = PartSort(nums,left,right);QuickSort(nums,left,mid - 1);QuickSort(nums,mid + 1,right);}}vector<int> sortArray(vector<int>& nums) {if(nums.empty()){return {};}QuickSort(nums,0,nums.size() - 1);return nums; } };

快速排序雙指針版本

class Solution { public://三數取中,避免有序的情況int GetMidIndex(vector<int>& nums, int begin, int end){int mid = begin + (end - begin) / 2;if(nums[begin] < nums[mid]){if(nums[mid] < nums[end]){return mid;}else if(nums[begin] > nums[end]){return begin;}else {return end;}}else {if(nums[mid] > nums[end]){return mid;}else if(nums[begin] < nums[end]){return begin;}else {return end;}}}//快速排序雙指針版本int PartSort(vector<int>& nums, int begin, int end){int key = nums[end];//后指針 int prev = begin - 1;//前指針int cur = begin;// 3 2 5 9 8 0 6// 3 2 5 0 6 9 8while(cur < end){//cur如果找到比key小的元素,就將cur和prev的元素互換if(nums[cur] < key){prev++;swap(nums[cur],nums[prev]);}//如果cur 所在下標的元素比key 所在元素大, 就直接后移curcur++;}//最后注意和end 位置的元素交換的是pref 的下一個,不是它自己swap(nums[end],nums[++prev]);return prev;}//快排void QuickSort(vector<int>& nums, int left, int right){if(left >= right){return ;}//if(right - left + 1 < 10)//{// 插入排序//}//else {int mid = PartSort(nums,left,right);QuickSort(nums,left,mid - 1);QuickSort(nums,mid + 1,right);}}vector<int> sortArray(vector<int>& nums) {if(nums.empty()){return {};}QuickSort(nums,0,nums.size() - 1);return nums; } };

快排非遞歸版本

class Solution { public://快速排序雙指針版本int PartSort(vector<int>& nums, int begin, int end){int key = nums[end];//后指針 int prev = begin - 1;//前指針int cur = begin;// 3 2 5 9 8 0 6// 3 2 5 0 6 9 8while(cur < end){//cur如果找到比key小的元素,就將cur和prev的元素互換if(nums[cur] < key){prev++;swap(nums[cur],nums[prev]);}//如果cur 所在下標的元素比key 所在元素大, 就直接后移curcur++;}//最后注意和end 位置的元素交換的是pref 的下一個,不是它自己swap(nums[end],nums[++prev]);return prev;}//快排非遞歸void QuickSortStack(vector<int>& nums, int left, int right){//用棧模擬遞歸stack<int> s;//往棧中放左右邊界if(left < right){s.push(right);s.push(left);}while(!s.empty()){//取左右邊界時要注意邊界的入棧順序left = s.top();s.pop();right = s.top();s.pop();//進行單趟排序獲取新的邊界int mid = PartSort(nums,left,right);//如果mid左邊還有2個元素及以上繼續入棧if(left < mid - 1){s.push(mid - 1);s.push(left);}//右邊同理if(right > mid + 1){s.push(right);s.push(mid + 1);}}}vector<int> sortArray(vector<int>& nums) {if(nums.empty()){return {};}QuickSortStack(nums,0,nums.size() - 1);return nums;} };

歸并排序

class Solution {void mergeSort(vector<int>& nums, int left, int right,vector<int>& tmp) {if (left >= right) return;int mid = (left + right) >> 1;mergeSort(nums, left, mid,tmp);mergeSort(nums, mid + 1, right,tmp);int begin1 = left;int end1 = mid;int begin2 = mid + 1;int end2 = right;int index = left;while (begin1 <= end1 && begin2 <= end2) {if (nums[begin1] < nums[begin2]) {tmp[index++] = nums[begin1++];}else {tmp[index++] = nums[begin2++];}}while (begin1 <= end1){tmp[index++] = nums[begin1++];} while (begin2 <= end2){tmp[index++] = nums[begin2++];} for (int i = 0; i < right - left + 1; ++i) nums[i + left] = tmp[i + left];} public:vector<int> sortArray(vector<int>& nums) {if(nums.empty()){return {};}vector<int> tmp(nums.size());mergeSort(nums, 0, (int)nums.size() - 1,tmp);return nums;} };

計數排序

class Solution { public:vector<int> sortArray(vector<int>& nums) {/*計數排序:主要思想:計數*/if(nums.empty()){return {};}map<int,int> mp;for(size_t i = 0;i < nums.size();i++){mp[nums[i]]++;}nums.clear();for(auto e : mp){for(int i = 0;i < e.second;i++){nums.push_back(e.first);}}return nums;} }; 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的十种基本排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 丝袜国产在线 | av中文字幕一区 | 欧美性生活免费视频 | 熟女肥臀白浆大屁股一区二区 | 啪啪网免费 | 中文字幕在线观看免费视频 | 天天夜夜爽 | 国产ts人妖系列高潮 | 在线看片你懂得 | 裸尼姑熟蜜桃 | 穿越异世荒淫h啪肉np文 | 国产白嫩美女无套久久 | 午夜在线精品偷拍 | 免费看裸体网站视频 | 丁香婷婷六月天 | 最新地址在线观看 | 日本视频在线播放 | 少妇人妻在线视频 | 国产福利视频一区 | 美女户外露出 | 天堂网一区二区三区 | 成人免费网站在线观看 | 午夜影视剧场 | 亚洲精品66| 国产精品99久久久久久久女警 | 久久久久亚洲精品中文字幕 | 日韩精品影视 | 国产一级做a爱免费视频 | 亚洲免费精品 | 无码国产69精品久久久久同性 | 天堂网www在线 | 人妻天天爽夜夜爽一区二区三区 | 色乱码一区二区三区熟女 | 香蕉黄色片 | 91亚洲精品久久久蜜桃借种 | 免费三片在线视频 | 日本aⅴ在线 | 中文字幕人妻一区二 | 黄色一级片 | 少妇搡bbbb搡bbb搡小说 | 国产精品美女视频 | 悠悠色在线 | 久久牛牛 | 俄罗斯女人裸体性做爰 | 欧美日韩电影一区二区三区 | 麻豆视频在线 | 午夜免费播放观看在线视频 | 久久超碰精品 | 欧美视频自拍偷拍 | 亚洲自拍偷拍网 | 色久网 | 国产伦理吴梦梦伦理 | 日韩av视屏 | 日本欧美在线视频 | 成人污视频 | 日韩成人性视频 | www男人的天堂 | 国产视频中文字幕 | 欧美高清视频在线观看 | 看片地址 | 激情综合网婷婷 | 中文字幕av在线免费 | 日韩福利一区二区 | 欧美成人精品一区二区免费看片 | 久久久久久蜜桃一区二区 | 超能一家人电影免费喜剧在线观看 | 风间由美在线观看 | 久久久久久福利 | av最新天堂 | 2025av在线播放 | 欧美va天堂| 国产精品亚洲一区二区无码 | 日本人做受免费视频 | 亚洲一区福利视频 | 国产无遮挡免费视频 | 少妇一级淫免费放 | 五月天激情视频在线观看 | 91在线观看免费高清完整版在线观看 | 美女国产视频 | 黑人黄色片 | 在线观看久草 | av在线不卡网站 | 黄色av国产| 日韩av成人在线 | 国产成人精品一区二区三区网站观看 | 拍真实国产伦偷精品 | 高h喷汁呻吟3p | 久久影院一区二区 | h无码动漫在线观看 | 亚洲综合免费 | 国产日韩视频在线 | 成人精品一区二区三区中文字幕 | 国产欧美视频一区 | 一区二区三区免费在线观看 | 色99色| 91视频影院 | 久久成人免费 | 性欧美激情 | 日韩一区二 |