




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
20xx年黑龍江省數(shù)據(jù)總結(jié)加強4000字
1、#definemaxsize棧空間容量voidInOutS(ints[maxsize])//s是元素為整數(shù)的棧,本算法進行入棧和退棧操作。{inttop=0;//top為棧頂指針,定義top=0時為棧空。for(i=1;i<=n;i++)//n個整數(shù)序列作處理。{scanf(“%d”,&x);//從鍵盤讀入整數(shù)序列。if(x!=-1)//讀入的整數(shù)不等于-1時入棧。if(top==maxsize-1){printf(“棧滿\n”);exit(0);}elses[++top]=x;//x入棧。else//讀入的整數(shù)等于-1時退棧。{if(top==0){printf(“??誠n”);exit(0);}elseprintf(“出棧元素是%d\n”,s[top--]);}}}//算法結(jié)2、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel3、本題應(yīng)使用深度優(yōu)先遍歷,從主調(diào)函數(shù)進入dfs(v)時,開始記數(shù),若退出dfs()前,已訪問完有向圖的全部頂點(設(shè)為n個),則有向圖有根,v為根結(jié)點。將n個頂點從1到n編號,各調(diào)用一次dfs()過程,就可以求出全部的根結(jié)點。題中有向圖的鄰接表存儲結(jié)構(gòu)、記頂點個數(shù)的變量、以及訪問標(biāo)記數(shù)組等均設(shè)計為全局變量。建立有向圖g的鄰接表存儲結(jié)構(gòu)參見上面第2題,這里只給出判斷有向圖是否有根的算法。intnum=0,visited[]=0//num記訪問頂點個數(shù),訪問數(shù)組visited初始化。constn=用戶定義的頂點數(shù);AdjListg;//用鄰接表作存儲結(jié)構(gòu)的有向圖g。voiddfs(v){visited[v]=1;num++;//訪問的頂點數(shù)+1if(num==n){printf(“%d是有向圖的根。\n”,v);num=0;}//ifp=g[v].firstarc;while(p){if(visied[p->adjvex]==0)dfs(p->adjvex);p=p->next;}//whilevisited[v]=0;num--;//恢復(fù)頂點v}//dfsvoidJudgeRoot()//判斷有向圖是否有根,有根則輸出之。{staticinti;for(i=1;i<=n;i++)//從每個頂點出發(fā),調(diào)用dfs()各一次。{num=0;visited[1..n]=0;dfs(i);}}//JudgeRoot算法中打印根時,輸出頂點在鄰接表中的序號(下標(biāo)),若要輸出頂點信息,可使用g[i].vertex。4、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel5、設(shè)T是一棵滿二叉樹,編寫一個將T的先序遍歷序列轉(zhuǎn)換為后序遍歷序列的遞歸算法。6、將頂點放在兩個集合V1和V2。對每個頂點,檢查其和鄰接點是否在同一個集合中,如是,則為非二部圖。為此,用整數(shù)1和2表示兩個集合。再用一隊列結(jié)構(gòu)存放圖中訪問的頂點。intBPGraph(AdjMatrixg)//判斷以鄰接矩陣表示的圖g是否是二部圖。{ints[];//頂點向量,元素值表示其屬于那個集合(值1和2表示兩個集合)intQ[];//Q為隊列,元素為圖的頂點,這里設(shè)頂點信息就是頂點編號。intf=0,r,visited[];//f和r分別是隊列的頭尾指針,visited[]是訪問數(shù)組for(i=1;i<=n;i++){visited[i]=0;s[i]=0;}//初始化,各頂點未確定屬于那個集合Q[1]=1;r=1;s[1]=1;//頂點1放入集合S1while(f<r){v=Q[++f];if(s[v]==1)jh=2;elsejh=1;//準(zhǔn)備v的鄰接點的集合號if(!visited[v]){visited[v]=1;//確保對每一個頂點,都要檢查與其鄰接點不應(yīng)在一個集合中for(j=1,j<=n;j++)if(g[v][j]==1){if(!s[j]){s[j]=jh;Q[++r]=j;}//鄰接點入隊列elseif(s[j]==s[v])return(0);}//非二部圖}//if(!visited[v])}//whilereturn(1);}//是二部圖[算法討論]題目給的是連通無向圖,若非連通,則算法要修改。7、證明由二叉樹的中序序列和后序序列,也可以唯一確定一棵二叉樹。當(dāng)n=1時,只有一個根結(jié)點,由中序序列和后序序列可以確定這棵二叉樹。設(shè)當(dāng)n=m-1時結(jié)論成立,現(xiàn)證明當(dāng)n=m時結(jié)論成立。設(shè)中序序列為S1,S2,?,Sm,后序序列是P1,P2,?,Pm。因后序序列最后一個元素Pm是根,則在中序序列中可找到與Pm相等的結(jié)點(設(shè)二叉樹中各結(jié)點互不相同)Si(1≤i≤m),因中序序列是由中序遍歷而得,所以Si是根結(jié)點,S1,S2,?,Si-1是左子樹的中序序列,而Si+1,Si+2,?,Sm是右子樹的中序序列。若i=1,則S1是根,這時二叉樹的左子樹為空,右子樹的結(jié)點數(shù)是m-1,則{S2,S3,?,Sm}和{P1,P2,?,Pm-1}可以唯一確定右子樹,從而也確定了二叉樹。若i=m,則Sm是根,這時二叉樹的右子樹為空,左子樹的結(jié)點數(shù)是m-1,則{S1,S2,?,Sm-1}和{P1,P2,?,Pm-1}唯一確定左子樹,從而也確定了二叉樹。最后,當(dāng)1<i<m時,Si把中序序列分成{S1,S2,?,Si-1}和{Si+1,Si+2,?,Sm}。由于后序遍歷是“左子樹—右子樹—根結(jié)點”,所以{P1,P2,?,Pi-1}和{Pi,Pi+1,?Pm-1}是二叉樹的左子樹和右子樹的后序遍歷序列。因而由{S1,S2,?,Si-1}和{P1,P2,?,Pi-1}可唯一確定二叉樹的左子樹,由{Si+1,Si+2,?,Sm}和{Pi,Pi+1,?,Pm-1}可唯一確定二叉樹的右子樹。
第二篇:20xx年黑龍江省數(shù)據(jù)總結(jié)深入15100字1、我們可用“破圈法”求解帶權(quán)連通無向圖的一棵最小代價生成樹。所謂“破圈法”就是“任取一圈,去掉圈上權(quán)最大的邊”,反復(fù)執(zhí)行這一步驟,直到?jīng)]有圈為止。請給出用“破圈法”求解給定的帶權(quán)連通無向圖的一棵最小代價生成樹的詳細算法,并用程序?qū)崿F(xiàn)你所給出的算法。注:圈就是回路。2、本題應(yīng)使用深度優(yōu)先遍歷,從主調(diào)函數(shù)進入dfs(v)時,開始記數(shù),若退出dfs()前,已訪問完有向圖的全部頂點(設(shè)為n個),則有向圖有根,v為根結(jié)點。將n個頂點從1到n編號,各調(diào)用一次dfs()過程,就可以求出全部的根結(jié)點。題中有向圖的鄰接表存儲結(jié)構(gòu)、記頂點個數(shù)的變量、以及訪問標(biāo)記數(shù)組等均設(shè)計為全局變量。建立有向圖g的鄰接表存儲結(jié)構(gòu)參見上面第2題,這里只給出判斷有向圖是否有根的算法。intnum=0,visited[]=0//num記訪問頂點個數(shù),訪問數(shù)組visited初始化。constn=用戶定義的頂點數(shù);AdjListg;//用鄰接表作存儲結(jié)構(gòu)的有向圖g。voiddfs(v){visited[v]=1;num++;//訪問的頂點數(shù)+1if(num==n){printf(“%d是有向圖的根。\n”,v);num=0;}//ifp=g[v].firstarc;while(p){if(visied[p->adjvex]==0)dfs(p->adjvex);p=p->next;}//whilevisited[v]=0;num--;//恢復(fù)頂點v}//dfsvoidJudgeRoot()//判斷有向圖是否有根,有根則輸出之。{staticinti;for(i=1;i<=n;i++)//從每個頂點出發(fā),調(diào)用dfs()各一次。{num=0;visited[1..n]=0;dfs(i);}}//JudgeRoot算法中打印根時,輸出頂點在鄰接表中的序號(下標(biāo)),若要輸出頂點信息,可使用g[i].vertex。3、本題應(yīng)使用深度優(yōu)先遍歷,從主調(diào)函數(shù)進入dfs(v)時,開始記數(shù),若退出dfs()前,已訪問完有向圖的全部頂點(設(shè)為n個),則有向圖有根,v為根結(jié)點。將n個頂點從1到n編號,各調(diào)用一次dfs()過程,就可以求出全部的根結(jié)點。題中有向圖的鄰接表存儲結(jié)構(gòu)、記頂點個數(shù)的變量、以及訪問標(biāo)記數(shù)組等均設(shè)計為全局變量。建立有向圖g的鄰接表存儲結(jié)構(gòu)參見上面第2題,這里只給出判斷有向圖是否有根的算法。intnum=0,visited[]=0//num記訪問頂點個數(shù),訪問數(shù)組visited初始化。constn=用戶定義的頂點數(shù);AdjListg;//用鄰接表作存儲結(jié)構(gòu)的有向圖g。voiddfs(v){visited[v]=1;num++;//訪問的頂點數(shù)+1if(num==n){printf(“%d是有向圖的根。\n”,v);num=0;}//ifp=g[v].firstarc;while(p){if(visied[p->adjvex]==0)dfs(p->adjvex);p=p->next;}//whilevisited[v]=0;num--;//恢復(fù)頂點v}//dfsvoidJudgeRoot()//判斷有向圖是否有根,有根則輸出之。{staticinti;for(i=1;i<=n;i++)//從每個頂點出發(fā),調(diào)用dfs()各一次。{num=0;visited[1..n]=0;dfs(i);}}//JudgeRoot算法中打印根時,輸出頂點在鄰接表中的序號(下標(biāo)),若要輸出頂點信息,可使用g[i].vertex。4、本題要求建立有序的循環(huán)鏈表。從頭到尾掃描數(shù)組A,取出A[i](0<=i<n),然后到鏈表中去查找值為A[i]的結(jié)點,若查找失敗,則插入。LinkedListcreat(ElemTypeA[],intn)//由含n個數(shù)據(jù)的數(shù)組A生成循環(huán)鏈表,要求鏈表有序并且無值重復(fù)結(jié)點{LinkedListh;h=(LinkedList)malloc(sizeof(LNode));//申請結(jié)點h->next=h;//形成空循環(huán)鏈表for(i=0;i<n;i++){pre=h;p=h->next;while(p!=h&&p->data<A[i]){pre=p;p=p->next;}//查找A[i]的插入位置if(p==h||p->data!=A[i])//重復(fù)數(shù)據(jù)不再輸入{s=(LinkedList)malloc(sizeof(LNode));s->data=A[i];pre->next=s;s->next=p;//將結(jié)點s鏈入鏈表中}}//forreturn(h);}算法結(jié)束5、給定n個村莊之間的交通圖,若村莊i和j之間有道路,則將頂點i和j用邊連接,邊上的Wij表示這條道路的長度,現(xiàn)在要從這n個村莊中選擇一個村莊建一所醫(yī)院,問這所醫(yī)院應(yīng)建在哪個村莊,才能使離醫(yī)院最遠的村莊到醫(yī)院的路程最短?試設(shè)計一個解答上述問題的算法,并應(yīng)用該算法解答如圖所示的實例。20分voidHospital(AdjMatrixw,intn)//在以鄰接帶權(quán)矩陣表示的n個村莊中,求醫(yī)院建在何處,使離醫(yī)院最遠的村莊到醫(yī)院的路徑最短。{for(k=1;k<=n;k++)//求任意兩頂點間的最短路徑for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(w[i][k]+w[k][j]<w[i][j])w[i][j]=w[i][k]+w[k][j];m=MAXINT;//設(shè)定m為機器內(nèi)最大整數(shù)。for(i=1;i<=n;i++)//求最長路徑中最短的一條。{s=0;for(j=1;j<=n;j++)//求從某村莊i(1<=i<=n)到其它村莊的最長路徑。if(w[i][j]>s)s=w[i][j];if(s<=m){m=s;k=i;}//在最長路徑中,取最短的一條。m記最長路徑,k記出發(fā)頂點的下標(biāo)。Printf(“醫(yī)院應(yīng)建在%d村莊,到醫(yī)院距離為%d\n”,i,m);}//for}//算法結(jié)束對以上實例模擬的過程略。各行中最大數(shù)依次是9,9,6,7,9,9。這幾個最大數(shù)中最小者為6,故醫(yī)院應(yīng)建在第三個村莊中,離醫(yī)院最遠的村莊到醫(yī)院的距離是6。1、對圖1所示的連通網(wǎng)G,請用Prim算法構(gòu)造其最小生成樹(每選取一條邊畫一個圖)。6、二路插入排序是將待排關(guān)鍵字序列r[1..n]中關(guān)鍵字分二路分別按序插入到輔助向量d[1..n]前半部和后半部(注:向量d可視為循環(huán)表),其原則為,先將r[l]賦給d[1],再從r[2]記錄開始分二路插入。編寫實現(xiàn)二路插入排序算法。7、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel8、后序遍歷最后訪問根結(jié)點,即在遞歸算法中,根是壓在棧底的。采用后序非遞歸算法,棧中存放二叉樹結(jié)點的指針,當(dāng)訪問到某結(jié)點時,棧中所有元素均為該結(jié)點的祖先。本題要找p和q的最近共同祖先結(jié)點r,不失一般性,設(shè)p在q的左邊。后序遍歷必然先遍歷到結(jié)點p,棧中元素均為p的祖先。將??饺肓硪惠o助棧中。再繼續(xù)遍歷到結(jié)點q時,將棧中元素從棧頂開始逐個到輔助棧中去匹配,第一個匹配(即相等)的元素就是結(jié)點p和q的最近公共祖先。typedefstruct{BiTreet;inttag;//tag=0表示結(jié)點的左子女已被訪問,tag=1表示結(jié)點的右子女已被訪問}stack;stacks[],s1[];//棧,容量夠大BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉樹上結(jié)點p和q的最近的共同祖先結(jié)點r。{top=0;bt=ROOT;while(bt!=null||top>0){while(bt!=null&&bt!=p&&bt!=q)//結(jié)點入棧{s[++top].t=bt;s[top].tag=0;bt=bt->lchild;}//沿左分枝向下if(bt==p)//不失一般性,假定p在q的左側(cè),遇結(jié)點p時,棧中元素均為p的祖先結(jié)點{for(i=1;i<=top;i++)s1[i]=s[i];top1=top;}//將棧s的元素轉(zhuǎn)入輔助棧s1保存if(bt==q)//找到q結(jié)點。for(i=top;i>0;i--)//;將棧中元素的樹結(jié)點到s1去匹配{pp=s[i].t;for(j=top1;j>0;j--)if(s1[j].t==pp){printf(“p和q的最近共同的祖先已找到”);return(pp);}}while(top!=0&&s[top].tag==1)top--;//退棧if(top!=0){s[top].tag=1;bt=s[top].t->rchild;}//沿右分枝向下遍歷}//結(jié)束while(bt!=null||top>0)return(null);//q、p無公共祖先}//結(jié)束Ancestor9、給出折半查找的遞歸算法,并給出算法時間復(fù)雜度性分析。10、設(shè)T是一棵滿二叉樹,編寫一個將T的先序遍歷序列轉(zhuǎn)換為后序遍歷序列的遞歸算法。11、兩棵空二叉樹或僅有根結(jié)點的二叉樹相似;對非空二叉樹,可判左右子樹是否相似,采用遞歸算法。intSimilar(BiTreep,q)//判斷二叉樹p和q是否相似{if(p==null&&q==null)return(1);elseif(!p&&q||p&&!q)return(0);elsereturn(Similar(p->lchild,q->lchild)&&Similar(p->rchild,q->rchild))}//結(jié)束Similar12、給定n個村莊之間的交通圖,若村莊i和j之間有道路,則將頂點i和j用邊連接,邊上的Wij表示這條道路的長度,現(xiàn)在要從這n個村莊中選擇一個村莊建一所醫(yī)院,問這所醫(yī)院應(yīng)建在哪個村莊,才能使離醫(yī)院最遠的村莊到醫(yī)院的路程最短?試設(shè)計一個解答上述問題的算法,并應(yīng)用該算法解答如圖所示的實例。20分voidHospital(AdjMatrixw,intn)//在以鄰接帶權(quán)矩陣表示的n個村莊中,求醫(yī)院建在何處,使離醫(yī)院最遠的村莊到醫(yī)院的路徑最短。{for(k=1;k<=n;k++)//求任意兩頂點間的最短路徑for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(w[i][k]+w[k][j]<w[i][j])w[i][j]=w[i][k]+w[k][j];m=MAXINT;//設(shè)定m為機器內(nèi)最大整數(shù)。for(i=1;i<=n;i++)//求最長路徑中最短的一條。{s=0;for(j=1;j<=n;j++)//求從某村莊i(1<=i<=n)到其它村莊的最長路徑。if(w[i][j]>s)s=w[i][j];if(s<=m){m=s;k=i;}//在最長路徑中,取最短的一條。m記最長路徑,k記出發(fā)頂點的下標(biāo)。Printf(“醫(yī)院應(yīng)建在%d村莊,到醫(yī)院距離為%d\n”,i,m);}//for}//算法結(jié)束對以上實例模擬的過程略。各行中最大數(shù)依次是9,9,6,7,9,9。這幾個最大數(shù)中最小者為6,故醫(yī)院應(yīng)建在第三個村莊中,離醫(yī)院最遠的村莊到醫(yī)院的距離是6。1、對圖1所示的連通網(wǎng)G,請用Prim算法構(gòu)造其最小生成樹(每選取一條邊畫一個圖)。13、若第n件物品能放入背包,則問題變?yōu)槟芊裨購膎-1件物品中選出若干件放入背包(這時背包可放入物品的重量變?yōu)閟-w[n])。若第n件物品不能放入背包,則考慮從n-1件物品選若干件放入背包(這時背包可放入物品仍為s)。若最終s=0,則有一解;否則,若s<0或雖然s>0但物品數(shù)n<1,則無解。(1)s-w[n],n-1//Knap(s-w[n],n-1)=true(2)s,n-1//Knap←Knap(s,n-1)14、約瑟夫環(huán)問題(Josephus問題)是指編號為1、2、…,n的n(n>0)個人按順時針方向圍坐成一圈,現(xiàn)從第s個人開始按順時針方向報數(shù),數(shù)到第m個人出列,然后從出列的下一個人重新開始報數(shù),數(shù)到第m的人又出列,…,如此重復(fù)直到所有的人全部出列為止?,F(xiàn)要求采用循環(huán)鏈表結(jié)構(gòu)設(shè)計一個算法,模擬此過程。#include<stdlib.h>typedefintdatatype;typedefstructnode{datatypedata;structnode*next;}listnode;typedeflistnode*linklist;voidjose(linklisthead,ints,intm){linklistk1,pre,p;intcount=1;pre=NULL;k1=head;/*k1為報數(shù)的起點*/while(count!=s)/*找初始報數(shù)起點*/{pre=k1;k1=k1->next;count++;}while(k1->next!=k1)/*當(dāng)循環(huán)鏈表中的結(jié)點個數(shù)大于1時*/{p=k1;/*從k1開始報數(shù)*/count=1;while(count!=m)/*連續(xù)數(shù)m個結(jié)點*/{pre=p;p=p->next;count++;}pre->next=p->next;/*輸出該結(jié)點,并刪除該結(jié)點*/printf("%4d",p->data);free(p);k1=pre->next;/*新的報數(shù)起點*/}printf("%4d",k1->data);/*輸出最后一個結(jié)點*/free(k1);}main(){linklisthead,p,r;intn,s,m,i;printf("n=");scanf("%d",&n);printf("s=");scanf("%d",&s);printf("m=",&m);scanf("%d",&m);if(n<1)printf("n<0");else{/*建表*/head=(linklist)malloc(sizeof(listnode));/*建第一個結(jié)點*/head->data=n;r=head;for(i=n-1;i>0;i--)/*建立剩余n-1個結(jié)點*/{p=(linklist)malloc(sizeof(listnode));p->data=i;p->next=head;head=p;}r->next=head;/*生成循環(huán)鏈表*/jose(head,s,m);/*調(diào)用函數(shù)*/}}15、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel16、請編寫一個判別給定二叉樹是否為二叉排序樹的算法,設(shè)二叉樹用llink-rlink法存儲。17、由二叉樹的前序遍歷和中序遍歷序列能確定唯一的一棵二叉樹,下面程序的作用是實現(xiàn)由已知某二叉樹的前序遍歷和中序遍歷序列,生成一棵用二叉鏈表表示的二叉樹并打印出后序遍歷序列,請寫出程序所缺的語句。#defineMAX100typedefstructNode{charinfo;structNode*llink,*rlink;}TNODE;charpred[MAX],inod[MAX];main(intargc,int**argv){TNODE*root;if(argc<3)exit0;strcpy(pred,argv[1]);strcpy(inod,argv[2]);root=restore(pred,inod,strlen(pred));postorder(root);}TNODE*restore(char*ppos,char*ipos,intn){TNODE*ptr;char*rpos;intk;if(n<=0)returnNULL;ptr->info=(1)_______;for((2)_______;rpos<ipos+n;rpos++)if(*rpos==*ppos)break;k=(3)_______;ptr->llink=restore(ppos+1,(4)_______,k);ptr->rlink=restore((5)_______+k,rpos+1,n-1-k);returnptr;}postorder(TNODE*ptr){if(ptr=NULL)return;postorder(ptr->llink);postorder(ptr->rlink);printf(“%c”,ptr->info);}18、設(shè)一棵樹T中邊的集合為{(A,B),(A,C),(A,D),(B,E),(C,F(xiàn)),(C,G)},要求用孩子兄弟表示法(二叉鏈表)表示出該樹的存儲結(jié)構(gòu)并將該樹轉(zhuǎn)化成對應(yīng)的二叉樹。19、后序遍歷最后訪問根結(jié)點,即在遞歸算法中,根是壓在棧底的。采用后序非遞歸算法,棧中存放二叉樹結(jié)點的指針,當(dāng)訪問到某結(jié)點時,棧中所有元素均為該結(jié)點的祖先。本題要找p和q的最近共同祖先結(jié)點r,不失一般性,設(shè)p在q的左邊。后序遍歷必然先遍歷到結(jié)點p,棧中元素均為p的祖先。將??饺肓硪惠o助棧中。再繼續(xù)遍歷到結(jié)點q時,將棧中元素從棧頂開始逐個到輔助棧中去匹配,第一個匹配(即相等)的元素就是結(jié)點p和q的最近公共祖先。typedefstruct{BiTreet;inttag;//tag=0表示結(jié)點的左子女已被訪問,tag=1表示結(jié)點的右子女已被訪問}stack;stacks[],s1[];//棧,容量夠大BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉樹上結(jié)點p和q的最近的共同祖先結(jié)點r。{top=0;bt=ROOT;while(bt!=null||top>0){while(bt!=null&&bt!=p&&bt!=q)//結(jié)點入棧{s[++top].t=bt;s[top].tag=0;bt=bt->lchild;}//沿左分枝向下if(bt==p)//不失一般性,假定p在q的左側(cè),遇結(jié)點p時,棧中元素均為p的祖先結(jié)點{for(i=1;i<=top;i++)s1[i]=s[i];top1=top;}//將棧s的元素轉(zhuǎn)入輔助棧s1保存if(bt==q)//找到q結(jié)點。for(i=top;i>0;i--)//;將棧中元素的樹結(jié)點到s1去匹配{pp=s[i].t;for(j=top1;j>0;j--)if(s1[j].t==pp){printf(“p和q的最近共同的祖先已找到”);return(pp);}}while(top!=0&&s[top].tag==1)top--;//退棧if(top!=0){s[top].tag=1;bt=s[top].t->rchild;}//沿右分枝向下遍歷}//結(jié)束while(bt!=null||top>0)return(null);//q、p無公共祖先}//結(jié)束Ancestor20、設(shè)T是一棵滿二叉樹,編寫一個將T的先序遍歷序列轉(zhuǎn)換為后序遍歷序列的遞歸算法。21、二叉樹的層次遍歷序列的第一個結(jié)點是二叉樹的根。實際上,層次遍歷序列中的每個結(jié)點都是“局部根”。確定根后,到二叉樹的中序序列中,查到該結(jié)點,該結(jié)點將二叉樹分為“左根右”三部分。若左、右子樹均有,則層次序列根結(jié)點的后面應(yīng)是左右子樹的根;若中序序列中只有左子樹或只有右子樹,則在層次序列的根結(jié)點后也只有左子樹的根或右子樹的根。這樣,定義一個全局變量指針R,指向?qū)哟涡蛄写幚碓?。算法中先處理根結(jié)點,將根結(jié)點和左右子女的信息入隊列。然后,在隊列不空的條件下,循環(huán)處理二叉樹的結(jié)點。隊列中元素的數(shù)據(jù)結(jié)構(gòu)定義如下:typedefstruct{intlvl;//層次序列指針,總是指向當(dāng)前“根結(jié)點”在層次序列中的位置intl,h;//中序序列的下上界intf;//層次序列中當(dāng)前“根結(jié)點”的雙親結(jié)點的指針intlr;//1—雙親的左子樹2—雙親的右子樹}qnode;BiTreeCreat(datatypein[],level[],intn)//由二叉樹的層次序列l(wèi)evel[n]和中序序列in[n]生成二叉樹。n是二叉樹的結(jié)點數(shù){if(n<1){printf(“參數(shù)錯誤\n”);exit(0);}qnodes,Q[];//Q是元素為qnode類型的隊列,容量足夠大init(Q);intR=0;//R是層次序列指針,指向當(dāng)前待處理的結(jié)點BiTreep=(BiTree)malloc(sizeof(BiNode));//生成根結(jié)點p->data=level[0];p->lchild=null;p->rchild=null;//填寫該結(jié)點數(shù)據(jù)for(i=0;i<n;i++)//在中序序列中查找根結(jié)點,然后,左右子女信息入隊列if(in[i]==level[0])break;if(i==0)//根結(jié)點無左子樹,遍歷序列的1—n-1是右子樹{p->lchild=null;s.lvl=++R;s.l=i+1;s.h=n-1;s.f=p;s.lr=2;enqueue(Q,s);}elseif(i==n-1)//根結(jié)點無右子樹,遍歷序列的1—n-1是左子樹{p->rchild=null;s.lvl=++R;s.l=1;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);}else//根結(jié)點有左子樹和右子樹{s.lvl=++R;s.l=0;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);//左子樹有關(guān)信息入隊列s.lvl=++R;s.l=i+1;s.h=n-1;s.f=p;s.lr=2;enqueue(Q,s);//右子樹有關(guān)信息入隊列}while(!empty(Q))//當(dāng)隊列不空,進行循環(huán),構(gòu)造二叉樹的左右子樹{s=delqueue(Q);father=s.f;for(i=s.l;i<=s.h;i++)if(in[i]==level[s.lvl])break;p=(bitreptr)malloc(sizeof(binode));//申請結(jié)點空間p->data=level[s.lvl];p->lchild=null;p->rchild=null;//填寫該結(jié)點數(shù)據(jù)if(s.lr==1)father->lchild=p;elsefather->rchild=p;//讓雙親的子女指針指向該結(jié)點if(i==s.l){p->lchild=null;//處理無左子女s.lvl=++R;s.l=i+1;s.f=p;s.lr=2;enqueue(Q,s);}elseif(i==s.h){p->rchild=null;//處理無右子女s.lvl=++R;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);}else{s.lvl=++R;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);//左子樹有關(guān)信息入隊列s.lvl=++R;s.l=i+1;s.f=p;s.lr=2;enqueue(Q,s);//右子樹有關(guān)信息入隊列}}//結(jié)束while(!empty(Q))return(p);}//算法結(jié)束22、若第n件物品能放入背包,則問題變?yōu)槟芊裨購膎-1件物品中選出若干件放入背包(這時背包可放入物品的重量變?yōu)閟-w[n])。若第n件物品不能放入背包,則考慮從n-1件物品選若干件放入背包(這時背包可放入物品仍為s)。若最終s=0,則有一解;否則,若s<0或雖然s>0但物品數(shù)n<1,則無解。(1)s-w[n],n-1//Knap(s-w[n],n-1)=true(2)s,n-1//Knap←Knap(s,n-1)23、二叉樹的層次遍歷序列的第一個結(jié)點是二叉樹的根。實際上,層次遍歷序列中的每個結(jié)點都是“局部根”。確定根后,到二叉樹的中序序列中,查到該結(jié)點,該結(jié)點將二叉樹分為“左根右”三部分。若左、右子樹均有,則層次序列根結(jié)點的后面應(yīng)是左右子樹的根;若中序序列中只有左子樹或只有右子樹,則在層次序列的根結(jié)點后也只有左子樹的根或右子樹的根。這樣,定義一個全局變量指針R,指向?qū)哟涡蛄写幚碓亍K惴ㄖ邢忍幚砀Y(jié)點,將根結(jié)點和左右子女的信息入隊列。然后,在隊列不空的條件下,循環(huán)處理二叉樹的結(jié)點。隊列中元素的數(shù)據(jù)結(jié)構(gòu)定義如下:typedefstruct{intlvl;//層次序列指針,總是指向當(dāng)前“根結(jié)點”在層次序列中的位置intl,h;//中序序列的下上界intf;//層次序列中當(dāng)前“根結(jié)點”的雙親結(jié)點的指針intlr;//1—雙親的左子樹2—雙親的右子樹}qnode;BiTreeCreat(datatypein[],level[],intn)//由二叉樹的層次序列l(wèi)evel[n]和中序序列in[n]生成二叉樹。n是二叉樹的結(jié)點數(shù){if(n<1){printf(“參數(shù)錯誤\n”);exit(0);}qnodes,Q[];//Q是元素為qnode類型的隊列,容量足夠大init(Q);intR=0;//R是層次序列指針,指向當(dāng)前待處理的結(jié)點BiTreep=(BiTree)malloc(sizeof(BiNode));//生成根結(jié)點p->data=level[0];p->lchild=null;p->rchild=null;//填寫該結(jié)點數(shù)據(jù)for(i=0;i<n;i++)//在中序序列中查找根結(jié)點,然后,左右子女信息入隊列if(in[i]==level[0])break;if(i==0)//根結(jié)點無左子樹,遍歷序列的1—n-1是右子樹{p->lchild=null;s.lvl=++R;s.l=i+1;s.h=n-1;s.f=p;s.lr=2;enqueue(Q,s);}elseif(i==n-1)//根結(jié)點無右子樹,遍歷序列的1—n-1是左子樹{p->rchild=null;s.lvl=++R;s.l=1;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);}else//根結(jié)點有左子樹和右子樹{s.lvl=++R;s.l=0;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);//左子樹有關(guān)信息入隊列s.lvl=++R;s.l=i+1;s.h=n-1;s.f=p;s.lr=2;enqueue(Q,s);//右子樹有關(guān)信息入隊列}while(!empty(Q))//當(dāng)隊列不空,進行循環(huán),構(gòu)造二叉樹的左右子樹{s=delqueue(Q);father=s.f;for(i=s.l;i<=s.h;i++)if(in[i]==level[s.lvl])break;p=(bitreptr)malloc(sizeof(binode));//申請結(jié)點空間p->data=level[s.lvl];p->lchild=null;p->rchild=null;//填寫該結(jié)點數(shù)據(jù)if(s.lr==1)father->lchild=p;elsefather->rchild=p;//讓雙親的子女指針指向該結(jié)點if(i==s.l){p->lchild=null;//處理無左子女s.lvl=++R;s.l=i+1;s.f=p;s.lr=2;enqueue(Q,s);}elseif(i==s.h){p->rchild=null;//處理無右子女s.lvl=++R;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);}else{s.lvl=++R;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);//左子樹有關(guān)信息入隊列s.lvl=++R;s.l=i+1;s.f=p;s.lr=2;enqueue(Q,s);//右子樹有關(guān)信息入隊列}}//結(jié)束while(!empty(Q))return(p);}//算法結(jié)束24、假設(shè)以鄰接矩陣作為圖的存儲結(jié)構(gòu),編寫算法判別在給定的有向圖中是否存在一個簡單有向回路,若存在,則以頂點序列的方式輸出該回路(找到一條即可)。(注:圖中不存在頂點到自己的弧)有向圖判斷回路要比無向圖復(fù)雜。利用深度優(yōu)先遍歷,將頂點分成三類:未訪問;已訪問但其鄰接點未訪問完;已訪問且其鄰接點已訪問完。下面用0,1,2表示這三種狀態(tài)。前面已提到,若dfs(v)結(jié)束前出現(xiàn)頂點u到v的回邊,則圖中必有包含頂點v和u的回路。對應(yīng)程序中v的狀態(tài)為1,而u是正訪問的頂點,若我們找出u的下一鄰接點的狀態(tài)為1,就可以輸出回路了。voidPrint(intv,intstart)//輸出從頂點start開始的回路。{for(i=1;i<=n;i++)if(g[v][i]!=0&&visited[i]==1)//若存在邊(v,i),且頂點i的狀態(tài)為1。{printf(“%d”,v);if(i==start)printf(“\n”);elsePrint(i,start);break;}//if}//Printvoiddfs(intv){visited[v]=1;for(j=1;j<=n;j++)if(g[v][j]!=0)//存在邊(v,j)if(visited[j]!=1){if(!visited[j])dfs(j);}//ifelse{cycle=1;Print(j,j);}visited[v]=2;}//dfsvoidfind_cycle()//判斷是否有回路,有則輸出鄰接矩陣。visited數(shù)組為全局變量。{for(i=1;i<=n;i++)visited[i]=0;for(i=1;i<=n;i++)if(!visited[i])dfs(i);}//find_cycle25、設(shè)有兩個集合A和集合B,要求設(shè)計生成集合C=A∩B的算法,其中集合A、B和C用鏈?zhǔn)酱鎯Y(jié)構(gòu)表示。typedefstructnode{intdata;structnode*next;}lklist;voidintersection(lklist*ha,lklist*hb,lklist*&hc){lklist*p,*q,*t;for(p=ha,hc=0;p!=0;p=p->next){for(q=hb;q!=0;q=q->next)if(q->data==p->data)break;if(q!=0){t=(lklist*)malloc(sizeof(lklist));t->data=p->data;t->next=hc;hc=t;}}}+20xx年黑龍江省數(shù)據(jù)總結(jié)加強發(fā)表于:2022.12.6來自:字?jǐn)?shù):4072手機看范文1、#definemaxsize??臻g容量voidInOutS(ints[maxsize])//s是元素為整數(shù)的棧,本算法進行入棧和退棧操作。{inttop=0;//top為棧頂指針,定義top=0時為???。for(i=1;i<=n;i++)//n個整數(shù)序列作處理。{scanf(“%d”,&x);//從鍵盤讀入整數(shù)序列。if(x!=-1)//讀入的整數(shù)不等于-1時入棧。if(top==maxsize-1){printf(“棧滿\n”);exit(0);}elses[++top]=x;//x入棧。else//讀入的整數(shù)等于-1時退棧。{if(top==0){printf(“??誠n”);exit(0);}elseprintf(“出棧元素是%d\n”,s[top--]);}}}//算法結(jié)2、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel3、本題應(yīng)使用深度優(yōu)先遍歷,從主調(diào)函數(shù)進入dfs(v)時,開始記數(shù),若退出dfs()前,已訪問完有向圖的全部頂點(設(shè)為n個),則有向圖有根,v為根結(jié)點。將n個頂點從1到n編號,各調(diào)用一次dfs()過程,就可以求出全部的根結(jié)點。題中有向圖的鄰接表存儲結(jié)構(gòu)、記頂點個數(shù)的變量、以及訪問標(biāo)記數(shù)組等均設(shè)計為全局變量。建立有向圖g的鄰接表存儲結(jié)構(gòu)參見上面第2題,這里只給出判斷有向圖是否有根的算法。intnum=0,visited[]=0//num記訪問頂點個數(shù),訪問數(shù)組visited初始化。constn=用戶定義的頂點數(shù);AdjListg;//用鄰接表作存儲結(jié)構(gòu)的有向圖g。voiddfs(v){visited[v]=1;num++;//訪問的頂點數(shù)+1if(num==n){printf(“%d是有向圖的根。\n”,v);num=0;}//ifp=g[v].firstarc;while(p){if(visied[p->adjvex]==0)dfs(p->adjvex);p=p->next;}//whilevisited[v]=0;num--;//恢復(fù)頂點v}//dfsvoidJudgeRoot()//判斷有向圖是否有根,有根則輸出之。{staticinti;for(i=1;i<=n;i++)//從每個頂點出發(fā),調(diào)用dfs()各一次。{num=0;visited[1..n]=0;dfs(i);}}//JudgeRoot算法中打印根時,輸出頂點在鄰接表中的序號(下標(biāo)),若要輸出頂點信息,可使用g[i].vertex。4、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel5、設(shè)T是一棵滿二叉樹,編寫一個將T的先序遍歷序列轉(zhuǎn)換為后序遍歷序列的遞歸算法。6、將頂點放在兩個集合V1和V2。對每個頂點,檢查其和鄰接點是否在同一個集合中,如是,則為非二部圖。為此,用整數(shù)1和2表示兩個集合。再用一隊列結(jié)構(gòu)存放圖中訪問的頂點。intBPGraph(AdjMatrixg)//判斷以鄰接矩陣表示的圖g是否是二部圖。{ints[];//頂點向量,元素值表示其屬于那個集合(值1和2表示兩個集合)intQ[];//Q為隊列,元素為圖的頂點,這里設(shè)頂點信息就是頂點編號。intf=0,r,visited[];//f和r分別是隊列的頭尾指針,visited[]是訪問數(shù)組for(i=1;i<=n;i++){visited[i]=0;s[i]=0;}//初始化,各頂點未確定屬于那個集合Q[1]=1;r=1;s[1]=1;//頂點1放入集合S1while(f<r){v=Q[++f];if(s[v]==1)jh=2;elsejh=1;//準(zhǔn)備v的鄰接點的集合號if(!visited[v]){visited[v]=1;//確保對每一個頂點,都要檢查與其鄰接點不應(yīng)在一個集合中for(j=1,j<=n;j++)if(g[v][j]==1){if(!s[j]){s[j]=jh;Q[++r]=j;}//鄰接點入隊列elseif(s[j]==s[v])return(0);}//非二部圖}//if(!visited[v])}//whilereturn(1);}//是二部圖[算法討論]題目給的是連通無向圖,若非連通,則算法要修改。7、證明由二叉樹的中序序列和后序序列,也可以唯一確定一棵二叉樹。當(dāng)n=1時,只有一個根結(jié)點,由中序序列和后序序列可以確定這棵二叉樹。設(shè)當(dāng)n=m-1時結(jié)論成立,現(xiàn)證明當(dāng)n=m時結(jié)論成立。設(shè)中序序列為S1,S2,?,Sm,后序序列是P1,P2,?,Pm。因后序序列最后一個元素Pm是根,則在中序序列中可找到與Pm相等的結(jié)點(設(shè)二叉樹中各結(jié)點互不相同)Si(1≤i≤m),因中序序列是由中序遍歷而得,所以Si是根結(jié)點,S1,S2,?,Si-1是左子樹的中序序列,而Si+1,Si+2,?,Sm是右子樹的中序序列。若i=1,則S1是根,這時二叉樹的左子樹為空,右子樹的結(jié)點數(shù)是m-1,則{S2,S3,?,Sm}和{P1,P2,?,Pm-1}可以唯一確定右子樹,從而也確定了二叉樹。若i=m,則Sm是根,這時二叉樹的右子樹為空,左子樹的結(jié)點數(shù)是m-1,則{S1,S2,?,Sm-1}和{P1,P2,?,Pm-1}唯一確定左子樹,從而也確定了二叉樹。最后,當(dāng)1<i<m時,Si把中序序列分成{S1,S2,?,Si-1}和{Si+1,Si+2,?,Sm}。由于后序遍歷是“左子樹—右子樹—根結(jié)點”,所以{P1,P2,?,Pi-1}和{Pi,Pi+1,?Pm-1}是二叉樹的左子樹和右子樹的后序遍歷序列。因而由{S1,S2,?,Si-1}和{P1,P2,?,Pi-1}可唯一確定二叉樹的左子樹,由{Si+1,Si+2,?,Sm}和{Pi,Pi+1,?,Pm-1}可唯一確定二叉樹的右子樹。
第二篇:20xx年黑龍江省數(shù)據(jù)總結(jié)深入15100字1、我們可用“破圈法”求解帶權(quán)連通無向圖的一棵最小代價生成樹。所謂“破圈法”就是“任取一圈,去掉圈上權(quán)最大的邊”,反復(fù)執(zhí)行這一步驟,直到?jīng)]有圈為止。請給出用“破圈法”求解給定的帶權(quán)連通無向圖的一棵最小代價生成樹的詳細算法,并用程序?qū)崿F(xiàn)你所給出的算法。注:圈就是回路。2、本題應(yīng)使用深度優(yōu)先遍歷,從主調(diào)函數(shù)進入dfs(v)時,開始記數(shù),若退出dfs()前,已訪問完有向圖的全部頂點(設(shè)為n個),則有向圖有根,v為根結(jié)點。將n個頂點從1到n編號,各調(diào)用一次dfs()過程,就可以求出全部的根結(jié)點。題中有向圖的鄰接表存儲結(jié)構(gòu)、記頂點個數(shù)的變量、以及訪問標(biāo)記數(shù)組等均設(shè)計為全局變量。建立有向圖g的鄰接表存儲結(jié)構(gòu)參見上面第2題,這里只給出判斷有向圖是否有根的算法。intnum=0,visited[]=0//num記訪問頂點個數(shù),訪問數(shù)組visited初始化。constn=用戶定義的頂點數(shù);AdjListg;//用鄰接表作存儲結(jié)構(gòu)的有向圖g。voiddfs(v){visited[v]=1;num++;//訪問的頂點數(shù)+1if(num==n){printf(“%d是有向圖的根。\n”,v);num=0;}//ifp=g[v].firstarc;while(p){if(visied[p->adjvex]==0)dfs(p->adjvex);p=p->next;}//whilevisited[v]=0;num--;//恢復(fù)頂點v}//dfsvoidJudgeRoot()//判斷有向圖是否有根,有根則輸出之。{staticinti;for(i=1;i<=n;i++)//從每個頂點出發(fā),調(diào)用dfs()各一次。{num=0;visited[1..n]=0;dfs(i);}}//JudgeRoot算法中打印根時,輸出頂點在鄰接表中的序號(下標(biāo)),若要輸出頂點信息,可使用g[i].vertex。3、本題應(yīng)使用深度優(yōu)先遍歷,從主調(diào)函數(shù)進入dfs(v)時,開始記數(shù),若退出dfs()前,已訪問完有向圖的全部頂點(設(shè)為n個),則有向圖有根,v為根結(jié)點。將n個頂點從1到n編號,各調(diào)用一次dfs()過程,就可以求出全部的根結(jié)點。題中有向圖的鄰接表存儲結(jié)構(gòu)、記頂點個數(shù)的變量、以及訪問標(biāo)記數(shù)組等均設(shè)計為全局變量。建立有向圖g的鄰接表存儲結(jié)構(gòu)參見上面第2題,這里只給出判斷有向圖是否有根的算法。intnum=0,visited[]=0//num記訪問頂點個數(shù),訪問數(shù)組visited初始化。constn=用戶定義的頂點數(shù);AdjListg;//用鄰接表作存儲結(jié)構(gòu)的有向圖g。voiddfs(v){visited[v]=1;num++;//訪問的頂點數(shù)+1if(num==n){printf(“%d是有向圖的根。\n”,v);num=0;}//ifp=g[v].firstarc;while(p){if(visied[p->adjvex]==0)dfs(p->adjvex);p=p->next;}//whilevisited[v]=0;num--;//恢復(fù)頂點v}//dfsvoidJudgeRoot()//判斷有向圖是否有根,有根則輸出之。{staticinti;for(i=1;i<=n;i++)//從每個頂點出發(fā),調(diào)用dfs()各一次。{num=0;visited[1..n]=0;dfs(i);}}//JudgeRoot算法中打印根時,輸出頂點在鄰接表中的序號(下標(biāo)),若要輸出頂點信息,可使用g[i].vertex。4、本題要求建立有序的循環(huán)鏈表。從頭到尾掃描數(shù)組A,取出A[i](0<=i<n),然后到鏈表中去查找值為A[i]的結(jié)點,若查找失敗,則插入。LinkedListcreat(ElemTypeA[],intn)//由含n個數(shù)據(jù)的數(shù)組A生成循環(huán)鏈表,要求鏈表有序并且無值重復(fù)結(jié)點{LinkedListh;h=(LinkedList)malloc(sizeof(LNode));//申請結(jié)點h->next=h;//形成空循環(huán)鏈表for(i=0;i<n;i++){pre=h;p=h->next;while(p!=h&&p->data<A[i]){pre=p;p=p->next;}//查找A[i]的插入位置if(p==h||p->data!=A[i])//重復(fù)數(shù)據(jù)不再輸入{s=(LinkedList)malloc(sizeof(LNode));s->data=A[i];pre->next=s;s->next=p;//將結(jié)點s鏈入鏈表中}}//forreturn(h);}算法結(jié)束5、給定n個村莊之間的交通圖,若村莊i和j之間有道路,則將頂點i和j用邊連接,邊上的Wij表示這條道路的長度,現(xiàn)在要從這n個村莊中選擇一個村莊建一所醫(yī)院,問這所醫(yī)院應(yīng)建在哪個村莊,才能使離醫(yī)院最遠的村莊到醫(yī)院的路程最短?試設(shè)計一個解答上述問題的算法,并應(yīng)用該算法解答如圖所示的實例。20分voidHospital(AdjMatrixw,intn)//在以鄰接帶權(quán)矩陣表示的n個村莊中,求醫(yī)院建在何處,使離醫(yī)院最遠的村莊到醫(yī)院的路徑最短。{for(k=1;k<=n;k++)//求任意兩頂點間的最短路徑for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(w[i][k]+w[k][j]<w[i][j])w[i][j]=w[i][k]+w[k][j];m=MAXINT;//設(shè)定m為機器內(nèi)最大整數(shù)。for(i=1;i<=n;i++)//求最長路徑中最短的一條。{s=0;for(j=1;j<=n;j++)//求從某村莊i(1<=i<=n)到其它村莊的最長路徑。if(w[i][j]>s)s=w[i][j];if(s<=m){m=s;k=i;}//在最長路徑中,取最短的一條。m記最長路徑,k記出發(fā)頂點的下標(biāo)。Printf(“醫(yī)院應(yīng)建在%d村莊,到醫(yī)院距離為%d\n”,i,m);}//for}//算法結(jié)束對以上實例模擬的過程略。各行中最大數(shù)依次是9,9,6,7,9,9。這幾個最大數(shù)中最小者為6,故醫(yī)院應(yīng)建在第三個村莊中,離醫(yī)院最遠的村莊到醫(yī)院的距離是6。1、對圖1所示的連通網(wǎng)G,請用Prim算法構(gòu)造其最小生成樹(每選取一條邊畫一個圖)。6、二路插入排序是將待排關(guān)鍵字序列r[1..n]中關(guān)鍵字分二路分別按序插入到輔助向量d[1..n]前半部和后半部(注:向量d可視為循環(huán)表),其原則為,先將r[l]賦給d[1],再從r[2]記錄開始分二路插入。編寫實現(xiàn)二路插入排序算法。7、對二叉樹的某層上的結(jié)點進行運算,采用隊列結(jié)構(gòu)按層次遍歷最適宜。intLeafKlevel(BiTreebt,intk)//求二叉樹bt的第k(k>1)層上葉子結(jié)點個數(shù){if(bt==null||k<1)return(0);BiTreep=bt,Q[];//Q是隊列,元素是二叉樹結(jié)點指針,容量足夠大intfront=0,rear=1,leaf=0;//front和rear是隊頭和隊尾指針,leaf是葉子結(jié)點數(shù)intlast=1,level=1;Q[1]=p;//last是二叉樹同層最右結(jié)點的指針,level是二叉樹的層數(shù)while(front<=rear){p=Q[++front];if(level==k&&!p->lchild&&!p->rchild)leaf++;//葉子結(jié)點if(p->lchild)Q[++rear]=p->lchild;//左子女入隊if(p->rchild)Q[++rear]=p->rchild;//右子女入隊if(front==last){level++;//二叉樹同層最右結(jié)點已處理,層數(shù)增1last=rear;}//last移到指向下層最右一元素if(level>k)return(leaf);//層數(shù)大于k后退出運行}//while}//結(jié)束LeafKLevel8、后序遍歷最后訪問根結(jié)點,即在遞歸算法中,根是壓在棧底的。采用后序非遞歸算法,棧中存放二叉樹結(jié)點的指針,當(dāng)訪問到某結(jié)點時,棧中所有元素均為該結(jié)點的祖先。本題要找p和q的最近共同祖先結(jié)點r,不失一般性,設(shè)p在q的左邊。后序遍歷必然先遍歷到結(jié)點p,棧中元素均為p的祖先。將??饺肓硪惠o助棧中。再繼續(xù)遍歷到結(jié)點q時,將棧中元素從棧頂開始逐個到輔助棧中去匹配,第一個匹配(即相等)的元素就是結(jié)點p和q的最近公共祖先。typedefstruct{BiTreet;inttag;//tag=0表示結(jié)點的左子女已被訪問,tag=1表示結(jié)點的右子女已被訪問}stack;stacks[],s1[];//棧,容量夠大BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉樹上結(jié)點p和q的最近的共同祖先結(jié)點r。{top=0;bt=ROOT;while(bt!=null||top>0){while(bt!=null&&bt!=p&&bt!=q)//結(jié)點入棧{s[++top].t=bt;s[top].tag=0;bt=bt->lchild;}//沿左分枝向下if(bt==p)//不失一般性,假定p在q的左側(cè),遇結(jié)點p時,棧中元素均為p的祖先結(jié)點{for(i=1;i<=top;i++)s1[i]=s[i];top1=top;}//將棧s的元素轉(zhuǎn)入輔助棧s1保存if(bt==q)//找到q結(jié)點。for(i=top;i>0;i--)//;將棧中元素的樹結(jié)點到s1去匹配{pp=s[i].t;for(j=top1;j>0;j--)if(s1[j].t==pp){printf(“p和q的最近共同的祖先已找到”);return(pp);}}while(top!=0&&s[top].tag==1)top--;//退棧if(top!=0){s[top].tag=1;bt=s[top].t->rchild;}//沿右分枝向下遍歷}//結(jié)束while(bt!=null||top>0)return(null);//q、p無公共祖先}//結(jié)束Ancestor9、給出折半查找的遞歸算法,并給出算法時間復(fù)雜度性分析。10、設(shè)T是一棵滿二叉樹,編寫一個將T的先序遍歷序列轉(zhuǎn)換為后序遍歷序列的遞歸算法。11、兩棵空二叉樹或僅有根結(jié)點的二叉樹相似;對非空二叉樹,可判左右子樹是否相似,采用遞歸算法。intSimilar(BiTreep,q)//判斷二叉樹p和q是否相似{if(p==null&&q==null)return(1);elseif(!p&&q||p&&!q)return(0);elsereturn(Similar(p->lchild,q->lchild)&&Similar(p->rchild,q->rchild))}//結(jié)束Similar12、給定n個村莊之間的交通圖,若村莊i和j之間有道路,則將頂點i和j用邊連接,邊上的Wij表示這條道路的長度,現(xiàn)在要從這n個村莊中選擇一個村莊建一所醫(yī)院,問這所醫(yī)院應(yīng)建在哪個村莊,才能使離醫(yī)院最遠的村莊到醫(yī)院的路程最短?試設(shè)計一個解答上述問題的算法,并應(yīng)用該算法解答如圖所示的實例。20分voidHospital(AdjMatrixw,intn)//在以鄰接帶權(quán)矩陣表示的n個村莊中,求醫(yī)院建在何處,使離醫(yī)院最遠的村莊到醫(yī)院的路徑最短。{for(k=1;k<=n;k++)//求任意兩頂點間的最短路徑for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(w[i][k]+w[k][j]<w[i][j])w[i][j]=w[i][k]+w[k][j];m=MAXINT;//設(shè)定m為機器內(nèi)最大整數(shù)。for(i=1;i<=n;i++)//求最長路徑中最短的一條。{s=0;for(j=1;j<=n;j++)//求從某村莊i(1<=i<=n)到其它村莊的最長路徑。if(w[i][j]>s)s=w[i][j];if(s<=m){m=s;k=i;}//在最長路徑中,取最短的一條。m記最長路徑,k記出發(fā)頂點的下標(biāo)。Printf(“醫(yī)院應(yīng)建在%d村莊,到醫(yī)院距離為%d\n”,i,m);}//for}//算法結(jié)束對以上實例模擬的過程略。各行中最大數(shù)依次是9,9,6,7,9,9。這幾個最大數(shù)中最小者為6,故醫(yī)院應(yīng)建在第三個村莊中,離醫(yī)院最遠的村莊到醫(yī)院的距離是6。1、對圖1所示的連通網(wǎng)G,請用Prim算法構(gòu)造其最小生成樹(每選取一條邊畫一個圖)。13、若第n件物品能放入背包,則問題變?yōu)槟芊裨購膎-1件物品中選出若干件放入背包(這時背包可放入物品的重量變?yōu)閟-w[n])。若第n件物品不能放入背包,則考慮從n-1件物品選若干件放入背包(這時背包可放入物品仍為s)。若最終s=0,則有一解;否則,若s<0或雖然s>0但物品數(shù)n<1,則無解。(1)s-w[n],n-1//Knap(s-w[n],n-1)=true(2)s,n-1//Knap←Knap(s,n-1)14、約瑟夫環(huán)問題(Josephus問題)是指編號為1、2、…,n的n(n>0)個人按順時針方向圍坐成一圈,現(xiàn)從第s個人開始按順時針方向報數(shù),數(shù)到第m個人出列,然后從出列的下一個人重新開始報數(shù),數(shù)到第m的人又出列,…,如此重復(fù)直到所有的人全部出列為止?,F(xiàn)要求采用循環(huán)鏈表結(jié)構(gòu)設(shè)計一個算法,模擬此過程。#include<stdlib.h>typedefintdatatype;typedefstructnode{datatypedata;st
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廉政風(fēng)險防范管理工作實施方案(醫(yī)院版)
- 明廚亮灶視頻聯(lián)網(wǎng)監(jiān)管系統(tǒng)解決方案
- 老年友善管理工作制度(14篇)
- 海洋特色農(nóng)產(chǎn)品開發(fā)
- 2025年石首市市直初中小學(xué)選調(diào)教師考試筆試試題(含答案)
- 2025年山東奇瑞汽車多崗招聘考試筆試試題(含答案)
- 老年護理課件視頻下載
- 老年護理課件-衣著護理
- 老年醫(yī)學(xué)專業(yè)技能課件
- 老年人睡眠健康教育課件
- 高墩(40m高)安全專項施工方案(專家)
- 苯系物的危害及怎樣預(yù)防
- 第二十一章-醫(yī)療與護理文件記錄課件
- 配電室運行維護投標(biāo)方案(技術(shù)標(biāo))
- (骨科)維生素D水平評估在骨科的應(yīng)用及研究新進展課件
- 煙草證遷移申請書范本
- 中南大學(xué)工程測量實習(xí)報告
- 40篇 短文搞定3500詞匯
- 行風(fēng)建設(shè)培訓(xùn)課件
- 思政課說課稿課件
- 施耐德ATS48軟啟動器使用手冊
評論
0/150
提交評論