學習筆記-C語言5(演算法設計提高)
阿新 • • 發佈:2018-10-31
演算法複雜度是指演算法在編寫可執行程式後,執行時所需要的時間資源和記憶體資源。演算法設計一般更在意時間和計算資源的開銷,而對空間資源則不太介意。
1. 二分查詢
二分查詢又稱折半查詢,首先陣列中的元素時按升序排列,將陣列中間位置的關鍵字與查詢關鍵字比較:
1)如果兩者相等,則查詢成功
2)否則利用中間位置將表分成前、後兩個子陣列:
- 如果中間位置的關鍵字大於查詢關鍵字,則進一步查詢前一子陣列
- 否則進一步查詢後一子陣列
重複以上過程,直到找到滿足條件的記錄,便查詢成功,或者直到字表不存在為止,此時查詢不成功。
二分查詢的時間複雜度log(n),整體時間複雜度nlog(n)。
實現程式碼:
普通迴圈版本:
int binary_search(int sort_array[],int n,int target){ int begain=0; int end=n-1; while(end>=begin){ int mid=(begain+end)/2; if(target==sort_array[mid]){ return 1; } else if(target<sort_array[mid]){ end=mid-1; } else if(target>sort_array[mid){ begin=mid+1; } } return 0; }
遞迴版本:
int binary_search(int sort_array[],int begain,int end,int target){ if(end<begin){ return 0; } int mid=(begain+end)/2; if(target==sort_array[mid]){ return 1; } else if(target<sort_array[mid]){ return binary_search(sort_array,begin,mid-1,target); } else if(target>sort_array[mid){ return binary_search(sort_array,mid+1,end,target); } }
2. LeetCode 34,Search for a Range(區間查詢)
題目描述:
給定一個排序陣列nums(nums中有重複元素)與目標值target,如果target在nums裡出現,則返回target所在區間的左右端點下標,[左端點,右端點],如果target在nums裡未出現,則返回[-1,-1]。
使用二分法分別求出左右端點的位置,程式碼如下:
//查詢左端點位置
int left_bound(int nums[],int n,int target){
int begin =0;
int end=n-1;
while(begin<=end){
int mid=(begain+end)/2;
if (target==nums[mid]){
if (nums[mid-1]<target || mid==0){
return mid;
}
end=mid-1;
}
else if (target<nums[mid]){
end=mid-1;
}
else if (target>nums[mid]){
begin=mid+1;
}
}
return -1;
}
//查詢右端點位置
int right_bound(int nums[],int n,int target){
int begin =0;
int end=n-1;
while(begin<=end){
int mid=(begain+end)/2;
if (target==nums[mid]){
if (nums[mid+1]>target || mid==n-1){
return mid;
}
begin=mid+1;
}
else if (target<nums[mid]){
end=mid-1;
}
else if (target>nums[mid]){
begin=mid+1;
}
}
return -1;
}
3. LeetCode 200. Number of Islands(島嶼數量)
題目描述:
用一個二維陣列代表一張地圖,這張地圖由字元“0”與字元“1”組成,其中“0”字元代表水域,“1”字元代表小島土地。小島“1”被水“0”所包圍,當小島土地“1”在水平和垂直方向相連線時,認為是同一塊土地。求這張地圖中小島的數量。如下圖分別是1和3個小島:
演算法分析:
第一步:
第二步:
一個完整的搜尋示意圖:
完整程式碼實現:
遞迴深度搜索——小島數量
#include <stdio.h>
#include <stdlib.h>
#define MAXN 500
void DFS(int mark[][MAXN], char **grid,
int gridRowSize, int gridColSize,
int x, int y){
mark[x][y] = 1;
static const int dx[] = {-1, 1, 0, 0};
static const int dy[] = {0, 0, -1, 1};
int i;
for (i = 0; i < 4; i++){
int newx = dx[i] + x;
int newy = dy[i] + y;
if (newx < 0 || newx >= gridRowSize ||
newy < 0 || newy >= gridColSize){
continue;
}
if (mark[newx][newy] == 0 && grid[newx][newy] == '1'){
DFS(mark, grid, gridRowSize, gridColSize, newx, newy);
}
}
}
int numIslands(char **grid, int gridRowSize, int gridColSize) {
int island_num = 0;
int mark[MAXN][MAXN] = {0};
int i, j;
for (i = 0; i < gridRowSize; i++){
for (j = 0; j < gridColSize; j++){
if (mark[i][j] == 0 && grid[i][j] == '1'){
DFS(mark, grid, gridRowSize, gridColSize, i, j);
island_num++;
}
}
}
return island_num;
}
int main(){
char **grid;
char str[10][10] = {"11100", "11000", "00100", "00011"};
int i, j;
grid = (char **)malloc(sizeof(char *) * 10);
for (i = 0; i < 4; i++){
grid[i] = (char *)malloc(sizeof(char) * 10);
for (j = 0; j < 5; j++){
grid[i][j] = str[i][j];
}
}
printf("%d\n", numIslands(grid, 4, 5));
for (i = 0; i < 10; i++){
free(grid[i]);
}
free(grid);
return 0;
}