c語言搜索演算法
它沒有固定的寫法, 但是大框都差不多, 一定要使用隊列, 因為隊列的存在可以維護程序按照廣度優先的方式進行搜索。即層次遍歷
可以給你一份我作過的一個題的代碼,大體上就是這個樣子
/****************************************************\
*
* Title : Rescue
* From : HDU 1242
* AC Time : 2012.01.12
* Type : 廣度優先搜索求最短步數
* Method :從目標結點向回搜索,初始結點有多個
*
\****************************************************/
#include <stdio.h>
#include <string.h>
#define DATASIZE 201
#define QUEUESIZE 65536
typedef struct
{
int x,y;
}CPOINT;
int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa);
int direction[][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int main(void)
{
int m,n,i,j,res;
CPOINT cpa;
char map[DATASIZE][DATASIZE];
freopen("c:\\in.data","r",stdin);
while(scanf("%d%d%*c",&n,&m) != EOF) {
for(i = 0 ; i < n ; i++) {
gets(map[i]);
for(j = 0 ; j < m ; j++) {
if(map[i][j] == 'a') {
cpa.x = i;
cpa.y = j;
}
}
}
res = bfs(map, n, m, cpa);
if(res) {
printf("%d\n",res);
} else {
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
}
return 0;
}
int bfs(char map[][DATASIZE], int n, int m, CPOINT cpa)
{
CPOINT q[QUEUESIZE],u,np;
int vis[DATASIZE][DATASIZE],step[DATASIZE][DATASIZE],i,front,rear,res;
memset(q, 0, sizeof(q));
memset(vis, 0, sizeof(vis));
memset(step, 0, sizeof(step));
front = rear = res = 0;
q[rear++] = cpa;
vis[cpa.x][cpa.y] = 1;
step[cpa.x][cpa.y] = 0;
while(front <= rear) {
u = q[front++];
if(map[u.x][u.y] == 'r') {
res = step[u.x][u.y];
break;
}
for(i = 0 ; i < 4; i++) {
np.x = u.x + direction[i][0];
np.y = u.y + direction[i][1];
if(np.x >= 0 && np.x < n && np.y >= 0 && np.y < m && !vis[np.x][np.y] && map[np.x][np.y] != '#' ) {
vis[np.x][np.y] = 1;
q[rear++] = np;
step[np.x][np.y] = step[u.x][u.y] + 1;
if(map[np.x][np.y] == 'x') {
++step[np.x][np.y];
}
}
}
}
return res;
}
② c語言演算法有哪些
這里整理c語言常用演算法,主要有:
交換演算法
查找最小值演算法
冒泡排序
選擇排序
插入排序
shell排序 (希爾排序)
歸並排序
快速排序
二分查找演算法
查找重復演算法
③ c語言的折中查找法的演算法
#include <stdio.h>
#define N 21
void main(void)
{
int a[N];
int i,n,num;
int top,bottom,mid;
int flag=1; //如果在表列中找到數字,則值為1,否則為0
int loc=-1;//要查找的數在表列中的位置,如果loca=-1表示表列中沒有這個數;如果有這個數,則它的值為所在的位置
printf("你想在多少個數中進行折半查找,請輸入(1--20):");
scanf("%d",&n);
while(n<1 || n>20)
{
printf("你輸入的數不正確,請重新輸入。\n");
printf("你想在多少個數中進行折半查找,請輸入(1--20):");
scanf("%d",&n);
}
printf("請你輸入一個整數 a[1]:");
scanf("%d",&a[1]);
i=2;
while(i<=n) //輸入從小到大的表列
{
printf("請你輸入一個整數 a[%d]:",i);
scanf("%d",&a[i]);
if(a[i] > a[i-1])
i++;
else
printf("你輸入的數不滿足要求,請重新輸入。\n");
}
//輸出表列
printf("\n輸出表列\n");
for(i=1; i<=n; i++)
{
printf("%6d",a[i]);
}
printf("\n");
printf("請你輸入要查找的數:");
scanf("%d",&num);
flag=1; //假設輸入的數在表列中
top=n;
bottom=1;
mid=(top+bottom)/2;
while(flag)
{
printf("top=%d, bottom=%d, mid=%d, a[%d]=%d\n",top,bottom,mid,mid,a[mid]);
if( (num>a[top]) || (num<a[bottom]) ) //輸入的數 num>a[top] 或者 num<a[bottom],肯定num不在這個表列中
{
loc=-1;
flag=0;
}
else if(a[mid]==num) //如果num 等於找到的數
{
loc=mid;
printf("找到數 %6d 的位置%2d\n",num,loc);
break;
}
else if(a[mid]>num) //若 a[mid]>num,則num 一定在 a[bottom]和a[mid-1]范圍之內
{
top=mid-1;
mid=(top+bottom)/2;
}
else if(a[mid]<num) //若 a[mid]<num,則num 一定在 a[mid+1]和a[top]范圍之內
{
bottom=mid+1;
mid=(top+bottom)/2;
}
}
if(loc==-1)
{
printf("%d 這個數在表列中沒有找到。\n",num);
}
printf("折半查找結束:");
scanf("%d",&n);
}
④ c語言常用演算法有哪些
0) 窮舉法
窮舉法簡單粗暴,沒有什麼問題是搞不定的,只要你肯花時間。同時對於小數據量,窮舉法就是最優秀的演算法。就像太祖長拳,簡單,人人都能會,能解決問題,但是與真正的高手過招,就頹了。
1) 貪婪演算法
貪婪演算法可以獲取到問題的局部最優解,不一定能獲取到全局最優解,同時獲取最優解的好壞要看貪婪策略的選擇。特點就是簡單,能獲取到局部最優解。就像打狗棍法,同一套棍法,洪七公和魯有腳的水平就差太多了,因此同樣是貪婪演算法,不同的貪婪策略會導致得到差異非常大的結果。
2) 動態規劃演算法
當最優化問題具有重復子問題和最優子結構的時候,就是動態規劃出場的時候了。動態規劃演算法的核心就是提供了一個memory來緩存重復子問題的結果,避免了遞歸的過程中的大量的重復計算。動態規劃演算法的難點在於怎麼將問題轉化為能夠利用動態規劃演算法來解決。當重復子問題的數目比較小時,動態規劃的效果也會很差。如果問題存在大量的重復子問題的話,那麼動態規劃對於效率的提高是非常恐怖的。就像斗轉星移武功,對手強它也會比較強,對手若,他也會比較弱。
3)分治演算法
分治演算法的邏輯更簡單了,就是一個詞,分而治之。分治演算法就是把一個大的問題分為若干個子問題,然後在子問題繼續向下分,一直到base cases,通過base cases的解決,一步步向上,最終解決最初的大問題。分治演算法是遞歸的典型應用。
4) 回溯演算法
回溯演算法是深度優先策略的典型應用,回溯演算法就是沿著一條路向下走,如果此路不同了,則回溯到上一個
分岔路,在選一條路走,一直這樣遞歸下去,直到遍歷萬所有的路徑。八皇後問題是回溯演算法的一個經典問題,還有一個經典的應用場景就是迷宮問題。
5) 分支限界演算法
回溯演算法是深度優先,那麼分支限界法就是廣度優先的一個經典的例子。回溯法一般來說是遍歷整個解空間,獲取問題的所有解,而分支限界法則是獲取一個解(一般來說要獲取最優解)。
⑤ A*搜尋演算法的代碼實現(C語言實現)
用C語言實現A*最短路徑搜索演算法,作者 Tittup frog(跳跳蛙)。 #include<stdio.h>#include<math.h>#defineMaxLength100 //用於優先隊列(Open表)的數組#defineHeight15 //地圖高度#defineWidth20 //地圖寬度#defineReachable0 //可以到達的結點#defineBar1 //障礙物#definePass2 //需要走的步數#defineSource3 //起點#defineDestination4 //終點#defineSequential0 //順序遍歷#defineNoSolution2 //無解決方案#defineInfinity0xfffffff#defineEast(1<<0)#defineSouth_East(1<<1)#defineSouth(1<<2)#defineSouth_West(1<<3)#defineWest(1<<4)#defineNorth_West(1<<5)#defineNorth(1<<6)#defineNorth_East(1<<7)typedefstruct{ signedcharx,y;}Point;constPointdir[8]={ {0,1},//East {1,1},//South_East {1,0},//South {1,-1},//South_West {0,-1},//West {-1,-1},//North_West {-1,0},//North {-1,1}//North_East};unsignedcharwithin(intx,inty){ return(x>=0&&y>=0 &&x<Height&&y<Width);}typedefstruct{ intx,y; unsignedcharreachable,sur,value;}MapNode;typedefstructClose{ MapNode*cur; charvis; structClose*from; floatF,G; intH;}Close;typedefstruct//優先隊列(Open表){ intlength; //當前隊列的長度 Close*Array[MaxLength]; //評價結點的指針}Open;staticMapNodegraph[Height][Width];staticintsrcX,srcY,dstX,dstY; //起始點、終點staticCloseclose[Height][Width];//優先隊列基本操作voidinitOpen(Open*q) //優先隊列初始化{ q->length=0; //隊內元素數初始為0}voidpush(Open*q,Closecls[Height][Width],intx,inty,floatg){ //向優先隊列(Open表)中添加元素 Close*t; inti,mintag; cls[x][y].G=g; //所添加節點的坐標 cls[x][y].F=cls[x][y].G+cls[x][y].H; q->Array[q->length++]=&(cls[x][y]); mintag=q->length-1; for(i=0;i<q->length-1;i++) { if(q->Array[i]->F<q->Array[mintag]->F) { mintag=i; } } t=q->Array[q->length-1]; q->Array[q->length-1]=q->Array[mintag]; q->Array[mintag]=t; //將評價函數值最小節點置於隊頭}Close*shift(Open*q){ returnq->Array[--q->length];}//地圖初始化操作voidinitClose(Closecls[Height][Width],intsx,intsy,intdx,intdy){ //地圖Close表初始化配置 inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { cls[i][j].cur=&graph[i][j]; //Close表所指節點 cls[i][j].vis=!graph[i][j].reachable; //是否被訪問 cls[i][j].from=NULL; //所來節點 cls[i][j].G=cls[i][j].F=0; cls[i][j].H=abs(dx-i)+abs(dy-j); //評價函數值 } } cls[sx][sy].F=cls[sx][sy].H; //起始點評價初始值 // cls[sy][sy].G=0; //移步花費代價值 cls[dx][dy].G=Infinity;}voidinitGraph(constintmap[Height][Width],intsx,intsy,intdx,intdy){ //地圖發生變化時重新構造地 inti,j; srcX=sx; //起點X坐標 srcY=sy; //起點Y坐標 dstX=dx; //終點X坐標 dstY=dy; //終點Y坐標 for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { graph[i][j].x=i;//地圖坐標X graph[i][j].y=j;//地圖坐標Y graph[i][j].value=map[i][j]; graph[i][j].reachable=(graph[i][j].value==Reachable); //節點可到達性 graph[i][j].sur=0;//鄰接節點個數 if(!graph[i][j].reachable) { continue; } if(j>0) { if(graph[i][j-1].reachable) //left節點可以到達 { graph[i][j].sur|=West; graph[i][j-1].sur|=East; } if(i>0) { if(graph[i-1][j-1].reachable &&graph[i-1][j].reachable &&graph[i][j-1].reachable) //up-left節點可以到達 { graph[i][j].sur|=North_West; graph[i-1][j-1].sur|=South_East; } } } if(i>0) { if(graph[i-1][j].reachable) //up節點可以到達 { graph[i][j].sur|=North; graph[i-1][j].sur|=South; } if(j<Width-1) { if(graph[i-1][j+1].reachable &&graph[i-1][j].reachable &&map[i][j+1]==Reachable)//up-right節點可以到達 { graph[i][j].sur|=North_East; graph[i-1][j+1].sur|=South_West; } } } } }}intbfs(){ inttimes=0; inti,curX,curY,surX,surY; unsignedcharf=0,r=1; Close*p; Close*q[MaxLength]={&close[srcX][srcY]}; initClose(close,srcX,srcY,dstX,dstY); close[srcX][srcY].vis=1; while(r!=f) { p=q[f]; f=(f+1)%MaxLength; curX=p->cur->x; curY=p->cur->y; for(i=0;i<8;i++) { if(!(p->cur->sur&(1<<i))) { continue; } surX=curX+dir[i].x; surY=curY+dir[i].y; if(!close[surX][surY].vis) { close[surX][surY].from=p; close[surX][surY].vis=1; close[surX][surY].G=p->G+1; q[r]=&close[surX][surY]; r=(r+1)%MaxLength; } } times++; } returntimes;}intastar(){ //A*演算法遍歷 //inttimes=0; inti,curX,curY,surX,surY; floatsurG; Openq;//Open表 Close*p; initOpen(&q); initClose(close,srcX,srcY,dstX,dstY); close[srcX][srcY].vis=1; push(&q,close,srcX,srcY,0); while(q.length) { //times++; p=shift(&q); curX=p->cur->x; curY=p->cur->y; if(!p->H) { returnSequential; } for(i=0;i<8;i++) { if(!(p->cur->sur&(1<<i))) { continue; } surX=curX+dir[i].x; surY=curY+dir[i].y; if(!close[surX][surY].vis) { close[surX][surY].vis=1; close[surX][surY].from=p; surG=p->G+sqrt((curX-surX)*(curX-surX)+(curY-surY)*(curY-surY)); push(&q,close,surX,surY,surG); } } } //printf("times:%d ",times); returnNoSolution;//無結果}constintmap[Height][Width]={ {0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,1}, {0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,1}, {0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1}, {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0}, {0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0}, {0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1}, {0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}};constcharSymbol[5][3]={"□","▓","▽","☆","◎"};voidprintMap(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { printf("%s",Symbol[graph[i][j].value]); } puts(""); } puts("");}Close*getShortest(){ //獲取最短路徑 intresult=astar(); Close*p,*t,*q=NULL; switch(result) { caseSequential: //順序最近 p=&(close[dstX][dstY]); while(p) //轉置路徑 { t=p->from; p->from=q; q=p; p=t; } close[srcX][srcY].from=q->from; return&(close[srcX][srcY]); caseNoSolution: returnNULL; } returnNULL;}staticClose*start;staticintshortestep;intprintShortest(){ Close*p; intstep=0; p=getShortest(); start=p; if(!p) { return0; } else { while(p->from) { graph[p->cur->x][p->cur->y].value=Pass; printf("(%d,%d)→ ",p->cur->x,p->cur->y); p=p->from; step++; } printf("(%d,%d) ",p->cur->x,p->cur->y); graph[srcX][srcY].value=Source; graph[dstX][dstY].value=Destination; returnstep; }}voidclearMap(){ //ClearMapMarksofSteps Close*p=start; while(p) { graph[p->cur->x][p->cur->y].value=Reachable; p=p->from; } graph[srcX][srcY].value=map[srcX][srcY]; graph[dstX][dstY].value=map[dstX][dstY];}voidprintDepth(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { if(map[i][j]) { printf("%s",Symbol[graph[i][j].value]); } else { printf("%2.0lf",close[i][j].G); } } puts(""); } puts("");}voidprintSur(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { printf("%02x",graph[i][j].sur); } puts(""); } puts("");}voidprintH(){ inti,j; for(i=0;i<Height;i++) { for(j=0;j<Width;j++) { printf("%02d",close[i][j].H); } puts(""); } puts("");}intmain(intargc,constchar**argv){ initGraph(map,0,0,0,0); printMap(); while(scanf("%d%d%d%d",&srcX,&srcY,&dstX,&dstY)!=EOF) { if(within(srcX,srcY)&&within(dstX,dstY)) { if(shortestep=printShortest()) { printf("從(%d,%d)到(%d,%d)的最短步數是:%d ", srcX,srcY,dstX,dstY,shortestep); printMap(); clearMap(); bfs(); //printDepth(); puts((shortestep==close[dstX][dstY].G)?"正確":"錯誤"); clearMap(); } else { printf("從(%d,%d)不可到達(%d,%d) ", srcX,srcY,dstX,dstY); } } else { puts("輸入錯誤!"); } } return(0);}
⑥ c語言排序和查找
1)利用readData()函數從data1.txt中讀入不同規模的數據存入數組,
編寫基於數組的順序查找演算法,測試數據量為1萬、5萬、10萬、20萬、
30萬、40萬和50萬時的數據查詢時間。
演算法代碼如下:
1 int seqsearch(int a[],int n,int key)
2 {
3 int k=n-1;
4 while(k>=0&&a[k]!=key)
5 k--;
6 return (k);
7 }
2)利用readData()函數從data2.txt中讀入不同規模的有序數據存入數組,
編寫基於數組的二分查找演算法,測試數據量為1萬、5萬、10萬、20萬、30萬、
40萬和50萬時的數據查詢時間。
演算法代碼如下:
1 int binSearch(int a[],int n,int key)
2 {
3 int low=0;
4 int high=n-1;
5 int mid;
6 while(low<=high)
7 {
8 mid=(low+high)/2;
9 if(a[mid]==key) return mid;
10 if(a[mid]>key)
11 high=mid-1;
12 else
13 low=mid+1;
14 }
15 return -1;
16 }
3)請設計冒泡排序演算法函數void bubbleSort(int a[],int n),對a[1]..a[n]進行升序排序。
並測試在不同數據規模下的排序效率。
演算法代碼如下:
1 void bubbleSort(int a[],int n)
2 {
3 int i=1,j,flag=1;
4 while(i<=n-1&&flag)
5 {
6 flag=0;
7 for(j=1;j<=n-1-i;j++)
8 if(a[j+1]<a[j])
9 {
10 a[0]=a[j];
11 a[j]=a[j+1];
12 a[j+1]=a[0];
13 flag=1;
14 }
15 i++;
16 }
17 }