① 用c語言編寫三個演算法,BFS或DFS,爬山演算法,遺傳演算法實現八皇後問題
網路演算法名,加上八皇後
比如
BFS 八皇後問題 C語言。
或者
遺傳演算法 八皇後問題 C語言
然後根據搜索結果 就可以得到演算法和代碼了。
② 求C語言源代碼二分法求解非線性方程組的根(VC++6.0)
如果連續函數在給定區間不單調,很有可能中值*下界值和中值*上界值都大於0,那麼會跳出認為沒有根,而事實上很有可能這個中值點靠近函數極點。而真正用二分法求給定區閉明間的思路是:首先為函數求導,算出導函螞敏數的零點,然後再判斷零點性質,悶態枝最後將函數區間分為單調遞增和單調遞減間隔的形式,對每一段進行二分法求根。
#include <stdio.h>
#include <math.h>
#define DEFAULT_UPPER (10)
#define DEFAULT_LOWER (-10)
#define DEFAULT_E (0.00000001)
#define _MID(x,y) ((x+y)/2)
#define _VALUE(x) (2*x*x*x-4*x*x+3*x-6)
double _e;
int getRoot(double lower, double upper, double *result);
main()
{
double root;
printf("Enter a deviation:");
scanf("%lf",& _e);
if(_e == 0.0)
_e = DEFAULT_E;
if(getRoot(DEFAULT_LOWER, DEFAULT_UPPER, &root))
printf("Root:%2.8lf\n", root);
else
printf("Root:No Solution.\n");
}
int getRoot(double lower, double upper, double *result)
{
*result = _MID(lower,upper);
if(upper - lower <= _e)
return 1;
if(_VALUE(lower)*_VALUE(*result) <= 0)
return getRoot(lower, *result, result);
else if(_VALUE(*result)*_VALUE(upper) <= 0)
return getRoot(*result, upper, result);
else
return 0;
}
③ 圖的遍歷(c語言)完整上機代碼
//圖的遍歷演算法程序
//圖的遍歷是指按某條搜索路徑訪問圖中每個結點,使得每個結點均被訪問一次,而且僅被訪問一次。圖的遍歷有深度遍歷演算法和廣度遍歷演算法,程序如下:
#include <iostream>
//#include <malloc.h>
#define INFINITY 32767
#define MAX_VEX 20 //最大頂點個數
#define QUEUE_SIZE (MAX_VEX+1) //隊列長度
using namespace std;
bool *visited; //訪問標志數組
//圖的鄰接矩陣存儲結構
typedef struct{
char *vexs; //頂點向量
int arcs[MAX_VEX][MAX_VEX]; //鄰接矩陣
int vexnum,arcnum; //圖的當前頂點數和弧數
}Graph;
//隊列類
class Queue{
public:
void InitQueue(){
base=(int *)malloc(QUEUE_SIZE*sizeof(int));
front=rear=0;
}
void EnQueue(int e){
base[rear]=e;
rear=(rear+1)%QUEUE_SIZE;
}
void DeQueue(int &e){
e=base[front];
front=(front+1)%QUEUE_SIZE;
}
public:
int *base;
int front;
int rear;
};
//圖G中查找元素c的位置
int Locate(Graph G,char c){
for(int i=0;i<G.vexnum;i++)
if(G.vexs[i]==c) return i;
return -1;
}
//創建無向網
void CreateUDN(Graph &G){
int i,j,w,s1,s2;
char a,b,temp;
printf("輸入頂點數和弧數:");
scanf("%d%d",&G.vexnum,&G.arcnum);
temp=getchar(); //接收回車
G.vexs=(char *)malloc(G.vexnum*sizeof(char)); //分配頂點數目
printf("輸入%d個頂點.\n",G.vexnum);
for(i=0;i<G.vexnum;i++){ //初始化頂點
printf("輸入頂點%d:",i);
scanf("%c",&G.vexs[i]);
temp=getchar(); //接收回車
}
for(i=0;i<G.vexnum;i++) //初始化鄰接矩陣
for(j=0;j<G.vexnum;j++)
G.arcs[i][j]=INFINITY;
printf("輸入%d條弧.\n",G.arcnum);
for(i=0;i<G.arcnum;i++){ //初始化弧
printf("輸入弧%d:",i);
scanf("%c %c %d",&a,&b,&w); //輸入一條邊依附的頂點和權值
temp=getchar(); //接收回車
s1=Locate(G,a);
s2=Locate(G,b);
G.arcs[s1][s2]=G.arcs[s2][s1]=w;
}
}
//圖G中頂點k的第一個鄰接頂點
int FirstVex(Graph G,int k){
if(k>=0 && k<G.vexnum){ //k合理
for(int i=0;i<G.vexnum;i++)
if(G.arcs[k][i]!=INFINITY) return i;
}
return -1;
}
//圖G中頂點i的第j個鄰接頂點的下一個鄰接頂點
int NextVex(Graph G,int i,int j){
if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum){ //i,j合理
for(int k=j+1;k<G.vexnum;k++)
if(G.arcs[i][k]!=INFINITY) return k;
}
return -1;
}
//深度優先遍歷
void DFS(Graph G,int k){
int i;
if(k==-1){ //第一次執行DFS時,k為-1
for(i=0;i<G.vexnum;i++)
if(!visited[i]) DFS(G,i); //對尚未訪問的頂點調用DFS
}
else{
visited[k]=true;
printf("%c ",G.vexs[k]); //訪問第k個頂點
for(i=FirstVex(G,k);i>=0;i=NextVex(G,k,i))
if(!visited[i]) DFS(G,i); //對k的尚未訪問的鄰接頂點i遞歸調用DFS
}
}
//廣度優先遍歷
void BFS(Graph G){
int k;
Queue Q; //輔助隊列Q
Q.InitQueue();
for(int i=0;i<G.vexnum;i++)
if(!visited[i]){ //i尚未訪問
visited[i]=true;
printf("%c ",G.vexs[i]);
Q.EnQueue(i); //i入列
while(Q.front!=Q.rear){
Q.DeQueue(k); //隊頭元素出列並置為k
for(int w=FirstVex(G,k);w>=0;w=NextVex(G,k,w))
if(!visited[w]){ //w為k的尚未訪問的鄰接頂點
visited[w]=true;
printf("%c ",G.vexs[w]);
Q.EnQueue(w);
}
}
}
}
//主函數
void main(){
int i;
Graph G;
CreateUDN(G);
visited=(bool *)malloc(G.vexnum*sizeof(bool));
printf("\n廣度優先遍歷: ");
for(i=0;i<G.vexnum;i++)
visited[i]=false;
DFS(G,-1);
printf("\n深度優先遍歷: ");
for(i=0;i<G.vexnum;i++)
visited[i]=false;
BFS(G);
printf("\n程序結束.\n");
}
輸出結果為(紅色為鍵盤輸入的數據,權值都置為1):
輸入頂點數和弧數:8 9
輸入8個頂點.
輸入頂點0:a
輸入頂點1:b
輸入頂點2:c
輸入頂點3:d
輸入頂點4:e
輸入頂點5:f
輸入頂點6:g
輸入頂點7:h
輸入9條弧.
輸入弧0:a b 1
輸入弧1:b d 1
輸入弧2:b e 1
輸入弧3:d h 1
輸入弧4:e h 1
輸入弧5:a c 1
輸入弧6:c f 1
輸入弧7:c g 1
輸入弧8:f g 1
廣度優先遍歷: a b d h e c f g
深度優先遍歷: a b c d e f g h
程序結束.
已經在vc++內運行通過,這個程序已經達到要求了呀~
④ 數據結構C語言版 圖的遍歷 DFS和BFS演算法,用鄰接矩陣儲存 急阿在線等 求大神指點
#include <iostream>
#include<string.h>
#include<stack>
#include<queue>
const int Max=100;
const int VISITED=101010;
const int UNVISITED=111111;
const int AFFINITY=101010;
const int INFINITY=111111;
using namespace std;
class Edge
{
public:
int start;
int end;
int weight;
Edge(int st=0,int en=0,int w=0):start(st),end(en),weight(w){}
bool operator>(Edge oneEdge){return weight>oneEdge.weight?true:false;}
bool operator<(Edge oneEdge){return weight<oneEdge.weight?true:false;}
bool operator!=(Edge oneEdge)
{
if(weight!=oneEdge.weight||start!=oneEdge.start||end!=oneEdge.end)
return true;
return false;
}
};
class AdjGraf
{
private:
int verticesNum;
int edgeNum;
int **matrix;
int *Mark;
public:
AdjGraf(int vert)
{
int i=0,j=0;
verticesNum=vert;
matrix=(int**)new int*[vert];
for(i=0;i<vert;i++)
matrix[i]=new int[vert];
Mark=new int[vert];
for(i=0;i<vert;i++)
for(j=0;j<vert;j++)
{
matrix[i][j]=0;
}
for( int m=0;m<verticesNum;m++)
Mark[m]=UNVISITED;
}
~AdjGraf();
//返回與頂點oneVertex相關聯的第一條邊
Edge FirstEdge(int oneVertex);
//返回與邊PreEdge有相同關聯頂點oneVertex的下一條邊
Edge NextEdge( Edge preEdge);
//添加一條邊
void setEdge(int fromVertex,int toVertex,int weight);
//刪一條邊
void delEdge(int fromVertex,int toVertex);
//如果oneEdge是邊則返回TRUE,否則返回FALSE
bool IsEdge( Edge oneEdge)
{
if(oneEdge.start>=0&&oneEdge.start<verticesNum&&
oneEdge.end>=0&&oneEdge.end<verticesNum)
return true;
else return false;
}
//返回邊oneEdge的始點
int FromVertex(Edge oneEdge){return oneEdge.start;}
//返回邊oneEdge的終點
int ToVertex(Edge oneEdge){return oneEdge.end;}
//返回邊oneEdge的權
int Weight(Edge oneEdge){return oneEdge.weight;}
void visit(int i){cout<<i+1<<" ";}
void BFS(int i=1);
void DFS(int i);
void DFSTraverse(int v);
void DFSNoReverse(int f=1);
Edge UNVISITEDEdge(int f);
};
AdjGraf::~AdjGraf()
{
for(int i=0;i<verticesNum;i++)
delete[]matrix[i];
delete[]matrix;
}
Edge AdjGraf::FirstEdge(int oneVertex)
{ int i;
Edge tempEdge;
tempEdge.start=oneVertex;
for( i=0;i<verticesNum;i++)
if(matrix[oneVertex][i]!=0)
break;
tempEdge.end=i;
tempEdge.weight=matrix[oneVertex][i];
return tempEdge;
}
Edge AdjGraf ::NextEdge( Edge preEdge)
{
Edge tempEdge;
tempEdge.start=preEdge.start;
int i=0;
for(i=preEdge.end+1;i<verticesNum;i++)
if(matrix[preEdge.start][i]!=0)
break;
tempEdge.end=i;
tempEdge.weight=matrix[preEdge.start][i];
return tempEdge;
}
void AdjGraf::setEdge(int fromVertex,int toVertex,int weight)
{
if(matrix[fromVertex-1][toVertex-1]==0)
edgeNum++;
matrix[fromVertex-1][toVertex-1]=weight;
}
void AdjGraf::delEdge(int fromVertex,int toVertex)
{
if(matrix[fromVertex][toVertex]==0)
edgeNum--;
matrix[fromVertex][toVertex]=0;
}
/*************遞歸實現深度優先****************/
void AdjGraf::DFS(int i)
{
visit(i);
Mark[i]=VISITED;
for(Edge e=FirstEdge(i);IsEdge(e);e=NextEdge(e))
if(Mark[ToVertex(e)] == UNVISITED)
DFS(ToVertex(e));
}
void AdjGraf::DFSTraverse(int v)
{
v--;
int i;
for(i=0;i<verticesNum;i++)
Mark[i]=UNVISITED;
for(i=v;i<v+verticesNum;i++)
if (Mark[i]== UNVISITED)
DFS(i);
}
Edge AdjGraf::UNVISITEDEdge(int f)
{ int i;
for( Edge e=FirstEdge(f);IsEdge(e);e=NextEdge(e))
if(Mark[e.end]==UNVISITED)
return e;
return Edge(verticesNum,verticesNum,0) ;
}
/*************非遞歸實現深度優先**************/
void AdjGraf::DFSNoReverse(int f)
{
f--;
int i,counter=0,j,flag;
stack<int>Temp;
for(i=0;i<verticesNum;i++)
Mark[i]=UNVISITED;
flag=f;
while(counter<12)
{
while(flag!=verticesNum&&IsEdge(UNVISITEDEdge(flag))||!Temp.empty())
{
// Edge tempEdge=UNVISITEDEdge(j);
while(flag!=verticesNum&&Mark[flag]==UNVISITED)
{
visit(flag);
Mark[flag]=VISITED;
Temp.push(flag);
flag=UNVISITEDEdge(flag).end;
}
if(!Temp.empty())
{
flag=UNVISITEDEdge(Temp.top()).end;
Temp.pop();
}
}
if(Mark[counter]==UNVISITED) flag=counter;
else counter++;
}
}
/*************非遞歸實現廣度優先**************/
void AdjGraf::BFS(int v)
{
int i;
v--;
for( i=0;i<verticesNum;i++)
Mark[i]=UNVISITED;
queue<int>tempqueue;
i=0;
/*********v先從指定位置開始,然後從v=0,1,2......
依次檢查是否有孤立結點*****************/
while(i<verticesNum)
{
tempqueue.push(v);
while(!tempqueue.empty())
{
v=tempqueue.front();
tempqueue.pop();
if(Mark[v]==UNVISITED)
{
visit(v);
Mark[v]=VISITED;
for(Edge e=FirstEdge(v);IsEdge(e);e=NextEdge(e))
{
v=ToVertex(e);
tempqueue.push(v);
}
}
}
/***********防止出現孤立點****************/
if(Mark[i]==VISITED) i++;
else v=i;
}
}
int main()
{
AdjGraf Graph(12);
Graph.setEdge(1,2,1);
Graph.setEdge(2,1,1);
Graph.setEdge(1,3,5);
Graph.setEdge(3,1,5);/** V1 V12 V11 */
Graph.setEdge(2,4,3);/** / \ / \ */
Graph.setEdge(4,2,3);/** v2 v3 V10 V9 */
Graph.setEdge(2,5,7);/** / \ / \ */
Graph.setEdge(5,2,7);/** v4 v5 v6-v7 */
Graph.setEdge(4,8,4);/** \ / */
Graph.setEdge(8,4,4);/** v8 */
Graph.setEdge(5,8,3);
Graph.setEdge(8,5,3);
Graph.setEdge(3,6,2);
Graph.setEdge(6,3,2);
Graph.setEdge(3,7,1);
Graph.setEdge(7,3,1);
Graph.setEdge(6,7,6);
Graph.setEdge(7,6,6);
Graph.setEdge(12,9,6);
Graph.setEdge(9,12,6);
Graph.setEdge(12,10,6);
Graph.setEdge(10,12,6);
Graph.setEdge(11,11,6);
cout<<"DFSTraverse:"<<endl;
Graph.DFSTraverse(3);
cout<<endl;
cout<<"DFSNoReverse:"<<endl;
Graph.DFSNoReverse(3);
cout<<endl;
cout<<"BFS:"<<endl;
Graph.BFS(3);
cout<<endl;
return 0;
}
以上代碼運行環境codeblocks 程序採用DFS遞歸演算法 DFS非遞歸演算法 BFS非遞歸演算法
望採納~
⑤ 用c語言做連連看其中方案圖塊的鏈接判斷,具體如何實現
連扮配連看游戲中,需要實現方案圖塊的鏈接判斷,即兩個方塊是否可以通過一定的路徑相連。
在C語言中,可以使用二維數組表示連連看游戲界面,每個數組元素表示一個方塊。為了方便判斷方塊之間的鏈接關系,可以給每個方塊添加一個編號或者標記。
在實現方塊鏈接判斷時,可以採用廣度優先搜索(BFS)演算法。具體實現過程如下:
首先選中兩個方塊,假設它們的編號分別為a和b。
以方塊a為起點,使用BFS演算法搜索所有與a相連的方塊,並將其標記為已訪問。
如果在上一步中發現了方塊b,則表示a和b可以通過一定的路徑相連。
如果沒有找到方塊b,就選取一個與a相連的未訪問方塊,重復上述步驟,直到找到方塊b或者搜索完所有與a相連的方塊。
在具體實現中,可以使用一個隊列來存儲待訪問的方塊,用一個數組來記錄每個方塊是否已經訪問過,以避免重復訪問。
需要注意的是,在搜索相鄰方塊時,需要判斷兩個方塊之間是否有障礙物,即是否存在無法通過的路徑。可以通過檢查路徑上的所有方塊,是否都是空閑狀態,來判斷是否存在障礙物。
另外,在實現連連看廳枝指游戲時,還需要考慮方塊搭鄭消除的邏輯、分數計算等問題。
⑥ c語言數據結構(考題,測試你的能力)--編寫源代碼
P88 稀疏矩陣十字鏈表相加演算法如下:
/*假設ha為A稀疏矩陣十字鏈表的頭指針,hb為B稀疏矩陣十字鏈表的頭指針*/
#include<stdio.h>
#define maxsize 100
struct linknode
{ int i,j;
struct linknode *cptr,*rptr;
union vnext
{ int v;
struct linknode *next;} k;
};
struct linknode creatlindmat( ) /*建立十字鏈表*/
{ int x, m, n, t, s, i, j, k;
struct linknode *p , *q, *cp[maxsize],*hm;
printf("請輸入稀疏矩陣的行、列數及非零元個數\n");
scanf("%d%d%d",&m,&n,&t);
if (m>n) s=m; else s=n;
hm=(struct linknode*)malloc(sizeof(struct linknode)) ;
hm->i=m; hm->j=n;
cp[0]=hm;
for (i=1; i<=s;i++)
{ p=(struct linknode*)malloc(sizeof(struct linknode)) ;
p->i=0; p->j=0;
p->rptr=p; p->cptr=p;
cp[i]=p;
cp[i-1]->k.next=p;
}
cp[s]->k.next=hm;
for( x=1;x<=t;x++)
{ printf("請輸入一個三元組(i,j,v)\n");
scanf("%d%d%d",&i,&j,&k);
p=(struct linknode*)malloc(sizeof(struct linknode));
p->i=i; p->j=j; p->k.v=k;
/*以下是將p插入到第i行鏈表中 */
q=cp[i];
while ((q->rptr!=cp[i]) &&( q->rptr->j<j))
q=q->rptr;
p->rptr=q->rptr;
q->rptr=p;
/*以下是將P插入到第j列鏈表中*/
q=cp[j];
while((q->cptr!=cp[j]) &&( q->cptr->i<i))
q=q->cptr;
p->cptr=q->cptr;
q->cptr=p;
}
return hm;
}
/* ha和hb表示的兩個稀疏矩陣相加,相加的結果放入ha中*/
struct linknode *matadd(struct linknode *ha, struct linknode *hb)
{ struct linknode *pa, *pb, *qa, *ca,*cb,*p,*q;
struct linknode *hl[maxsize];
int i , j, n;
if((ha->i!=hb->i)||(ha->j!=hb->j))
printf("矩陣不匹配,不能相加\n");
else
{ p=ha->k.next; n=ha->j;
for (i=1;i<=n; i++)
{ hl[i]=p;
p=p->k.next;
}
ca=ha->k.next; cb=hb->k.next;
while(ca->i==0)
{pa=ca->rptr; pb=cb->rptr;
qa=ca;
while(pb->j!=0)
{ if((pa->j<pb->j)&&(pa->j!=0))
{ qa=pa; pa=pa->rptr;}
else if ((pa->j>pb->j)||(pa->j==0)) /*插入一個結點*/
{ p=(struct linknode*)malloc(sizeof(struct linknode));
p->i=pb->i; p->j=pb->j;
p->k.v=pb->k.v;
qa->rptr=p; p->rptr=pa;
qa=p; pb=pb->rptr;
j=p->j; q=hl[j]->cptr;
while((q->i<p->i)&&(q->i!=0))
{ hl[j]=q; q=hl[j]->cptr;}
hl[j]->cptr=p; p->cptr=q;
hl[j]=p;
}
else
{pa->k.v=pa->k.v+pb->k.v;
if(pa->k.v==0) /*刪除一個結點*/
{ qa->rptr=pa->rptr;
j=pa->j; q=hl[j]->cptr;
while (q->i<pa->i)
{hl[j]=q; q=hl[j]->cptr;}
hl[j]->cptr=q->cptr;
pa=pa->rptr; pb=pb->rptr;
free(q);
}
else
{ qa=pa; pa=pa->rptr;
pb=pb->rptr;
}
}
}
ca=ca->k.next; cb=cb->k.next;
}
}
return ha;
}
void print(struct linknode *ha) /*輸出十字鏈表*/
{ struct linknode *p,*q;
p=ha->k.next;
while(p->k.next!=ha)
{ q=p->rptr;
while(q->rptr!=p)
{ printf("%3d%3d%3d\t",q->i,q->j,q->k.v);
q=q->rptr;
}
if(p!=q)
printf("%3d%3d%3d",q->i,q->j,q->k.v);
printf("\n");
p=p->k.next;
}
q=p->rptr;
while(q->rptr!=p)
{ printf("%3d%3d%3d\t",q->i,q->j,q->k.v);
q=q->rptr;
}
if(p!=q)
printf("%3d%3d%3d",q->i,q->j,q->k.v);
printf("\n");
}
void main()
{
struct linknode *ha=NULL,*hb=NULL,*hc=NULL;
ha=creatlindmat( ); /*生成一個十字鏈表ha*/
hb=creatlindmat( ); /*生成另一個十字鏈表hb*/
printf("A:\n"); /*輸出十字鏈表ha*/
print(ha);printf("\n");
printf("B:\n"); /*輸出十字鏈表hb*/
print(hb);printf("\n");
hc=matadd(ha,hb); /*十字鏈表相加*/
printf("A+B:\n"); /*輸出相加後的結果*/
print(hc);printf("\n");
}
P94 數據類型描述如下:
#define elemtype char
struct node1
{ int atom;
struct node1 *link;
union
{
struct node1 *slink;
elemtype data;
} ds;
}
P95 數據類型描述如下:
struct node2
{ elemtype data;
struct node2 *link1,*link2;
}
P96 求廣義表的深度depth(LS)
int depth(struct node1 *LS)
{
int max=0,dep;
while(LS!=NULL)
{ if(LS->atom==0) //有子表
{ dep=depth(LS->ds.slink);
if(dep>max) max=dep;
}
LS=LS->link;
}
return max+1;
}
P96 廣義表的建立creat(LS)
void creat(struct node1 *LS)
{
char ch;
scanf("%c",&ch);
if(ch=='#')
LS=NULL;
else if(ch=='(')
{LS=(struct node*)malloc(sizeof(struct node));
LS->atom=0;
creat(LS->ds.slink);
}
else
{ LS=(struct node*)malloc(sizeof(struct node));
LS->atom=1;
LS->ds.data=ch;
}
scanf("%c",&ch);
if(LS==NULL);
else if(ch==',')
creat(LS->link);
else if((ch==')')||(ch==';'))
LS->link=NULL;
}
P97 輸出廣義表print(LS)
void print(struct node1 *LS)
{
if(LS->atom==0)
{
printf("(");
if(LS->ds.slink==NULL)
printf("#");
else
print(LS->ds.slink);
}
else
printf("%c ",LS->ds.data);
if(LS->atom==0)
printf(")");
if(LS->link!=NULL)
{
printf(";");
print(LS->link);
}
}
P98 該演算法的時間復雜度為O(n)。整個完整程序如下:
#include<stdio.h>
#define elemtype char
struct node1
{ int atom;
struct node1 *link;
union
{
struct node1 *slink;
elemtype data;
} ds;
};
void creat(struct node1 LS) /*建立廣義表的單鏈表*/
{
char ch;
scanf("%c",&ch);
if(ch=='#')
LS=NULL;
else if(ch=='(')
{LS=(struct node1*)malloc(sizeof(struct node1));
LS->atom=0;
creat(LS->ds.slink);
}
else
{ LS=(struct node1*)malloc(sizeof(struct node1));
LS->atom=1;
LS->ds.data=ch;
}
scanf("%c",&ch);
if(LS==NULL);
else if(ch==',')
creat(LS->link);
else if((ch==')')||(ch==';'))
LS->link=NULL;
}
void print(struct node1 LS) /*輸出廣義單鏈表*/
{
if(LS->atom==0)
{
printf("(");
if(LS->ds.slink==NULL)
printf("#");
else
print(LS->ds.slink);
}
else
printf("%c",LS->ds.data);
if(LS->atom==0)
printf(")");
if(LS->link!=NULL)
{
printf(";");
print(LS->link);
}
}
int depth(struct node1 LS) /*求廣義表的深度*/
{
int max=0;
while(LS!=NULL)
{ if(LS->atom==0)
{ int dep=depth(LS->ds.slink);
if(dep>max) max=dep;
}
LS=LS->link;
}
return max+1;
}
main()
{ int dep;
struct node1 *p=NULL;
creat(p); /*建立廣義表的單鏈表*/
print(p); /*輸出廣義單鏈表*/
dep=depth(p); /*求廣義表的深度*/
printf("%d\n",dep);
}
第六章 樹
P109 二叉鏈表的結點類型定義如下:
typedef struct btnode
{ anytype data;
struct btnode *Lch,*Rch;
}tnodetype;
P109 三叉鏈表的結點類型定義如下:
typedef struct btnode3
{ anytype data;
struct btnode *Lch,*Rch,*Parent ;
}tnodetype3;
P112 C語言的先序遍歷演算法:
void preorder (tnodetype *t)
/*先序遍歷二叉樹演算法,t為指向根結點的指針*/
{ if (t!=NULL)
{printf("%d ",t->data);
preorder(t->lch);
preorder(t->rch);
}
}
P113 C語言的中序遍歷演算法:
void inorder(tnodetype *t)
/*中序遍歷二叉樹演算法,t為指向根結點的指針*/
{
if(t!=NULL)
{inorder(t->lch);
printf("%d ",t->data);
inorder(t->rch);
}
}
P113 C語言的後序遍歷演算法:
void postorder(tnodetype *t)
/*後序遍歷二叉樹演算法,t為指向根結點的指針*/
{
if(t!=NULL)
{ postorder(t->lch);
postorder(t->rch);
printf("%d ",t->data);
}
}
P114 如果引入隊列作為輔助存儲工具,按層次遍歷二叉樹的演算法可描述如下:
void levelorder(tnodetype *t)
/*按層次遍歷二叉樹演算法,t為指向根結點的指針*/
{tnodetype q[20]; /*輔助隊列*/
front=0;
rear=0; /*置空隊列*/
if (t!=NULL)
{ rear++;
q[rear]=t; /*根結點入隊*/
}
while (front!=rear)
{ front++;
t=q [front];
printf ("%c\n",t->data);
if (t->lch!=NULL) /*t的左孩子不空,則入隊*/
{ rear++;
q [rear]=t->lch;
}
if (t->rch!=NULL) /*t的右孩子不空,則入隊*/
{ rear++;
q [rear]=t->rch;
}
}
}
P115 以中序遍歷的方法統計二叉樹中的結點數和葉子結點數,演算法描述為:
void inordercount (tnodetype *t)
/*中序遍歷二叉樹,統計樹中的結點數和葉子結點數*/
{ if (t!=NULL)
{ inordercount (t->lch); /*中序遍歷左子樹*/
printf ("%c\n",t->data); /*訪問根結點*/
countnode++; /*結點計數*/
if ((t->lch==NULL)&&(t->rch==NULL))
countleaf++; /*葉子結點計數*/
inordercount (t->rch); /*中序遍歷右子樹*/
}
}
P115 可按如下方法計算一棵二叉樹的深度:
void preorderdeep (tnodetype *t,int j)
/*先序遍歷二叉樹,並計算二叉樹的深度*/
{ if (t!=NULL)
{ printf ("%c\n",t->data); /*訪問根結點*/
j++;
if (k<j) k=j;
preorderdeep (t->lch,j); /*先序遍歷左子樹*/
preorderdeep (t->rch,j); /*先序遍歷右子樹*/
}
}
P117 線索二叉樹的結點類型定義如下:
struct nodexs
{anytype data;
struct nodexs *lch, *rch;
int ltag,rtag; /*左、右標志域*/
}
P117 中序次序線索化演算法
void inorderxs (struct nodexs *t)
/*中序遍歷t所指向的二叉樹,並為結點建立線索*/
{ if (t!=NULL)
{ inorderxs (t->lch);
printf ("%c\n",t->data);
if (t->lch!=NULL)
t->ltag=0;
else { t->ltag=1;
t->lch=pr;
} /*建立t所指向結點的左線索,令其指向前驅結點pr*/
if (pr!=NULL)
{ if (pr->rch!=NULL)
pr->rtag=0;
else { pr->rtag=1;
pr->rch=p;
}
} /*建立pr所指向結點的右線索,令其指向後繼結點p*/
pr=p;
inorderxs (t->rch);
}
}
P118 在中根線索樹上檢索某結點的前驅結點的演算法描述如下:
struct nodexs * inpre (struct nodexs *q)
/*在中根線索樹上檢索q所指向的結點的前驅結點*/
{ if (q->ltag==1)
p=q->lch;
else { r=q->lch;
while (r->rtag!=1)
r=r->rch;
p=r;
}
return (p);
}
P119 在中根線索樹上檢索某結點的後繼結點的演算法描述如下:
struct nodexs * insucc (struct nodexs *q)
/*在中根線索樹上檢索q所指向的結點的後繼結點*/
{ if (q->rtag==1)
p=q->rch;
else { r=q->rch;
while (r->ltag!=1)
r=r->lch;
p=r;
}
return (p);
}
P120 演算法程序用C語言描述如下:
void sortBT(BT *t,BT *s) /*將指針s所指的結點插入到以t為根指針的二叉樹中*/
{ if (t==NULL) t=s; /*若t所指為空樹,s所指結點為根*/
else if (s->data < t->data)
sortBT(t->lch,s); /*s結點插入到t的左子樹上去*/
else
sortBT(t->rch,s); /*s結點插入到t的右子樹上去*/
}
P121 二叉排序樹結點刪除演算法的C語言描述如下:
void delnode(bt,f,p)
/*bt為一棵二叉排序樹的根指針,p指向被刪除結點,f指向其雙親*/
/*當p=bt時f為NULL*/
{ fag=0; /*fag=0時需修改f指針信息,fag=1時不需修改*/
if (p->lch==NULL)
s=p->rch; /*被刪除結點為葉子或其左子樹為空*/
else if (p->rch==NULL)
s=p->lch;
else { q=p; /*被刪除結點的左、右子樹均非空*/
s=p->lch;
while (s->rch!=NULL)
{ q=s;
s=s->rch;
} /*尋找s結點*/
if (q=p)
q->lch=s->lch;
else q->rch=s->lch;
p->data=s->data; /*s所指向的結點代替被刪除結點*/
DISPOSE(s);
Fag=1;
}
if (fag=0) /*需要修改雙親指針*/
{ if (f=NULL)
bt=s; /*被刪除結點為根結點*/
else if (f->lch=p)
f->lch=s;
else f->rch=s;
DISPOSE(p); /*釋放被刪除結點*/
}
}
第七章 圖
P134 用鄰接矩陣表示法表示圖,除了存儲用於表示頂點間相鄰關系的鄰接矩陣外,通常還需要用一個順序表來存儲頂點信息。其形式說明如下:
# define n 6 /*圖的頂點數*/
# define e 8 /*圖的邊(弧)數*/
typedef char vextype; /*頂點的數據類型*/
typedef float adjtype; /*權值類型*/
typedef struct
{vextype vexs[n];
adjtype arcs[n][n];
}graph;
P135 建立一個無向網路的演算法。
CREATGRAPH(ga) /*建立無向網路*/
Graph * ga;
{
int i,j,k;
float w;
for(i=0;i<n;i++ )
ga ->vexs[i]=getchar(); /*讀入頂點信息,建立頂點表*/
for(i=0;i<n;i++ )
for(j=0;j<n;j++)
ga ->arcs[i][j]=0; /*鄰接矩陣初始化*/
for(k=0;k<e;k++) /*讀入e條邊*/
(scanf("%d%d%f",&I,&j,&w); /*讀入邊(vi,vj)上的權w */
ga ->arcs[i][j]=w;
ga - >arcs[j][i]=w;
}
} /*CREATGRAPH*/
P136 鄰接表的形式說明及其建立演算法:
typedef struct node
{int adjvex; /*鄰接點域*/
struct node * next; /*鏈域*/
}edgenode; /*邊表結點*/
typedef struct
{vextype vertex; /*頂點信息*/
edgenode link; /*邊表頭指針*/
}vexnode; /*頂點表結點*/
vexnode ga[n];
CREATADJLIST(ga) /*建立無向圖的鄰接表*/
Vexnode ga[ ];
{int i,j,k;
edgenode * s;
for(i=o;i<n;i++= /*讀入頂點信息*/
(ga[i].vertex=getchar();
ga[i].1ink=NULL; /*邊表頭指針初始化*/
}
for(k=0;k<e;k++= /*建立邊表*/
{scanf("%d%d",&i,&j); /*讀入邊(vi , vj)的頂點對序號*/
s=malloc(sizeof(edgenode)); /*生成鄰接點序號為j的表結點*s */
s-> adjvex=j;
s- - >next:=ga[i].Link;
ga[i].1ink=s; /*將*s插入頂點vi的邊表頭部*/
s=malloc(size0f(edgende)); /*生成鄰接點序號為i的邊表結點*s */
s ->adjvex=i;
s ->next=ga[j].1ink;
ga[j].1ink=s; /*將*s插入頂點vj的邊表頭部*/
}
} /* CREATADJLIST */
P139 分別以鄰接矩陣和鄰接表作為圖的存儲結構給出具體演算法,演算法中g、g1和visited為全程量,visited的各分量初始值均為FALSE。
int visited[n] /*定義布爾向量visitd為全程量*/
Graph g; /*圖g為全程量*/
DFS(i) /*從Vi+1出發深度優先搜索圖g,g用鄰接矩陣表示*/
int i;
{ int j;
printf("node:%c\n" , g.vexs[i]); /*訪問出發點vi+1 */
Visited[i]=TRUE; /*標記vi+l已訪問過*/
for (j=0;j<n;j++) /*依次搜索vi+1的鄰接點*/
if((g.arcs[i][j]==1) &&(! visited[j]))
DFS(j); /*若Vi+l的鄰接點vj+l未曾訪問過,則從vj+l出發進行深度優先搜索*/
} /*DFS*/
vexnode gl[n] /*鄰接表全程量*/
DFSL(i) /*從vi+l出發深度優先搜索圖g1,g1用鄰接表表示*/
int i;
{ int j;
edgenode * p;
printf("node:%C\n" ,g1[i].vertex);
vistited[i]=TRUE;
p=g1[i].1ink; /*取vi+1的邊表頭指針*/
while(p !=NULL) /*依次搜索vi+l的鄰接點*/
{
if(! Vistited[p ->adjvex])
DFSL(p - >adjvex); /*從vi+1的未曾訪問過的鄰接點出發進行深度優先搜索*/
p=p - >next; /*找vi+l的下一個鄰接點*/
}
} /* DFSL */
P142 以鄰接矩陣和鄰接表作為圖的存儲結構,分別給出寬度優先搜索演算法。
BFS(k) /*從vk+l出發寬度優先搜索圖g,g用鄰接矩陣表示,visited為訪問標志向量*/
int k;
{ int i,j;
SETNULL(Q); /*置空隊Q */
printf("%c\n",g.vexs[k]); /*訪問出發點vk+l*x/
visited[k]=TRUE; /*標記vk+l已訪問過*/
ENQUEUE(Q,K); /*已訪問過的頂點(序號)入隊列*/
While(!EMPTY(Q)) /*隊非空時執行*/
{i=DEQUEUE(Q); /*隊頭元素序號出隊列*/
for(j=0;j<n;j++)
if((g.arcs[i][j]==1)&&(! visited[j]))
{printf("%c\n" , g.vexs[j]); /*訪問vi+l的未曾訪問的鄰接點vj+l */
visited[j]=TRUE;
ENQUEUE(Q,j); /*訪問過的頂點入隊*/
}
}
} /* BFS */
BFSL(k) /*從vk+l出發寬度優先搜索圖g1,g1用鄰接表表示*/
int k
{ int i;
edgenode * p;
SETNULL(Q);
printf("%c\n" , g1[k].vertex);
visited[k]=TRUE;
ENQUEUE(Q,k);
while(! EMPTY(Q));
{ i=DEQUEUE(Q);
p=g1[i].1ink /*取vi+l的邊表頭指針*/
while(p !=NULL) /*依次搜索vi+l的鄰接點*/
{ if( ! visited[p - >adjvex]) /*訪問vi+l的未訪問的鄰接點*/
{ printf{"%c\n" , g1[p - >adjvex].vertex};
visited[p - >adjvex]=TRUE;
ENQUEUE(Q,p - >adjvex); /*訪問過的頂點入隊*/
}
p=p - >next; /*找vi+l的下一個鄰接點*/
}
}
} /*BFSL*/
P148 在對演算法Prim求精之前,先確定有關的存儲結構如下:
typdef struct
{Int fromvex,endvex; /*邊的起點和終點*/
float length; /*邊的權值*/
} edge;
float dist[n][n]; /*連通網路的帶權鄰接矩陣*/
edgeT[n-1]; /*生成樹*/
P149 抽象語句(1)可求精為:
for(j=1;j<n;j++) /*對n-1個藍點構造候選紫邊集*/
{T[j-1].fromvex=1}; /*紫邊的起點為紅點*/
T[j-1].endvex=j+1; /*紫邊的終點為藍點*/
T[j-1].1ength=dist[0][j]; /*紫邊長度*/
}
P149 抽象語句(3)所求的第k條最短紫邊可求精為:
min=max; /*znax大於任何邊上的權值*/
for (j=k;j<n-1;j++) /*掃描當前候選紫邊集T[k]到T[n-2],找最短紫邊*/
if(T[j].1ength<min)
{min=T[j].1ength;m=j; /*記錄當前最短紫邊的位置*/
}
P149 抽象語句(4)的求精:
e=T[m];T[m]=T[k];T[k]=e, /* T[k]和T[m]交換*/
v=T[kl.Endvex]; /* v是剛被塗紅色的頂點*/
P149 抽象語句(5)可求精為:
for(j=k+1;j<n-1;j++) /*調整候選紫邊集T[k+1]到T[n-2]*/
{d=dist[v-1][T[j].endvex-1]; /*新紫邊的長度*/
if(d<T[j].1ength) /*新紫邊的長度小於原最短紫邊*/
{T[j].1ength=d;
T[j].fromvex=v; /*新紫邊取代原最短紫邊*/
}
}
P150 完整的演算法:
PRIM() /*從第一個頂點出發構造連通網路dist的最小生成樹,結果放在T中*/
{int j , k , m , v , min , max=l0000;
float d;
edge e;
for(j=1;j<n;j++) /*構造初始候選紫邊集*/
{T[j-1].formvex=1; /*頂點1是第一個加入樹中的紅點*/
T[j-1].endvex=j+1;
T[j-1].length=dist[o][j];
}
for(k=0;k<n-1;k++) /*求第k條邊*/
{min=max;
for(j=k;j<n-1;j++) /*在候選紫邊集中找最短紫邊*/
if(T[j].1ength<min)
{min=T[j].1ength;
m=j;
} /*T[m]是當前最短紫邊*/
}
e=T[m];T[m]=T[k];T[k]=e; /*T[k]和T[m]交換後,T[k]是第k條紅色樹邊*/
v=T[k].endvex ; /* v是新紅點*/
for(j=k+1;j<n-1;j++) /*調整候選紫邊集*/
{d=dist[v-1][T[j].endvex-1];
if(d<T[j].1ength);
{T[j].1ength=d;
T[j].fromvex=v;
}
}
} /* PRIM */
P151 Kruskl演算法的粗略描述:
T=(V,φ);
While(T中所含邊數<n-1)
{從E中選取當前最短邊(u,v);
從E中刪去邊(u,v);
if((u,v)並入T之後不產生迴路,將邊(u,v)並入T中;
}
P153 迪傑斯特拉演算法實現。演算法描述如下:
#define max 32767 /*max代表一個很大的數*/
void dijkstra (float cost[][n],int v)
/*求源點v到其餘頂點的最短路徑及其長度*/
{ v1=v-1;
for (i=0;i<n;i++)
{ dist[i]=cost[v1][i]; /*初始化dist*/
if (dist[i]<max)
pre[i]=v;
else pre[i]=0;
}
pre[v1]=0;
for (i=0;i<n;i++)
s[i]=0; /*s數組初始化為空*/
s[v1]=1; /*將源點v歸入s集合*/
for (i=0;i<n;i++)
{ min=max;
for (j=0;j<n;j++)
if (!s[j] && (dist[j]<min))
{ min=dist[j];
k=j;
} /*選擇dist值最小的頂點k+1*/
s[k]=1; /*將頂點k+1歸入s集合中*/
for (j=0;j<n;j++)
if (!s[j]&&(dist[j]>dist[k]+cost[k][j]))
{ dist[j]=dist[k]+cost[k][j]; /*修改 V-S集合中各頂點的dist值*/
pre[j]=k+1; /*k+1頂點是j+1頂點的前驅*/
}
} /*所有頂點均已加入到S集合中*/
for (j=0;j<n;j++) /*列印結果*/
{ printf("%f\n%d",dist[j],j+1;);
p=pre[j];
while (p!=0)
{ printf("%d",p);
p=pre[p-1];
}
}
}
P155 弗洛伊德演算法可以描述為:
A(0)[i][j]=cost[i][j]; //cost為圖的鄰接矩陣
A(k)[i][j]=min{A(k-1) [i][j],A(k-1) [i][k]+A(k-1) [k][j]}
其中 k=1,2,…,n
P155 弗洛伊德演算法實現。演算法描述如下:
int path[n][n]; /*路徑矩陣*/
void floyd (float A[][n],cost[][n])
{ for (i=0;i<n;i++) /*設置A和path的初值*/
for (j=0;j<n;j++)
{ if (cost[i][j]<max)
path[i][j]=j;
else { path[i][j]=0;
A[i][j]=cost[i][j];
}
}
for (k=0;k<n;k++)
/*做n次迭代,每次均試圖將頂點k擴充到當前求得的從i到j的最短路徑上*/
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (A[i][j]>(A[i][k]+A[k]
⑦ c語言BFS、DFS函數代碼
這個沒有固定的形式
根據具體的情況來寫
關鍵是思想
bfs是先擴展節點再增加深度
dfs是先增加深度,到底後返回再擴展節點
一個是使用大量空間 另一個則是遍歷所有路徑,相對的更費時間
⑧ 一個簡單的小程序 C語言 BF演算法
引用沒問題,就是BF函數錯了。
#include<stdio.h>
#include<string.h>
#include<iostream>//.h去掉
usingnamespacestd;//命名空間
intBF(charS[],charT[])
{
inti,j,start;
i=0;
j=0;
start=0;
while(S[i]!='