二分查找和快速排序
一、二分查找
二分查找的基本思想:
? 二分查找就是給定一個已經排序好的數組,輸入你想查找的數值,然后對數組進行折半查找,找到直接返回在數組中的位置,否則返回-1。它充分利用了元素間的次序關系,采用分治策略,可在最壞的情況下用O(log n)完成搜索任務。
具體實現:
1、binarySearch函數傳入已經排序好的數組(nums[]),你想查找的目標數值(target),數組的長度(length)
2、binarySearch中先設置數組的左右邊界left、right,然后求解數組的中間位置mid,判斷其與目標數值的大小,如果中間位置的數值剛好等于目標數值,則直接返回mid。如果中間數值小于目標數值,說明目標數值在中間位置后方重置left=mid+1,反之目標數值就是在中間位置的前方重置right=mid-1。直到查找到目標數值并且返回目標數值在數組中的位置。
二分查找算法的時間復雜度分析:
時間復雜度即是while循環的次數。總共有n個元素,漸漸跟下去就是n,n/2,n/4,…n/2k(接下來操作元素的剩余個數),其中k就是循環的次數由于你n/2k取整后>=1,即令n/2^k=1,可得k=log2n,(是以2為底,n的對數)。所以時間復雜度可以表示O(h)=O(log2n)=O(log n)。
O(log2n)是以2為底數,n為對數的對數函數,O(log n)同理只不過底數2省略了
//二分查找:對有順序的數組中特定元素進行的快速查找的算法 。 #include<stdio.h>int binarySearch(int nums[],int target,int length);int main(){int i,n,target;scanf("%d %d",&n,&target);int a[n];for(i=0;i<n;i++){scanf("%d",&a[i]);}printf("%d",binarySearch(a,target,n));return 0; }int binarySearch(int nums[], int target,int length) {//設置左右邊界int left = 0; int right = length - 1; while(left <= right) { //計算數組的中間位置midint mid = (right + left) / 2; if(nums[mid] == target) //如果中間位置找到直接返回return mid; else if (nums[mid] < target)//如果中間位置的數值小于目標數值,說明目標數值在數組的右邊left = mid + 1; else if (nums[mid] > target)//如果中間位置的數值大于目標數值,說明目標數值在數組的左邊right = mid - 1; }return -1; }二、快速排序
快速排序的基本思想:
快速排序的時間復雜度分析:
快速排序的一次劃分算法從兩頭交替搜索,直到low和hight重合,因此其時間復雜度是O(n);而整個快速排序算法的時間復雜度與劃分的趟數有關。 [4]
理想的情況是,每次劃分所選擇的中間數恰好將當前序列幾乎等分,經過log2n趟劃分,便可得到長度為1的子表。這樣,整個算法的時間復雜度為O(nlog2n)。 [4]
最壞的情況是,每次所選的中間數是當前序列中的最大或最小元素,這使得每次劃分所得的子表中一個為空表,另一子表的長度為原表的長度-1。這樣,長度為n的數據表的快速排序需要經過n趟劃分,使得整個排序算法的時間復雜度為O(n2)。 [4]
為改善最壞情況下的時間性能,可采用其他方法選取中間數。通常采用“三者值取中”方法,即比較H->r[low].key、H->r[high].key與H->r[(low+high)/2].key,取三者中關鍵字為中值的元素為中間數。 [4]
可以證明,快速排序的平均時間復雜度也是O(nlog2n)。因此,該排序方法被認為是目前最好的一種內部排序方法。
快速排序的時間復雜度分析引用于百度百科
百度百科-快速排序算法
快速排序還有很多改進版本,如隨機選擇基準數,區間內數據較少時直接用另的方法排序以減小遞歸深度 。
總結
- 上一篇: docker 安装ELK
- 下一篇: js serialize php 解,[