條件:如果陣列是有序陣列、部分有序陣列、或者區域性有序陣列,在這類陣列中進行查詢時,二分查詢較為常用。時間複雜度o(logn)。二分查詢的主要思路:設定兩個指標start和end分別指向陣列元素的首、尾,然後比較陣列中間結點arry[mid]和待查詢元素。如果待查詢元素小於中間元素,說明待查詢元素在陣列的前半段,那麼將end=mid-1,如果待查詢元素大於中間元素,說明該元素在陣列的後半段,將start=mid+1; 如果中間元素等於待查詢元素,那麼返回mid的值。
//統計乙個數字在已經有序的陣列中出現的次數。
int binary_search(vectordata, int len, int goal)
//沒找到
return -1;
}int getnumberofk(vectordata, int k)
} for (int i = index + 1; i < len; i++)
}} return count;
}void main()
; cout << getnumberofk(v, 3);
}//尋找第乙個
int getfirsttarget(vector& data, int target)
int pleft = 0;
int pright = length - 1;
while (pleft <= pright)
else
pright = index - 1;
}else if (data[index] < target)
else
}return -1;
}//尋找最後乙個
int getlasttarget(vector& data, int target)
int pleft = 0;
int pright = length - 1;
while (pleft <= pright)
else
pleft = index + 1;
}else if (data[index] < target)
else
}return -1;
}int getnumberofk1(vectordata, int k)
}return count;
}
在快速排序演算法中,我們隨機在陣列中選擇乙個數字,然後把比選中數字小的數字都排在它前面,比選中數字大的數字都排在它的後面。
//分割
int partition(vector& data, int length, int start, int end)
//int index = randominrange(start, end); //隨機產生乙個數為基準點進行劃分
//std::swap(data[index], data[end]);
int curdivision = start - 1;
for (int index = start; index < end; ++index)
}} ++curdivision;
std::swap(data[curdivision], data[end]);
return curdivision; //把基準元素放到最終位置上,並且返回其最終位置索引
}
快速排序:
//快速排序
void quicksort(vector& data, int length, int start, int end)
int index = partition(data, length, start, end); //由上述partition可知以最後乙個元素為基準元素
if (index > start)
if (index < end)
}
問題描述:
//陣列中有乙個數字出現的次數超過陣列長度的一半,請找出這個數字。
//例如輸入乙個長度為9的陣列。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。
//如果不存在則輸出0。
採用上述的partition()函式來做的思想:利用partition函式「」跳躍獲得」」
中間元素。既然出現次數超過一半,那麼在排好序以後(利用partition函式並不需要把整個陣列都排序,所以說是「」跳躍獲得「」),位於中間位置上的元素必定是「出現次數」超過一半的數。
bool g_inputinvalidflag = false;
bool checkinvalid(const vector& data, int length) //檢查輸入是否有效
return g_inputinvalidflag;
}bool checkmorethanhalf(const vector& data, int length, int number) //檢查是否存在出現次數超過一半的數字
bool ismorethanhalf = true;
if (times * 2 <= length)
return ismorethanhalf;
}int morethanhalfnum_solution(vectornumbers) //查詢出現次數超過一半的數字
else
}int result = numbers[middle];
if (!checkmorethanhalf(numbers, length, result))
result = 0;
return result;
}
問題描述:
//輸入n個整數,找出其中最小的k個數。
//例如輸入4,5,1,6,2,7,3,8, 則最小的4個數字是1, 2, 3, 4。
採用上述的partition()函式來做的思想:利用partition函式「盡量快速地」把前k個「最終有序」數字放到指定位置上,仍舊是區域性排序,並不等到整個陣列都排序完成猜得到結果。(這種解法修改了初始陣列)
vectorgetleastnumbers_solution(vectorinput, int k)
else
}for (int i = 0; i < k; i++)
output.push_back(input[i]);
} return output;
}//分割
int partition(vector& data, int low, int high)
return low; // 返回關鍵字所在位置
}int findkth(vectora, int n, int k)
else
}return a[index];
}
void main()
; cout << "排序前vector:";
for (int i : v)
cout << i << " ";
quicksort(v, v.size(), 0, v.size() - 1);
cout << endl << "排序後vector:";
for (int i : v)
cout << i << " ";
cout << endl;
cout << endl << "出現次數超過一半的數是:";
拓展1的優化方案:時間複雜度o(n)
int morethanhalfnum_solution1(vectornumbers) //查詢出現次數超過一半的數字
else if (numbers[i] == result)
else
}if (!checkmorethanhalf(numbers, length, result))
result = 0;
return result;
}
拓展2的優化方案:o(n*logk)
#include#include#include#includeusing namespace std;
//這種方法適合處理海量資料,比如在一億個數中選出前十個最小的數,
//我們做如下面的工作:設定集合中的元素降序排列,只需k個元素大小的結合
typedef multiset> intset; //關鍵:設定集合中的元素降序排列
typedef multiset>::iterator setite;
void getleastnumbers_solution1(const vector& input, intset& leastnums, int k)
else
}} }
}測試:
快速排序演算法裡的partition函式
快速排序演算法裡的partition函式用來解決這樣乙個問題 給定乙個陣列arr和陣列中任意乙個元素a,重排陣列使得a左邊都小於它,右邊都不小於它。實現 arr為陣列,start end分別為陣列第乙個元素和最後乙個元素的索引 povitindex為陣列中任意選中的數的索引 int partitio...
Partition函式實現的快速排序演算法
被傳值傳引用的問題還有一些雜事困擾了一下午,現在終於可以靜下心來寫部落格了。這個partition函式是我在 劍指offer 那本書上看到的,其實對應於快排是乙個單項掃瞄。這個函式在很多演算法題上都有應用,主要原理就是選定乙個參考值,然後將資料分成兩部分,左邊都是比它小的,右邊都是比它大的。然後把中...
快速排序中的partition函式詳解
快速排序的精髓就在partition函式的實現。我們構建兩個指標,將陣列分為三部分,黑色部分全部小於pivot,中間藍色部分都大於pivot,後面紅色部分未知。i指標遍歷整個陣列,只要它指向的元素小於pivot就交換兩個指標指向的元素,然後遞增。arr為陣列,start end分別為陣列第乙個元素和...