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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二分查找和快速排序

發(fā)布時(shí)間:2023/12/9 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二分查找和快速排序 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、二分查找

二分查找的基本思想:

? 二分查找就是給定一個(gè)已經(jīng)排序好的數(shù)組,輸入你想查找的數(shù)值,然后對數(shù)組進(jìn)行折半查找,找到直接返回在數(shù)組中的位置,否則返回-1。它充分利用了元素間的次序關(guān)系,采用分治策略,可在最壞的情況下用O(log n)完成搜索任務(wù)。

具體實(shí)現(xiàn):

1、binarySearch函數(shù)傳入已經(jīng)排序好的數(shù)組(nums[]),你想查找的目標(biāo)數(shù)值(target),數(shù)組的長度(length)

2、binarySearch中先設(shè)置數(shù)組的左右邊界left、right,然后求解數(shù)組的中間位置mid,判斷其與目標(biāo)數(shù)值的大小,如果中間位置的數(shù)值剛好等于目標(biāo)數(shù)值,則直接返回mid。如果中間數(shù)值小于目標(biāo)數(shù)值,說明目標(biāo)數(shù)值在中間位置后方重置left=mid+1,反之目標(biāo)數(shù)值就是在中間位置的前方重置right=mid-1。直到查找到目標(biāo)數(shù)值并且返回目標(biāo)數(shù)值在數(shù)組中的位置。

二分查找算法的時(shí)間復(fù)雜度分析:
時(shí)間復(fù)雜度即是while循環(huán)的次數(shù)。總共有n個(gè)元素,漸漸跟下去就是n,n/2,n/4,…n/2k(接下來操作元素的剩余個(gè)數(shù)),其中k就是循環(huán)的次數(shù)由于你n/2k取整后>=1,即令n/2^k=1,可得k=log2n,(是以2為底,n的對數(shù))。所以時(shí)間復(fù)雜度可以表示O(h)=O(log2n)=O(log n)。

O(log2n)是以2為底數(shù),n為對數(shù)的對數(shù)函數(shù),O(log n)同理只不過底數(shù)2省略了

//二分查找:對有順序的數(shù)組中特定元素進(jìn)行的快速查找的算法 。 #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) {//設(shè)置左右邊界int left = 0; int right = length - 1; while(left <= right) { //計(jì)算數(shù)組的中間位置midint mid = (right + left) / 2; if(nums[mid] == target) //如果中間位置找到直接返回return mid; else if (nums[mid] < target)//如果中間位置的數(shù)值小于目標(biāo)數(shù)值,說明目標(biāo)數(shù)值在數(shù)組的右邊left = mid + 1; else if (nums[mid] > target)//如果中間位置的數(shù)值大于目標(biāo)數(shù)值,說明目標(biāo)數(shù)值在數(shù)組的左邊right = mid - 1; }return -1; }

二、快速排序

快速排序的基本思想:

  • 先從給定的數(shù)組中取出一個(gè)基準(zhǔn)數(shù)
  • 劃分過程,小于等于基準(zhǔn)數(shù)的放在左邊,大于基準(zhǔn)數(shù)的放在右邊
  • 再對左右區(qū)間重復(fù)第2步操作,直到各區(qū)間只有一個(gè)數(shù)
  • 快速排序的時(shí)間復(fù)雜度分析:

    快速排序的一次劃分算法從兩頭交替搜索,直到low和hight重合,因此其時(shí)間復(fù)雜度是O(n);而整個(gè)快速排序算法的時(shí)間復(fù)雜度與劃分的趟數(shù)有關(guān)。 [4]

    理想的情況是,每次劃分所選擇的中間數(shù)恰好將當(dāng)前序列幾乎等分,經(jīng)過log2n趟劃分,便可得到長度為1的子表。這樣,整個(gè)算法的時(shí)間復(fù)雜度為O(nlog2n)。 [4]

    最壞的情況是,每次所選的中間數(shù)是當(dāng)前序列中的最大或最小元素,這使得每次劃分所得的子表中一個(gè)為空表,另一子表的長度為原表的長度-1。這樣,長度為n的數(shù)據(jù)表的快速排序需要經(jīng)過n趟劃分,使得整個(gè)排序算法的時(shí)間復(fù)雜度為O(n2)。 [4]

    為改善最壞情況下的時(shí)間性能,可采用其他方法選取中間數(shù)。通常采用“三者值取中”方法,即比較H->r[low].key、H->r[high].key與H->r[(low+high)/2].key,取三者中關(guān)鍵字為中值的元素為中間數(shù)。 [4]

    可以證明,快速排序的平均時(shí)間復(fù)雜度也是O(nlog2n)。因此,該排序方法被認(rèn)為是目前最好的一種內(nèi)部排序方法。

    快速排序的時(shí)間復(fù)雜度分析引用于百度百科
    百度百科-快速排序算法

    //快速排序:不斷的劃分左右兩邊的數(shù)值 ,以一個(gè)數(shù)為基準(zhǔn)左邊的數(shù)永遠(yuǎn)小于右邊的數(shù)。最后的劃分都是對兩個(gè)數(shù)值的比較。 #include<stdio.h>void QuickSort(int a[],int p,int r); //分治代碼int Partition(int a[],int p,int r);//填坑代碼int main(){int i,n;scanf("%d",&n);int a[n];for(i=0;i<n;i++){scanf("%d",&a[i]);}QuickSort(a,0,n-1);for(i=0;i<n;i++){printf("%d",a[i]);}return 0; }void QuickSort(int a[],int p,int r){if(p<r){int q = Partition(a,p,r);QuickSort(a,p,q-1);QuickSort(a,q+1,r); } }//對a的數(shù)組從p到r以a[p]為基準(zhǔn)進(jìn)行分割,左邊永遠(yuǎn)比a[p]小,右邊永遠(yuǎn)比a[p]大。 int Partition(int a[],int p,int r){int tmp; int i=p,j=r+1;//以第一個(gè)數(shù)為基準(zhǔn)來進(jìn)行左右兩邊的劃分! int x=a[p];printf("%d\n",x); while(true){while(a[++i]<x&&i<r) ;//找出左邊第一個(gè)比數(shù)值大的 while(a[--j]>x) ; //找出右邊第一個(gè)比數(shù)值小的 if(i>=j) break;//Swap(a[i],a[j]); 交換兩個(gè)數(shù)的位置 tmp=a[i];a[i]=a[j];a[j]=tmp;}a[p]=a[j];a[j]=x;return j; }

    快速排序還有很多改進(jìn)版本,如隨機(jī)選擇基準(zhǔn)數(shù),區(qū)間內(nèi)數(shù)據(jù)較少時(shí)直接用另的方法排序以減小遞歸深度 。

    總結(jié)

    以上是生活随笔為你收集整理的二分查找和快速排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。