C語言面試常見考點排序總結(jié)
排序算法有兩塊比較重要的知識點
- 內(nèi)存消耗 :算法的內(nèi)存消耗可以通過空間復雜度來衡量,排序算法也不例外。不過,針對排序算法的空間復雜度,有一個概念是原地排序。原地排序算法是指空間復雜度是O(1)的排序算法。其中冒泡排序,插入排序、選擇排序都屬于原地排序算法
- 穩(wěn)定性:針對排序算法,我們還有一個衡量指標是穩(wěn)定性。這個概念是說,如果待排序的序列中存在值相等的元素,經(jīng)過排序之后,相等元素之間原有的先后順序不變。
例如我們有一組數(shù)據(jù) 2 9 3 4 8 3 按照從小到大的排序是 2 3 3 4 8 9,經(jīng)過某種排序算法之后,如果兩個3的前后順序沒有改變,就稱為穩(wěn)定的排序算法,否則就是不穩(wěn)定的排序算法
算法名稱 | 時間復雜度 | 是否穩(wěn)定排序 | 是否原地排序 |
冒泡排序 | O(N^2) | 是 | 是 |
插入排序 | O(N^2) | 是 | 是 |
選擇排序 | O(N^2) | 否 | 是 |
歸并排序 | O(nlogn) | 是 | 否 |
快速排序 | O(nlogn) | 否 | 是 |
堆排序 | O(nlogn) | 是 | 是 |
冒泡排序
- 平均復雜度是O(N^2)
- 最好情況是O(1) 本身就是排好序的
- 最壞就是倒序O(N^2)
- 空間復雜度是O(1)
冒泡排序只會操作相鄰的兩個數(shù)據(jù)。每次冒泡操作都會對相鄰的兩個元素進行比較,看是否滿足大小關(guān)系要求。如果不滿足就讓它倆互換。一次冒泡會讓至少一個元素移動到它應(yīng)該在的位置,重復 n 次,就完成了 n 個數(shù)據(jù)的排序工作。
class Sort{ public: void MaoPao_Sort(vector<int> &arr){ //1.判斷溢出條件 if(arr.size() <2) return; int length =arr.size(); for(int i =0;i < length;i++){ for(int j=0; j < length -i -1 ;j++){ if(arr[j] >arr[j+1]){ int temp = arr[j]; arr[j]= arr[j+1]; arr[j+1]=temp; } } } } };
插入排序
插入排序思想的由來,其實就是按照在一個有序的數(shù)組中插入一個元素的思想,找到合適的位置進行插入并遷移后面的元素
首先,我們將數(shù)組中的數(shù)據(jù)分為兩個區(qū)間,已排序區(qū)間和未排序區(qū)間。初始已排序區(qū)間只有一個元素,就是數(shù)組的第一個元素。插入算法的核心思想是取未排序區(qū)間中的元素,在已排序區(qū)間中找到合適的插入位置將其插入,并保證已排序區(qū)間數(shù)據(jù)一直有序。重復這個過程,直到未排序區(qū)間中元素為空,算法結(jié)束。
class Sort{ public: void Insert_Sort(vector<int> &arr){ //1.判斷溢出條件 if(arr.size() < 2) return; int length =arr.size(); int j =0;//初始的已排序區(qū)間的下標 for(int i =1;i < length ;i++){ //從未排序的區(qū)間里面取元素 int temp =arr[i]; j =i-1; //不斷更新已排序區(qū)間 while(j >= 0 && temp <a[j]){ //如果小的話就往后移動,找到合適的插入位置 arr[j+1]=arr[j]; j--; } arr[j+1]=temp; //插入元素 } } };
選擇排序
選擇排序算法的實現(xiàn)思路有點類似插入排序,也分已排序區(qū)間和未排序區(qū)間。但是選擇排序每次會從未排序區(qū)間中找到最小的元素,將其放到已排序區(qū)間的末尾
class Sort{ public: void Select_Sort(vector<int> &arr ,int length){ for(int i =0;i < length -1;i++){ int min_number =arr[i]; int flag = i; for(int j =i;j <length ;j++){ if(min_number > arr[j]){ min_number = arr[j]; flag =j; } } //交換數(shù)字 arr[flag] =arr[i]; arr[i]=min_number; } } };
歸并排序
歸并排序是由下而上,采用分治的思想,把數(shù)據(jù)先拆分在合并,并把合并后的數(shù)據(jù)存入臨時數(shù)組中,保證原先的數(shù)據(jù)位置不發(fā)生變化,是一種穩(wěn)定的排序但不是原地排序,時間復雜度是O(nlogn),空間復雜度是O(N)
class Sort{ public: //歸并排序 void MergeSort(vector<int> & arr){ if(arr.size() < 2){ return ; } //拆分函數(shù) Merge_Process(arr,0,arr.size())-1); } //先拆分,這是拆分函數(shù) void Merge_Process(vector<int> &arr,int start,int end){ //遞歸拆分,首先需要遞歸的終止條件 if(end -start == 0) return; int mid =((end -start)/2) +start; Merge_Process(arr,start,mid); Merge_Process(arr,mid+1,end); //在合并 Merge(arr,start,mid,end); } //合并函數(shù) void Merge(vector<int> &arr,int start,int mid, int end){ vector<int> temp(end-start+1,0);//初始化一個臨時數(shù)組 int tempIndex =0; //輔助空間索引 int leftIndex =start; int rightIndex =mid+1; while(leftIndex <= mid && rightIndex <= end){ if(leftIndex <rightIndex){ temp[tempIndex++] =arr[leftIndex++]; }else{ temp[tempIndex++] =arr[rightIndex++]; } } while(leftIndex <= mid){ temp[tempIndex++]=arr[leftIndex++]; } while(rightIndex <= end){ temp[tempIndex++]=arr[rightIndex++]; } for(int i =0;i< temp.size();i++){ arr[start+i]=temp[i]; } } };
快速排序
快速排序是先分區(qū),在處理子問題,通過找到區(qū)間后取得任意一個分區(qū)點,小的放分區(qū)點左邊,大的放分區(qū)點右邊,時間復雜度是O(nlong),空間復雜度是O(1),是原地排序但不是穩(wěn)定排序
快排優(yōu)化的話,有:三數(shù)取中法,和隨機法,都是為了防止要排序的數(shù)組中有重復元素,這塊我演示的是隨機法
class Sort{ public: void quickSort(vector<int> &arr,int begin, int low){ if(begin <end){ //產(chǎn)生一個隨機值 int index =rand()%(end-begin+1)+begin; //然后把產(chǎn)生的這個隨機值,替換到數(shù)組的首位 swap(arr[begin],arr[index]); int i =begin; int j =end; int base =arr[i];//基準位 while(i <j){ while(i<j&& arr[j] >= base){ j--; } num[i]=num[j]; while(i<j && arr[i] < base){ i++; } num[j]=num[i]; } //回歸基準位 num[i]=base; //遞歸開始處理子問題 quickSort(arr,begin,i-1); quickSort(arr,i+1,end); } } };
以上就是C語言面試常見考點排序總結(jié)的詳細內(nèi)容,更多關(guān)于C語言 排序的資料請關(guān)注腳本之家其它相關(guān)文章!
- C語言數(shù)據(jù)結(jié)構(gòu)之堆排序源代碼
- C語言中數(shù)據(jù)結(jié)構(gòu)之鏈式基數(shù)排序
- C語言數(shù)據(jù)結(jié)構(gòu) 快速排序?qū)嵗斀?/a>
- C語言中數(shù)據(jù)結(jié)構(gòu)之鏈表歸并排序?qū)嵗a
- C語言 數(shù)據(jù)結(jié)構(gòu)堆排序順序存儲(升序)
- C語言數(shù)據(jù)結(jié)構(gòu) 鏈表與歸并排序?qū)嵗斀?/a>
- 深入學習C語言中常見的八大排序
- C語言排序方法(冒泡,選擇,插入,歸并,快速)
- C語言之快速排序案例詳解
- c語言實現(xiàn)的幾種常用排序算法
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡單實例
這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之循環(huán)鏈表的簡單實例的相關(guān)資料,需要的朋友可以參考下2017-06-06c語言中exit和return的區(qū)別點總結(jié)
小編今天給大家整理了關(guān)于c語言中exit和return的不同點及相關(guān)基礎(chǔ)知識點,有興趣的朋友們可以跟著學習下。2021-10-10Qt數(shù)據(jù)庫應(yīng)用之實現(xiàn)文件編碼格式識別
在做數(shù)據(jù)導入導出的過程中,如果應(yīng)用場景多了,相信各位都會遇到一個問題就是文件編碼的問題。本文將用Qt實現(xiàn)文件編碼格式識別,感興趣的可以了解一下2022-06-06