第一篇:C語言課程實踐-實踐1實驗報告
實驗報告
1.程序源代碼
程序1 編程先由計算機(jī)“想”一個1~100之間的數(shù)請人猜,如果人猜對了,則計算機(jī)給出提示“Right!”,否則提示“Wrong!”,并告訴人所猜的數(shù)是大還是小,然后結(jié)束游戲。要求每次運行程序時機(jī)器所“想”的數(shù)不能都一樣。#include
int input_number;
int random_number;srand((unsigned)time(NULL));random_number = rand()%100+1;printf(“輸入您想猜的0~100之間的數(shù):”);scanf(“%d”,&input_number);if(input_number >= 0 && input_number <= 100){
if(input_number == random_number)
{
printf(“nright!”);
}
else if(input_number > random_number)
{
printf(“n您猜的數(shù)過大n”);
}
else
{
printf(“n您猜的數(shù)過小n”);
} }
else
{
printf(“n您猜的數(shù)應(yīng)在0~100之間”);} } 程序2 編程先由計算機(jī)“想”一個1~100之間的數(shù)請人猜,如果人猜對了,則結(jié)束游戲,并在屏幕上輸出人猜了多少次才猜對此數(shù),以此來反映猜數(shù)者“猜”的水平;否則計算機(jī)給出提示,告訴人所猜的數(shù)是太大還是太小,直到人猜對為止。#include
int input_number;
int random_number;int n;srand((unsigned)time(NULL));random_number = rand()%100+1;for(n=1;;n++){
printf(“輸入您想猜的0~100之間的數(shù):”);scanf(“%d”,&input_number);if(input_number >= 0 && input_number <= 100)
if(input_number == random_number)
{
printf(“nright!n”);
if(n==1)
{
printf(“n您猜了%d次,太牛逼了.n”,n);break;
}
else if(n>1&&n<6)
{
printf(“n您一共猜了%d次,水平還行.n”,n);break;
}
else
{
printf(“n您一共猜了%d次,才猜對,很勉強(qiáng)啊.n”,n);break;
}
}
else if(input_number > random_number)
printf(“n您猜的數(shù)過大n”);
else
printf(“n您猜的數(shù)過小n”);
else
printf(“n您猜的數(shù)應(yīng)在0~100之間”);} } 程序3 編程先由計算機(jī)“想”一個1~100之間的數(shù)請人猜,如果人猜對了,則結(jié)束游戲,并在屏幕上輸出人猜了多少次才猜對此數(shù),以此來反映猜數(shù)者“猜”的水平;否則計算機(jī)給出提示,告訴人所猜的數(shù)是太大還是太小,最多可以猜10次,如果猜了10次仍未猜中的話,結(jié)束游戲。
#include
int input_number;
int random_number;int n;srand((unsigned)time(NULL));random_number = rand()%100+1;for(n=1;n<=10;n++){
printf(“輸入您想猜的0~100之間的數(shù):”);scanf(“%d”,&input_number);if(input_number >= 0 && input_number <= 100)
if(input_number == random_number)
{
printf(“nright!n”);
if(n==1)
{
printf(“n您猜了%d次,太牛逼了.n”,n);break;
}
else if(n>1&&n<6)
{
printf(“n您一共猜了%d次,水平還行.n”,n);break;
}
else
{
printf(“n您一共猜了%d次,才猜對,很勉強(qiáng)啊.n”,n);break;
}
}
else if(input_number > random_number)
printf(“n您猜的數(shù)過大,您還有%d次機(jī)會n”,10-n);
else
printf(“n您猜的數(shù)過小,您還有%d次機(jī)會n”,10-n);
else
printf(“n您猜的數(shù)應(yīng)在0~100之間”);} if(n==11)
printf(“n你輸了!n”);}
程序4 編程先由計算機(jī)“想”一個1~100之間的數(shù)請人猜,如果人猜對了,在屏幕上輸出人猜了多少次才猜對此數(shù),以此來反映猜數(shù)者“猜”的水平,則結(jié)束游戲;否則計算機(jī)給出提示,告訴人所猜的數(shù)是太大還是太小,最多可以猜10次,如果猜了10次仍未猜中的話,則停止本次猜數(shù),然后繼續(xù)猜下一個數(shù)。每次運行程序可以反復(fù)猜多個數(shù),直到操作者想停止時才結(jié)束。#include
int input_number;
int random_number;int n,i=1;
game: srand((unsigned)time(NULL));random_number = rand()%100+1;for(n=1;n<=10;n++){
printf(“第%d輪游戲,輸入您想猜的0~100之間的數(shù):”,i);scanf(“%d”,&input_number);if(input_number >= 0 && input_number <= 100)
if(input_number == random_number)
{
printf(“nright!n”);
if(n==1)
{
printf(“n您猜了%d次,太牛逼了.n”,n);break;
}
else if(n>1&&n<6)
{
printf(“n您一共猜了%d次,水平還行.n”,n);break;
}
else
{
printf(“n您一共猜了%d次,才猜對,很勉強(qiáng)啊.n”,n);break;
}
}
else if(input_number > random_number)
printf(“n您猜的數(shù)過大,您還有%d次機(jī)會n”,10-n);
else
printf(“n您猜的數(shù)過小,您還有%d次機(jī)會n”,10-n);
else
printf(“n您猜的數(shù)應(yīng)在0~100之間”);}
} if(n==11){ printf(“n你輸了!n”);i=i+1;goto game;} 2.遇到的問題及解決方法
問題1:隨機(jī)數(shù)如何調(diào)用?
解決方法:運用srand((unsigned)time(NULL))函數(shù)。
問題2:”直到人猜對為止”功能如何實現(xiàn)? 解決辦法:運用一個“無窮循環(huán)”,另游戲能夠不斷進(jìn)行,并運用break語句停止于猜對情況。
問題3: “以此來反映猜數(shù)者“猜”的水平”功能的實現(xiàn)?
解決辦法:在猜對情況下的if語句中嵌套if語句實現(xiàn)“猜數(shù)次數(shù)”的判斷,分支輸出“猜”的水平。
問題4:“每次運行程序可以反復(fù)猜多個數(shù)”功能的實現(xiàn)?
解決辦法:此功能比較困難,但反復(fù)閱讀程序后,發(fā)現(xiàn)代碼并不復(fù)雜,運用goto語句和if語句的運用進(jìn)行循環(huán),即可實現(xiàn)此功能,且不會因為運用goto語句造成程序模塊的混亂。
3.總結(jié)(心得體會)
這是“C語言課程實踐”的第一次實踐,由于平時并沒接觸過Microsoft Visual C++ 6.0這個編譯軟件,因此剛開始還存在操作方面的苦難。經(jīng)過一兩節(jié)課的實踐,能夠熟悉界面和學(xué)會新建工程。
此次實踐題目是“猜數(shù)游戲”,題目分成4個部分,其實內(nèi)容相同,只是功能逐漸增加。鑒于這種題目,編寫程序中需要思考預(yù)留部分,比如運用if語句嵌套時,要注意把“猜對”、“猜錯”和“誤猜”分支出來,使程序容易閱讀也容易進(jìn)行修改。
在編寫程序過程中,遇到幾個核心問題,通過學(xué)習(xí)后把困難一個個突破,并成功實現(xiàn)題目所要求的功能。
最后,我對編程有進(jìn)一步認(rèn)識,而且在編程調(diào)試過程中,能夠從中發(fā)現(xiàn)問題并解決問題,這是程序能夠走向成功的必經(jīng)之路,也是帶來成功喜悅必不可少的過程。
第二篇:《計算機(jī)實踐》 實驗報告
《計算機(jī)實踐》 實驗報告 I
—數(shù)據(jù)結(jié)構(gòu)
班號: 0316102 學(xué)號: 031650106
姓名: 郭硯璞 Email: 2755858446@qq.com
簽名:
南京航空航天大學(xué)
2018年10月21日
目錄
目錄…………………………………………………………2
實驗一:約瑟夫斯問題求解………………………………3
實驗二:停車場管理問題…………………………………12
實驗三:管道鋪設(shè)施工的最佳方案問題…………………25
實驗四:內(nèi)部排序算法的實現(xiàn)與比較……………………35
參考資料……………………………………………………44
源程序清單…………………………………………………44
實驗一、約瑟夫斯問題求解
一、問題描述
1)問題描述
約瑟夫斯(Josephus)問題的一種描述是:編號為 1,2,…,n 的 n 個人按順時針方向
圍坐一圈,每人持有一個密碼(正整數(shù))。一開始任選一個正整數(shù)作為報數(shù)上限值 m,從
第一個人開始按順時針方向自 1 開始報數(shù),報到 m 時停止報數(shù)。報 m 的人出列,將他的密碼作為新的 m 值,從他在順時針方向下一個人開始重新從 1 報數(shù),如此下去,直至所有的人全部出列為止。試設(shè)計一個程序,按出列順序印出各人編號。
2)實驗?zāi)康呐c基本要求
利用單向循環(huán)鏈表存儲結(jié)構(gòu)模擬此過程,按照出列的順序印出各人的編號。
3)測試數(shù)據(jù)
n=7,7 個人的密碼依次為:3,1,7,2,4,8,4。m 初值為 6(正確的出列順序應(yīng)為
6,1,4,7,2,3,5)。
4)提示
程序運行后,首先要求用戶指定初始報數(shù)上限 m,然后讀取個人的密碼??稍O(shè) n≤30。注意鏈表中空表和非空表的界限。
5)輸入輸出
輸入數(shù)據(jù):建立輸入處理,輸入 n 輸入以及每個人的密碼;m 的初值。
輸出形式:建立一個輸出函數(shù),輸出正確的序列。
6)選作內(nèi)容
添加采用順序存儲結(jié)構(gòu)實現(xiàn)問題求解的模塊。
以上是本實驗的題目要求,下面我將介紹我的實現(xiàn)算法,程序調(diào)試結(jié)果以及編程過程中遇到的具體問題,并且談?wù)勎业氖斋@和感悟!
二、需求分析
1、本實驗用于求出一組排列數(shù)的約瑟夫斯出列順序。
2、程序運行后顯示提示信息,提示用戶輸入人數(shù)n和初始報數(shù)上限m,程序需判斷m與n的大小,如果m>n,需提示用戶重新輸入n值和m值。
3、m和n輸入有效后,程序提示用戶繼續(xù)輸入n個數(shù)據(jù),作為n個人的密碼。
4、用戶輸入完畢后,程序需自動顯示輸入的數(shù)據(jù),并且按照出列順序?qū)個出列者的編號結(jié)果顯示出來。
三、概要設(shè)計
為了實現(xiàn)上述功能,應(yīng)以循環(huán)鏈表的數(shù)據(jù)結(jié)構(gòu)存儲n個人的編號、密碼信息和順序關(guān)系,因此需要一個循環(huán)鏈表的數(shù)據(jù)類型。
1、循環(huán)鏈表抽象數(shù)據(jù)類型定義:
ADT CircularLinkList{
數(shù)據(jù)對象:一個循環(huán)鏈表,每個結(jié)點數(shù)據(jù)域是一個人的編號和密碼。
數(shù)據(jù)關(guān)系:一個結(jié)點的指針域指向按照編號下一個結(jié)點。
基本操作:
CREATE_SL(SLNODE*);//構(gòu)建順序鏈表
ShowOutput(SLNODE *h, int m);//遞歸程序,按順序依次輸出出列者的編號
}ADT CircularLinkList
2、本程序保護(hù)模塊
主函數(shù)模塊
建立鏈表模塊:將輸入數(shù)據(jù)賦給結(jié)點數(shù)據(jù)域,并構(gòu)建循環(huán)鏈表的數(shù)據(jù)關(guān)系
核心算法模塊:按照算法移動指針、刪除節(jié)點,依次輸出出列者的編號。
調(diào)用關(guān)系:
3、算法流程圖
四、詳細(xì)設(shè)計
1.元素類型、結(jié)點類型和結(jié)點指針類型:
#define ElemType int
#define SLNODE struct sl_node
SLNODE
{
ElemType data[2];
SLNODE *next;
};
2、建立鏈表的偽碼
SLNODE *CREATE_SL(SLNODE *h,int n)//創(chuàng)建一個h為頭指針的鏈表,h指向的結(jié)點數(shù)據(jù)域用不到
{
ElemType data;
int i = 1;
SLNODE *p, *s;
p = h;
while(i<=n)
{
printf(“請輸入第%d個元素:t”,i);
scanf_s(“%d”, &data);
s =(SLNODE *)malloc(sizeof(SLNODE));
s->data[0]=i;
s->data[1] = data;
if(h->next == NULL)
{
h->next = s;
}
else
{
p->next = s;
}
p = s;
i++;
}
p->next = h;
return h;
}
3、主函數(shù)偽碼
int main()
{
int m,n,mistake=1;
SLNODE *Head;
PrintInformation1();//輸出程序信息和個人信息
while(mistake)
{
printf(“輸入人數(shù)n:n”);
scanf_s(“%d”, &n);
printf(“請指定初始報數(shù)上限m(m應(yīng)必須小于等于n):n”);
scanf_s(“%d”, &m);
if(m>n)
{
printf(“輸入數(shù)據(jù)有誤,請重新輸入n”);
}
else mistake=0;
}
Head =(SLNODE *)malloc(sizeof(SLNODE));
Head->next = NULL;
Head = CREATE_SL(Head,n);
ShowInput(Head,n);
printf(“正確的出列順序為:rn”);
ShowOutput(Head,m);
PrintInformation2();//程序結(jié)束信息
system(“pause”);
return 0;
}
五、調(diào)試分析與核心算法解釋
程序的調(diào)試主要是針對循環(huán)鏈表,所以調(diào)試對象明確,按照算法思路來調(diào)試,難度不大。
本題在建立好鏈表以后,開始執(zhí)行核心程序ShowOutput遞歸函數(shù),也就是想辦法按照約瑟夫斯問題的規(guī)則來刪除指針指向的結(jié)點、移動指針等,從而以一定排列輸出n個人的密碼。程序剛開始,先由用戶依次輸入人數(shù)n和初始報數(shù)上限m,并判斷是否m<=n,如果m>n,則顯示重新輸入(程序并不會結(jié)束)。
然后程序建立頭指針Head并且執(zhí)行CREATE_SL函數(shù),創(chuàng)建鏈表。
執(zhí)行ShowInput函數(shù),將n個人的密碼依次輸出。
下面開始執(zhí)行本程序的關(guān)鍵函數(shù),也是整個算法的核心函數(shù)ShowOutput,這也是整個算法的體現(xiàn):
函數(shù)整體是個遞歸函數(shù),運用遞歸的思想,效率很高,占用內(nèi)存小,不需要設(shè)置標(biāo)志位來判斷是否某個結(jié)點被訪問,而是訪問到一個應(yīng)該出列的結(jié)點“出列”,然后以此結(jié)點為下一次遞歸的頭結(jié)點,然后刪除本次遞歸程序充當(dāng)頭結(jié)點的那個結(jié)點。
圖解:
h,p,s均為指向節(jié)點的指針,第一次執(zhí)行此函數(shù)時,h指向頭結(jié)點。
p指針尋找到要“出列”的節(jié)點,h指向要出列的結(jié)點作為下一次遞歸的新的頭結(jié)點。
利用p指針和s指針重新改造循環(huán)鏈表,然后s指針用于記錄本次遞歸的頭結(jié)點位置,即將用于刪除、釋放空間。
下面執(zhí)行free(s),刪除所指內(nèi)存空間,開始下一次遞歸調(diào)用。
后面執(zhí)行遞歸函數(shù)時,h剛開始指向的是上一次輸出的結(jié)點(還沒刪除),程序一開始先讓s指向h,等這一趟程序快結(jié)束找到下一個要出列的結(jié)點時,h指向該結(jié)點作為下一次遞歸函數(shù)的頭結(jié)點,并且讓p找到s指向的充當(dāng)本次頭結(jié)點的結(jié)點,把它刪除,再執(zhí)行此遞歸程序。
終止條件是p->next=h,說明沒有需要輸出的節(jié)點了,于是便實現(xiàn)了遞歸。如圖所示:
截圖如圖:
六、使用說明
按照程序界面指示輸入即可,逐個整數(shù)數(shù)字輸入,每輸入一個數(shù)字按一個回車。
七、調(diào)試結(jié)果
按照測試要求進(jìn)行了測試,結(jié)果如下:
八、遇到的問題及解決方法(程序調(diào)試日志)
2018/9/不詳
問題:先建立了一個鏈表實現(xiàn)插入算法的小功能,再進(jìn)行約瑟夫問題求解,結(jié)果程序不停的輸出不完整的數(shù)據(jù),陷入死循環(huán)。
解決:p指針?biāo)缚臻g邏輯上不該釋放但被不正確釋放,刪去free(p)代碼,一切正常。
2018/9/不詳
問題:遞歸程序死循環(huán)。
解決:單步執(zhí)行發(fā)現(xiàn)遞歸的終止條件不正確,修改為p->next=h,程序功能實現(xiàn)!
2018/10/20
最后一天,完善程序,將程序中的注釋寫清楚,百度找到了顯示系統(tǒng)時間的方法,按格式輸出,截屏、書寫報告。
九、實驗的收獲與感想
個人感想:循環(huán)鏈表雖然不是很容易理解,但是處理約瑟夫斯這樣的刪除元素的操作真的十分便利,比起數(shù)組要方便的多。但是代價是編程要仔細(xì),不要釋放錯內(nèi)存空間。
個人方法優(yōu)點:
1、建立鏈表時,將頭結(jié)點和頭指針同時運用,使頭指針一開始指向頭結(jié)點,這樣操作方便,同時個人的算法要利用s刪除上一次h指向的頭結(jié)點,所以一開始讓頭指針指向一個頭結(jié)點對于個人的算法是有一定好處的。
2、本人采用遞歸的算法,每次找到要出列的點后,先不馬上刪除結(jié)點,而是將h指針指向此結(jié)點作為下一次遞歸的h結(jié)點,等下一次遞歸找到新的出列結(jié)點并用h指向來作為頭結(jié)點后,再將廢棄結(jié)點刪除,這樣“改變頭結(jié)點”,操作簡便,很適合遞歸的條件。
個人方法缺點:本人認(rèn)為此程序缺點是陌生人剛看到此程序不能馬上理解,因為遞歸程序本身不易理解。所以為了更好給別人使用,本人已將程序注釋的很清楚了。
建議:本實驗很好,建議像第四題那樣,增加一項計算程序空間復(fù)雜度和時間復(fù)雜度(移動次數(shù))的要求,組織同學(xué)進(jìn)行討論,展示最優(yōu)的算法。
十、源程序
見源程序清單。
實驗二、停車場管理問題
一、問題描述
1)問題描述
設(shè)停車場是一個可停放 n 輛汽車的狹長通道,且只有一個大門可供汽車進(jìn)出。汽車在停車場內(nèi)按車輛到達(dá)時間的先后順序,依次由北向南排列(大門在最南端,最先到達(dá)的第一輛車停放在車場的最北端)。若停車場內(nèi)已經(jīng)停滿 n 輛車,那么后來的車只能在門外的便道上等候。一旦有車開走,則排在便道上的第一輛車即可開入。當(dāng)停車場內(nèi)某輛車要離
開時,在它之后進(jìn)入的車輛必須先退出車場為它讓路,待該輛車開出大門外,其他車輛再
按原次序進(jìn)入車場。每輛停放在車場的車在它離開停車場時必須按它停留的時間長短繳納
費用。試為停車場編制按上述要求進(jìn)行管理的模擬程序。
2)基本要求
以棧模擬停車場,以隊列模擬車場外的便道,按照從終端讀入數(shù)據(jù)的序列進(jìn)行模擬管
理。每一組輸入數(shù)據(jù)包括三個數(shù)據(jù)項:汽車的“到達(dá)”(‘A’表示)或“離去”(‘D’表示)信息、汽車標(biāo)識(牌照號)以及到達(dá)或離去的時刻。對每一組輸入數(shù)據(jù)進(jìn)行操作后的輸出信息為:若是車輛到達(dá),則輸出汽車在停車場內(nèi)或者便道上的停車位置;若是車輛離去,則輸出汽車在停車場停留的時間和應(yīng)繳納的費用(便道上停留的時間不收費)。棧以順序
結(jié)構(gòu)實現(xiàn),隊列以鏈表結(jié)構(gòu)實現(xiàn)。
3)測試數(shù)據(jù)
設(shè) n=2,輸入數(shù)據(jù)為:(‘A’,1,5),(‘A’,2,10),(‘D’,1,15),(‘A’,3,20),(‘A’,4,25),(‘A’,5,30),(‘D’,2,35),(‘D’,4,40),(‘E’,0,0)。每一組輸入數(shù)據(jù)包括三個數(shù)據(jù)項:汽車 “到達(dá)”或“離去”信息、汽車牌照號碼及到達(dá)或離去的時刻,其中,‘A’表示到達(dá);‘D’表示離去,‘E’表示輸入結(jié)束。其中:(‘A’,1,5)表示 1 號牌照車在 5 這個時刻到達(dá),而(‘D’,1,15)表示 1 號牌照車在 15 這個時刻離去。
4)提示
需另設(shè)一個棧,臨時停放為給要離去的汽車讓路而從停車場退出來的汽車。輸入數(shù)據(jù)
按到達(dá)或離去的時刻有序。棧中每個元素表示一輛汽車,包含兩個數(shù)據(jù)項:汽車的牌照號 碼和進(jìn)入停車場的時刻。
5)輸入輸出:
輸入數(shù)據(jù):
程序接受 5 個命令,分別是:到達(dá)(‘A’,車牌號,時間);離去(‘D’,車牌號,時 間);停車場(‘P’, 0, 0)顯示停車場的車數(shù);候車場(‘W’, 0, 0)顯示候車場的車數(shù);退出(‘E’, 0, 0)退出程序。
輸出數(shù)據(jù):
對于車輛到達(dá),要輸出汽車在停車場內(nèi)或者便道上的停車位置;對于車輛 離去,則輸出汽車在停車場停留的時間和應(yīng)繳納的費用(便道上不收費)。
二、需求分析
1、本程序用來模擬停車場進(jìn)場、進(jìn)便道、場外等候、出場、收費等操作。
2、程序運行后顯示提示信息,提示用戶輸入停車每小時需繳納的費用,用戶輸入后,提示信息提示用戶輸入命令:駛?cè)胪\噲鯝,離開停車場D,查看停車場內(nèi)車數(shù)P 0 0,查看候車廠內(nèi)車數(shù)W 0 0,程序結(jié)束E 0 0。
3、程序需判斷用戶輸入的進(jìn)場出場時間的有效性,后來輸入的時間要大于以前輸入的時間。
4、用戶輸入有效命令后,程序顯示汽車進(jìn)出場信息,若是車輛到達(dá),則輸出汽車在停車場內(nèi)或者便道上的停車位置;若是車輛離去,則輸出汽車在停車場停留的時間和應(yīng)繳納的費用。
三、概要設(shè)計
為了實現(xiàn)上述功能,需要用棧模擬停車場,用一個備用的棧存儲暫時出場的外部汽車,用隊列模擬便道。
1、停車場“?!背橄髷?shù)據(jù)類型定義:
ADT stack{
數(shù)據(jù)對象:車牌號、進(jìn)場時間、汽車數(shù)量
數(shù)據(jù)關(guān)系:先入后出
基本操作:
*Init_Parking();//置空棧
IsEmpty_Parking(Parking *s);//判空棧
Push_Parking(Parking *s,ElemType license,ElemType timeIn);//入棧
Pop_Parking(Parking *s,ElemType *license,ElemType *timeIn);//出棧
}ADT stack
2、備用存儲“?!背橄髷?shù)據(jù)類型定義:
ADT stack1
{
數(shù)據(jù)對象:車牌號、進(jìn)場時間、汽車數(shù)量
數(shù)據(jù)關(guān)系:先入后出
基本操作:
*Init_Backup();//置空棧
IsEmpty_Backup(Backup *s);//判空棧
Push_Backup(Backup *s, ElemType license, ElemType timeIn);//入棧
Pop_Backup(Backup *s, ElemType *license,ElemType* timeIn);//出棧
}
3、鏈?zhǔn)疥犃谐橄髷?shù)據(jù)類型定義:
ADT linkqueue
{
數(shù)據(jù)對象:車牌號、汽車數(shù)量
數(shù)據(jù)關(guān)系:先入先出
基本操作:
*Init_LQueue();//創(chuàng)建一個帶頭結(jié)點的空隊
In_LQueue(LinkQueue *q, ElemType license);//入隊
IsEmpty_LQueue(LinkQueue *q);//判隊空
Out_LQueue(LinkQueue *q, ElemType *license);//出隊
}
4、本程序保護(hù)模塊
主函數(shù)模塊
進(jìn)場模塊:對于進(jìn)場的命令進(jìn)行完善地操作處理并進(jìn)行狀態(tài)顯示的模塊
出場模塊:對于出場的命令進(jìn)行完善地操作處理并進(jìn)行狀態(tài)顯示的模塊
置空棧、置空隊、進(jìn)出棧、進(jìn)出隊、判??諚M、判隊空隊滿模塊:對棧、備用棧、隊列進(jìn)行的基本操作
調(diào)用關(guān)系:
5、算法流程圖
四、詳細(xì)設(shè)計
1、元素類型、結(jié)點類型和結(jié)點指針類型:
#define Maxsize 2 //停車場最多能停的車數(shù)
#define ElemType int
int Prize;//每停一個時刻收費多少元
static int num = 0;//num用于記錄入隊的車所在的位置
typedef struct stack //模擬停車場的棧
{
ElemType license[Maxsize];//用于存放車牌號
ElemType timeIn[Maxsize];//用于存放入停車場時間
int top;
}Parking;
typedef struct stack1 //退車時暫時存放
{
ElemType license[Maxsize-1];
ElemType timeIn[Maxsize-1];
int top;
}Backup;
typedef struct road
{
ElemType license;
struct road *next;
}Road;
typedef struct linkqueue//隊列模擬便道
{
Road *front,*rear;
}LinkQueue;
2、部分基本操作的偽碼類型
//給停車場用的配置函數(shù)
Parking *Init_Parking()//置空棧
{
Parking *s;
s=(Parking*)malloc(sizeof(Parking));
s->top=-1;
return s;
}
int IsEmpty_Parking(Parking *s)//判空棧
{
if(s->top==-1)
return 1;
else return 0;
}
int Push_Parking(Parking *s,ElemType license,ElemType timeIn)//入棧
{
if(s->top==Maxsize-1)
return 0;
else
{
s->top++;
s->license[s->top]=license;
s->timeIn[s->top]=timeIn;
return 1;
}
}
int Pop_Parking(Parking *s,ElemType *license,ElemType *timeIn)//出棧
{
if(IsEmpty_Parking(s))
return 0;
else
{
*license = s->license[s->top];
*timeIn = s->timeIn[s->top];
s->top--;
return 1;
}
}
//給備用棧配置的函數(shù)
Backup *Init_Backup()//置空棧
{
Backup *s;
s =(Backup*)malloc(sizeof(Backup));
s->top =-1;
return s;
}
int IsEmpty_Backup(Backup *s)//判空棧
{
if(s->top ==-1)
return 1;
else return 0;
}
int Push_Backup(Backup *s, ElemType license, ElemType timeIn)//入棧
{
if(s->top == Maxsize-1)
return 0;
else
{
s->top++;
s->license[s->top] = license;
s->timeIn[s->top] = timeIn;
return 1;
}
}
int Pop_Backup(Backup *s, ElemType *license,ElemType* timeIn)//出棧
{
if(IsEmpty_Backup(s))
return 0;
else
{
*license = s->license[s->top];
*timeIn = s->timeIn[s->top];
s->top--;
return 1;
}
}
//給候車便道鏈?zhǔn)疥犃信渲玫暮瘮?shù)
LinkQueue *Init_LQueue()//創(chuàng)建一個帶頭結(jié)點的空隊
{
LinkQueue *q;
Road *p;
q =(LinkQueue*)malloc(sizeof(LinkQueue));
p =(Road*)malloc(sizeof(Road));
p->next = NULL;
q->front = q->rear = p;
return q;
}
void In_LQueue(LinkQueue *q, ElemType license)//入隊
{
Road *p;
p =(Road*)malloc(sizeof(Road));
p->license = license;
p->next = NULL;
q->rear->next = p;
q->rear = p;
}
int IsEmpty_LQueue(LinkQueue *q)//判隊空
{
if(q->front == q->rear)
return 1;
else
return 0;
}
int Out_LQueue(LinkQueue *q, ElemType *license)//出隊
{
Road *p;
if(IsEmpty_LQueue(q))
{
printf(”隊空“);
return 0;
}
else
{
p = q->front->next;
q->front->next = p->next;
*license = p->license;
free(p);
if(q->front->next == NULL)
q->rear = q->front;
return 1;
}
}
3、主函數(shù)的偽碼
void main()
{
ElemType license, time,timelast=0;//timeInlast是最近一次有車進(jìn)停車場的時間,提示以后輸入的進(jìn)場時間要大于此數(shù)值
char command;//進(jìn)入A還是離開D
Parking *s;
Backup *s1;
LinkQueue *q;
PrintInformation1();//輸出程序信息和個人信息
s = Init_Parking();//停車場
q = Init_LQueue();//便道隊列
s1 = Init_Backup();//退車時的備用棧
printf(”請輸入停車每小時需交納的費用(元)rn“);
setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少
scanf(”%d“,&Prize);
setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少
while(1)
{
setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少
Loop:printf(”請輸入操作的命令,駛?cè)胪\噲鯝,離開停車場D,查看停車場內(nèi)車數(shù)P 0 0,查看候車廠內(nèi)車數(shù)W 0 0,程序結(jié)束E 0 0:n“);
scanf(”%c%d%d“,&command, &license,&time);
setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少
if(command == A)
{
if(time <= timelast)
{
printf(”輸入的時間必須大于上一次輸入的時間:t“);
printf(”%dt“, timelast);
printf(”請重新輸入n“);
goto Loop;
}
else
{
timelast = time;
GetIn(s,q,license,time);
}
}
if(command == D)
{
if(time <= timelast)
{
printf(”輸入的時間必須大于上一次輸入的時間:t“);
printf(”%dt“, timelast);
printf(”請重新輸入n“);
goto Loop;
}
else
{
timelast = time;
GetOut(s, s1, q, license, time);//車開走的函數(shù)
}
}
if(command == P)
{
if(license == 0 && time == 0)
printf(”停車場內(nèi)停了%d輛車n“,s->top+1);//顯示停車場車數(shù)
}
if(command == W)
{
if(license == 0 && time == 0)
printf(”侯車場內(nèi)停了%d輛車n“,num);//顯示候車場車數(shù)
}
if(command == E)
{
if(license == 0 && time == 0)
{
PrintInformation2();//程序結(jié)束信息
system(”pause“);
return;
}
}
}
}
五、調(diào)試分析與核心算法解釋
程序本身是利用棧、隊列的進(jìn)出完成停車場汽車進(jìn)出場的模擬的,只要按照模塊化的函數(shù),按照基本的邏輯編寫,調(diào)試是比較容易的。
程序一開始會要求用戶輸入每小時繳納多少元費用,顯示“請輸入停車每小時需交納的費用(元)”。
以棧模擬停車場,以隊列模擬車場外的便道,在while循環(huán)開始讓用戶輸入命令、車牌號、時間三個變量,對三個變量進(jìn)行判斷,并執(zhí)行相應(yīng)函數(shù)。
程序顯示“請輸入操作的命令,駛?cè)胪\噲鯝,離開停車場D,查看停車場內(nèi)車數(shù)P 0 0,查看候車廠內(nèi)車數(shù)W 0 0,程序結(jié)束E 0 0:”
如果后來輸入的時間比之前輸入的時間小,程序會提示“輸入的時間必須大于上一次輸入的時間: xx 請重新輸入”。
其中駛?cè)牒瘮?shù)先判斷是否棧滿,如果棧滿則執(zhí)行入隊操作,否則入棧,并將車牌號、駛?cè)霑r間存入棧元素數(shù)組,top值加一,用于記錄車的數(shù)量,用于判斷是否棧滿。
如果棧不滿,程序顯示“車牌號為xx的汽車在xx時刻停在xx車位”。
如果棧滿,程序顯示“xx號車停在候車便道的第xx個位置”。
離開函數(shù)先判斷是否???,如果??談t輸出沒有車輛提示,否則進(jìn)一步比較是否有棧內(nèi)車牌號元素與命令的離開的車牌號一致,有則出棧,計算停車時間和計價,無則輸出沒有此車牌號的車的提示。
如果沒有命令的車牌號的汽車,則顯示“對不起!停車場內(nèi)沒有車牌號為xx的車”。
如果停車場已空,會顯示“對不起!停車場已空!”。
如果原先棧滿,離開一輛車以后,最早到便道上的一輛車進(jìn)棧,并顯示“xx號汽車此時退出便道,進(jìn)入停車場最后一個位置”。
隊列和棧的top記錄了車的數(shù)量,可用于輸出內(nèi)部車數(shù),也可用于判斷是否棧滿。
如果三個變量分別為P,0,0,則輸出停車場內(nèi)車的個數(shù)。
如果三個變量分別為E,0,0,則輸出便道上車的個數(shù)。
如果三個變量分別為E ,0, 0,則結(jié)束程序。
六、使用說明
程序接受 5 個命令,分別是:到達(dá)(‘A’,車牌號,時間);離去(‘D’,車牌號,時 間);停車場(‘P’, 0, 0)顯示停車場的車數(shù);候車場(‘W’, 0, 0)顯示候車場的車數(shù);退出(‘E’, 0, 0)退出程序。
注意:命令字符(A D P W E)用大寫,輸入的三個數(shù)據(jù)之間用空格隔開。如A 1 5。代表1號1號汽車在5時刻進(jìn)場。
七、調(diào)試結(jié)果
按照測試要求給的數(shù)據(jù)進(jìn)行了測試:
八、遇到的問題和解決方法(程序調(diào)試日志)
2018/9/不詳
問題:程序全部結(jié)束,執(zhí)行時能基本完成功能,但是總是會間隔有一次命令無效,重復(fù)輸出“請輸入命令.......”。
解決方法:后來百度發(fā)現(xiàn),這是因為數(shù)據(jù)緩存區(qū)沒有清除的緣故,每次回車都會在數(shù)據(jù)緩存區(qū)遺留下來一個Enter字符,可被char型變量讀取,因此在每次輸入數(shù)據(jù)前后加入一個清除數(shù)據(jù)緩存區(qū)的函數(shù)setbuf(stdin, NULL)即可解決問題。
2018/10/20
最后一天,完善程序,將程序中的注釋寫清楚,百度找到了顯示系統(tǒng)時間的方法,按格式輸出,截屏、書寫報告。
九、實驗的收獲與感想
個人感想:
這道題目和后面的第四道題目都是屬于比較透徹的題目,先做了第二題,還是對第二題印象最深,首先這道題很講究編程的條理性,里面的初始化棧、判棧空、棧滿、入棧、出棧以及初始化隊列、判隊空、隊滿、入隊、出隊等函數(shù)在書上都有,主要的工作是利用模塊化的思想,由整體到局部逐漸求精地去寫整個程序,從而把整個停車場的5個命令功能給實現(xiàn),感覺收獲很多,模塊化的思想很厲害!
方法的優(yōu)點:
整體程序思路比較簡單,因此個人沒有什么更優(yōu)算法,只是在這里面有一個邏輯,就是后面輸入的時間不能比之前輸入的時間小,因為這不符合日常邏輯,同時也影響了入棧出棧次序,因此我程序里使用了不常用的goto函數(shù),一般這個函數(shù)是不建議用的,它會跳轉(zhuǎn)程序,但是在這里判斷后面輸入的時間大于之前輸入的時間后,goto函數(shù)可以讓程序跳轉(zhuǎn)到while循環(huán)開始的地方,讓用戶重新輸入命令,這里感覺很方便!
建議:
希望多多布置這樣的習(xí)題,有助于教會學(xué)生利用模塊化思想,不過希望布置的題目可以是多方向的比如有關(guān)界面制作的題目,把模塊化的函數(shù)給大家,大家進(jìn)行使用,根據(jù)自己愛好設(shè)計出相應(yīng)的模塊化功能的程序。
十、源程序
見源程序清單。
實驗三、管道鋪設(shè)施工的最佳方案問題
一、問題描述
1)問題描述
需要在某個城市 n 個居民小區(qū)之間鋪設(shè)煤氣管道,則在這 n 個居民小區(qū)之間只需要鋪設(shè) n-1 條管道即可。假設(shè)任意兩個小區(qū)之間都可以鋪設(shè)管道,但由于地理環(huán)境不同,所需要的費用也不盡相同。選擇最優(yōu)的方案能使總投資盡可能小,這個問題即為求無向網(wǎng)的最小生成樹。
2)基本要求
在可能假設(shè)的 m 條管道中,選取 n-1 條管道,使得既能連通 n 個小區(qū),又能使總投資最小。每條管道的費用以網(wǎng)中該邊的權(quán)值形式給出,網(wǎng)的存儲采用鄰接表的結(jié)構(gòu)。
3)測試數(shù)據(jù)
使用下圖給出的無線網(wǎng)數(shù)據(jù)作為程序的輸入,求出最佳鋪設(shè)方案。右側(cè)是給出的參考解。
以上是本實驗的題目要求,下面我將介紹我的實現(xiàn)算法,程序調(diào)試結(jié)果以及編程過程中遇到的具體問題,并且談?wù)勎业氖斋@和感悟!
二、需求分析
1、此程序用來求無向帶權(quán)網(wǎng)的最小生成樹。
2、程序的輸入數(shù)據(jù)放在一個dat格式的文件中,想要修改輸入數(shù)據(jù),用記事本打開文件直接修改即可。任何時刻想看到結(jié)果,點擊一下exe文件即可一鍵解決。
3、輸入數(shù)據(jù)的形式是一個矩陣形式,行和列的元素依次代表A、B、C....,兩點之間有邊,則數(shù)據(jù)是一個不為0的數(shù),否則為0。
4、程序運行結(jié)果不僅會在控制臺顯示出來,同時還要在一個新的文件中顯示出來,點擊一下exe文件即可一鍵解決,滿足用戶“即點即看”,輸出文件令用戶能“隨時且長久”看到結(jié)果,不必每一次都要運行程序。
三、概要設(shè)計
為實現(xiàn)上述功能,應(yīng)以圖的鄰接表數(shù)據(jù)結(jié)構(gòu),即鏈表與數(shù)組相結(jié)合的數(shù)據(jù)結(jié)構(gòu)。
1、鄰接表抽象數(shù)據(jù)類型定義:
ADT ALGraph{
數(shù)據(jù)對象:結(jié)點A、B、C....數(shù)據(jù)關(guān)系:存儲結(jié)構(gòu)上鏈表式指針相連,物理結(jié)構(gòu)上點之間相連成邊
基本操作:CreateALGraph(ALGraph *G);//建立無向圖的鄰接表存儲
}ADT ALGraph
2、文件操作模塊
基本操作:
read_data(void);//只讀方式打開文件
read_array(double *array,int n1,int n2,FILE *fp);//讀取文件中的邊值信息
cout_data(void);//只寫方式打開或建立文件
cout_array(double *array,int n1,int n2,FILE *fp);//向文件中寫入邊值信息
3、本程序保護(hù)模塊
主程序模塊
建立無向圖模塊:根據(jù)讀入文件的邊值信息創(chuàng)建無向圖鄰接表存儲
最小生成樹模塊:由無向圖生成最小生成樹
讀入數(shù)據(jù)模塊:只讀方式讀取文件數(shù)據(jù)
輸出結(jié)果模塊:將結(jié)果輸出到控制臺
輸出到文件模塊:將結(jié)果輸出到文件
調(diào)用關(guān)系:
四、詳細(xì)設(shè)計
需要建立一個無向圖的鄰接表存儲結(jié)構(gòu),進(jìn)行最小生成樹的提取。
1、元素類型、結(jié)點類型和結(jié)點指針類型:
#define MaxVertexNum 100 //設(shè)置小區(qū)數(shù)最多為100
#define VertexNum 9
double LeastNum;//用于記錄最短邊長度
double LongestNum;//用于記錄最長邊長度,程序過程中不改變
double adjacent[VertexNum][VertexNum];
//鄰接矩陣,不用于處理數(shù)據(jù),而是用于暫時存儲從文件讀來的數(shù)據(jù)
//進(jìn)而在鄰接表存儲數(shù)據(jù)時讀取此數(shù)組數(shù)據(jù)即可
//二維數(shù)組數(shù)據(jù)為0的元素說明之間沒有通道
//在處理完數(shù)據(jù)后,此數(shù)組會用來暫時存儲處理后的數(shù)據(jù),并寫入到另一個文件中
typedef struct vnode
{//頂點表結(jié)點
char vertex;
EdgeNode *firstedge;
}VertexNode;
typedef struct
{
VertexNode adjlist[MaxVertexNum];
int n,e;
}ALGraph;
2、有序表類型:
typedef struct node
{//邊表結(jié)點
char adjvex;
double weight;//權(quán)值
struct node *next;
}EdgeNode;
3、主函數(shù)的偽碼:
void main()
{
ALGraph *G;
PrintInformation1();
G =(ALGraph*)malloc(sizeof(ALGraph));
G->n = VertexNum;//為G指向的圖分配空間,設(shè)置點數(shù)(小區(qū)數(shù))
read_data();
CreateALGraph(G);
MinimumSpanningTree(G);
cout_data();//輸出到文件
ResultOutput((double *)adjacent,VertexNum,VertexNum);//輸出到控制臺
PrintInformation2();
system(”pause“);
}
4、算法流程圖
五、調(diào)試分析與核心算法解釋
此題按照Prim算法,設(shè)置一個用于存儲點的點集,找短邊從一個點向兩點、三個....更多逐漸擴(kuò)張,即可得到最小生成樹。
1).輸入:一個加權(quán)連通圖,其中頂點集合為V,邊集合為E;
2).初始化:Vnew = {x},其中x為集合V中的任一節(jié)點(起始點),Enew = {},為空;
3).重復(fù)下列操作,直到Vnew = V:
a.在集合E中選取權(quán)值最小的邊,其中u為集合Vnew中的元素,而v不在Vnew集合當(dāng)中,并且v∈V(如果存在有多條滿足前述條件即具有相同權(quán)值的邊,則可任意選取其中之一);
b.將v加入集合Vnew中,將邊加入集合Enew中;
4).輸出:使用集合Vnew和Enew來描述所得到的最小生成樹。
具體可以參考資料:https://baike.baidu.com/redirect/cb1fkztQc2TOscNlcMemKsGZ1fsgTprJsdBq_APeZx74W4q4TzbKXHsvSYW_6aM1DqhF56eTgD8EZLzBCQHKBGa6ExWmgXbju_gm13Qbbu0KxbHuiIS_DxEp2fgT3BU
六、使用說明
輸入數(shù)據(jù)已經(jīng)在”gyp_program3_Input.dat“中寫好,如果想做修改可以在該文件中修改即可,輸出的數(shù)據(jù)既在控制臺顯示,也會輸出到”gyp_program3_Output.dat“。
七、調(diào)試結(jié)果
輸入數(shù)據(jù)文件:
這是一個矩陣,例如:第2行,第3列代表B,C兩點間的邊,0代表無邊,不為0代表有邊。
控制臺程序顯示:
輸出數(shù)據(jù)到輸出文件
八、遇到的問題和解決方法(程序調(diào)試日志)
2018/9/不詳
問題:一進(jìn)入建立無向圖的函數(shù)程序就中止出錯。
解決方法:給建立無向圖函數(shù)傳遞的形參是指針,而在主函數(shù)中G指針沒有賦給內(nèi)存空間,所以函數(shù)無法對G所指的空間進(jìn)行初始化,在主程序中加入這樣一句代碼就好了:
G =(ALGraph*)malloc(sizeof(ALGraph));
2018/10/17
問題:輸出的二維數(shù)組只有一位正常,其余全是0。如下圖所示:
解決方法:后來發(fā)現(xiàn)是里面flag2這個標(biāo)志位剛開始是1,程序執(zhí)行過程中被置0用于判斷,但是判斷以后沒有再次重置為1,導(dǎo)致要用很多次的標(biāo)志位只發(fā)揮了一次作用,后面就誤判了,在循環(huán)結(jié)束加入重置1的語句即可。
問題:輸出的二維數(shù)組輸出數(shù)據(jù)不完整,里面總有最小的邊(問題切入點)。
解決方法:單步執(zhí)行后發(fā)現(xiàn),某一次循環(huán)中Leastnum這個變量得到的最小值恰好是所有邊中最小的一個,它在發(fā)揮完比較作用后,沒有被置為一個很大的數(shù)(不小于這些邊中最大值即可),結(jié)果在下一次循環(huán)的時候,導(dǎo)致后面的邊都比它大,以至于后面的邊都被舍去了,解決方法就是每次循環(huán)第一句先把原圖的最大邊賦給leastnum。
問題:直接運行debug文件夾里的exe程序,且debug程序終止,懷疑是文件數(shù)據(jù)讀取失敗,無法打開文件,即文件不存在。
解決方法:如果不詳細(xì)說明文件路徑,程序本身會在當(dāng)前文件夾內(nèi)找文件,存數(shù)據(jù)的文件gyp_program3_Input.dat要保存在當(dāng)前文件中。也就是和源代碼在同一個文件夾中,但是這樣子的話,只有用編程軟件打開代碼運行,dat文件才有效,若想在debug里直接運行exe程序,則把存數(shù)據(jù)的輸入文件同名復(fù)制到debug文件夾里即可。
九、實驗的收獲和感想
個人感想:這個程序可以說是算法感十足了,也是我遇到問題最大的一個程序,但是也證明了自己的能力,學(xué)到了很多,收獲最大的就是:對于用的不止一次的標(biāo)志位,一定不可能只單方向置位,一定是雙向置位,一次循環(huán)結(jié)束一定要記得置位,否則用了這一次以后,后面的循環(huán)就會誤判!
Prim算法真的很好用,不僅適合求帶球圖的最小生成樹,還適合尋找一個點到另一點的最短路徑。
個人方法優(yōu)點:輸入方便,輸出簡潔。讀取文件中的數(shù)據(jù),不用手動輸入,想修改數(shù)據(jù)在文件中修改就可以,另外輸出有兩種形式,一種是控制臺輸出,一種是輸出到文件,輸出的是一個二維數(shù)組,行和列都有表頭,看起來很清晰,兩個點之間若有邊,相應(yīng)二維坐標(biāo)的元素就是邊值,無邊則相應(yīng)的位置為0。
建議:可以要求用順序表的方法,因為從理解和編程難度角度考慮,圖的鄰接表找邊會很慢每次都要順著其中一個鏈表頭結(jié)點去尋找,不過這也很鍛煉人的能力!
十、源程序
見源程序清單。
實驗四、內(nèi)部排序算法的實現(xiàn)與比較
一、問題描述
1)問題描述
在教科書中,各種內(nèi)部排序算法的時間復(fù)雜度分析結(jié)果只給出了算法執(zhí)行時間的階,或大概執(zhí)行時間。試通過隨機(jī)數(shù)據(jù)比較各算法的關(guān)鍵字比較次數(shù)和關(guān)鍵字移動次數(shù),以取得直觀感受。
2)基本要求
(1)對常用的內(nèi)部排序算法進(jìn)行比較:直接插入排序、簡單選擇排序、冒泡排序、快速排序、希爾排序。
(2)利用隨機(jī)函數(shù)產(chǎn)生N(如30000)個隨機(jī)整數(shù),作為輸入數(shù)據(jù)作比較;比較的指標(biāo)為關(guān)鍵字參加的比較次數(shù)和關(guān)鍵字的移動次數(shù)(關(guān)鍵字交換計為3次移動)。
(3)對結(jié)果作出簡要分析。
3)測試數(shù)據(jù)
隨機(jī)函數(shù)產(chǎn)生。
4)提示
主要工作是設(shè)法在已知算法中適當(dāng)位置插入對關(guān)鍵字的比較次數(shù)和移動次數(shù)的計數(shù)操 作。注意采用分塊調(diào)試的方法。
5)輸入輸出:
輸入數(shù)據(jù):參加排序的整數(shù)個數(shù) n(如 n=30000);
輸出數(shù)據(jù):各種排序方法的關(guān)鍵字比較次數(shù)和移動次數(shù)(從小到大排列)。
二、需求分析
1、本程序用來比較5種排序的關(guān)鍵字比較次數(shù)和關(guān)鍵字移動次數(shù)。
2、本程序用srand()和rand()函數(shù)產(chǎn)生N個隨機(jī)數(shù)用于排序方法的比較,用戶無需輸入。
3、運行程序后,程序需按從小到大的順序分別輸出5種排序的關(guān)鍵字比較次數(shù)和移動次數(shù)。
三、概要設(shè)計
為實現(xiàn)上述功能,程序需要產(chǎn)生N個隨機(jī)數(shù),并且需要寫出這5種排序的排序函數(shù)。
1、產(chǎn)生N個隨機(jī)數(shù)的方法
srand((unsigned)(time(NULL)));
for(int j = 0;j < N;j++)
{
num0[j] = rand();
}
2、保證每次排序的數(shù)據(jù)都相同的方法
num0數(shù)組用于得到隨機(jī)數(shù),num數(shù)組每次排序前先用num0數(shù)組賦值即可。
for(int j=0;j { num[j] = num0[j]; } InsertSort(num,N);3、5種排序函數(shù) void InsertSort(int R[], int n);//插入排序 void SelectSort(int R[], int n);//選擇排序 void BubbleSort(int R[], int n);//冒泡排序 void QuickSort(int R[],int low,int high);//快速排序 void ShellInsert(int R[],int m,int n);//快速排序 void Shellsort(int R[],int n);//希爾排序 4、本程序保護(hù)模塊 主程序模塊 排序模塊 比較輸出模塊 調(diào)用關(guān)系: 4、算法流程圖 四、詳細(xì)設(shè)計 1、排序函數(shù)基本操作的偽碼實現(xiàn) void InsertSort(int R[], int n)//插入排序 { int i, j; for(i = 2;i <= n;i++) { R[0] = R[i]; MoveNum[0]++; j = i-1; while(R[0] < R[j]) { KeyCompareNum[0]++; R[j + 1] = R[j]; MoveNum[0]++; j--; } R[j + 1] = R[0]; MoveNum[0]++; } } void SelectSort(int R[], int n)//選擇排序 { int i, j, k; for(i = 1;i < n;i++) { k = i; for(j = i + 1;j <= n;j++) if(R[j] < R[k]) { k = j; KeyCompareNum[1]++; } if(k!= i) { R[0] = R[k]; R[k] = R[i]; R[i] = R[0]; MoveNum[1]+=3; } } } void BubbleSort(int R[], int n)//冒泡排序 { int i, j, flag = 0; for(i = 1;(i < n && flag == 0);i++) { flag = 1; for(j=1;j if(R[j + 1] < R[j]) { KeyCompareNum[2]++; flag = 0; R[0] = R[j]; R[j] = R[j+1]; R[j + 1] = R[0]; MoveNum[2]+=3; } } } void QuickSort(int R[],int low,int high)//快速排序 { int i,j; i=low; j=high; R[0]=R[i]; MoveNum[3]++; while(i { while((R[j]>=R[0])&&(j>i)) { j--; KeyCompareNum[3]++; } if(j>i) { R[i]=R[j]; MoveNum[3]++; i++; } while((R[i]<=r[0])&&(j>i)) { i++; KeyCompareNum[3]++; } if(j>i) { R[j]=R[i]; MoveNum[3]++; j--; } } R[i]=R[0]; MoveNum[3]++; if(low QuickSort(R,low,i-1); if(i QuickSort(R,j+1,high); } void ShellInsert(int R[],int m,int n) {//一趟希爾排序,按間隔m劃分子序列 int temp,j; for(int i=m;i { temp=R[i]; MoveNum[4]++; j=i; while(j>=m && temp { KeyCompareNum[4]++; R[j]=R[j-m]; MoveNum[4]++; j-=m; } R[j]=temp; MoveNum[4]++; } } void Shellsort(int R[],int n)//希爾排序 { int m; m=n/2; while(m>=1) { ShellInsert(R,m,n); m=(m==2?1:(m/2)); } } 2、主函數(shù)偽碼實現(xiàn) int main() { //數(shù)組設(shè)為N+1個是因為有些算法是從數(shù)組1到N存儲的,0位有的不用,有的用作了哨兵 int num0[N+1];//記錄最原先隨機(jī)產(chǎn)生的N個數(shù)字,因為num[N]每排序一次都會改變 int num[N+1];//每次排序前先讀入num0[N]數(shù)據(jù) //srand函數(shù)只增加一次就夠了,用系統(tǒng)當(dāng)前時間設(shè)置rand()隨機(jī)序列種子,保證每次運行隨機(jī)序列不一樣 srand((unsigned)(time(NULL))); for(int j = 0;j < N;j++) { num0[j] = rand(); } PrintInformation1(); for(int j=0;j { num[j] = num0[j]; } InsertSort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } SelectSort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } BubbleSort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } Shellsort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } QuickSort(num,0,N-1); printf(”關(guān)鍵字比較次數(shù)按從小到大排列分別是:rn“); KeyCompareNum_pailie(); printf(”rn“); printf(”移動次數(shù)按從小到大排列分別是:rn“); MoveNum_pailie(); PrintInformation2(); system(”pause“); return 0; } 五、調(diào)試分析與核心算法解釋 程序的5種排序函數(shù)可以自己寫,也可以百度找源碼,總之五種排序函數(shù)寫完以后,調(diào)試的關(guān)鍵是設(shè)置計數(shù)變量,并在這些函數(shù)的合適位置進(jìn)行加1計數(shù)或加3計數(shù),因此注意分塊調(diào)試,分函數(shù)調(diào)試,做到這幾點調(diào)試難度總體不大。 六、使用說明 隨機(jī)數(shù)產(chǎn)生,5種排序用的都是同一組N個隨機(jī)數(shù),用戶無需輸入,直接運行程序即可輸出運算結(jié)果。 七、調(diào)試結(jié)果 八、遇到的問題和解決方法(程序調(diào)試日志) 2018/10/19 問題:第一種排序輸出很大,后面輸出很小,幾乎沒作用。 解決方法:每經(jīng)過一個排序函數(shù),數(shù)組已經(jīng)排好序了,不能直接調(diào)用其余的排序函數(shù),而是要在程序一開始就用另一個數(shù)組num0[N]記錄了隨機(jī)數(shù)產(chǎn)生的數(shù)組num[N],因此只需要在每次排序前,把num0數(shù)組中數(shù)據(jù)重新賦給num數(shù)據(jù)即可參與排序了。 問題:數(shù)據(jù)輸出個數(shù)少于5個,單步執(zhí)行發(fā)現(xiàn)循環(huán)不到5次。 解決方案:分析后發(fā)現(xiàn),程序的幾個for循環(huán),內(nèi)層的循環(huán)里面的計數(shù)加1變量如i,j,和外層循環(huán)設(shè)置的加1變量用的是一個變量,導(dǎo)致內(nèi)層循環(huán)計數(shù)變量的改變會影響外層循環(huán),導(dǎo)致輸出個數(shù)小于5。將這些變量設(shè)置成不同變量就不影響了(相互獨立的循環(huán)可能不會影響,但內(nèi)外層關(guān)系的兩個循環(huán)絕對不能用同一個計數(shù)變量)。 問題:程序末尾會跳出一個程序中止警告框,說是棧釋放的問題。 解決方案:百度發(fā)現(xiàn),這實際上是數(shù)組越界的問題,把數(shù)組個數(shù)設(shè)置為N+1大小的,就好了。 九、實驗的收獲和感想 個人感想:這個程序難度不大,關(guān)鍵在于在合適的位置插入用于記錄的變量+1或者+3,真正有技術(shù)含量的在于按照從小到大的順序輸出相應(yīng)數(shù)據(jù)。收獲比較大的一個技巧:相互獨立的循環(huán)計數(shù)變量可能不會影響,但內(nèi)外層關(guān)系的兩個循環(huán)絕對不能用同一個計數(shù)變量,否則程序循環(huán)次數(shù)就會亂! 從關(guān)鍵字比較次數(shù)和移動次數(shù)來看,選擇和快速排序都是非常高效的,希爾排序也不錯,不要用或少用冒泡排序和直接插入排序。 個人方法的優(yōu)點:只產(chǎn)生了1次隨機(jī)數(shù),5次排序的用的都是同一組數(shù)據(jù),可以更好地更嚴(yán)謹(jǐn)?shù)乇容^出這5種算法的優(yōu)劣。 個人方法的缺點:因為要“長久”保留產(chǎn)生的隨機(jī)數(shù),因此需多設(shè)置一個數(shù)組,占用內(nèi)存空間比較大。 十、源程序 源程序見源程序清單。 參考資料 https://blog.csdn.net/guanyasu/article/details/53153705 https://jingyan.baidu.com/article/49711c616b8a1ffa441b7cdc.html https://zhidao.baidu.com/question/***684.html 源程序清單 實驗一、約瑟夫斯問題求解 #include #include #include #define ElemType int #define SLNODE struct sl_node SLNODE { ElemType data[2]; SLNODE *next; }; SLNODE *CREATE_SL(SLNODE*,int); void ShowInput(SLNODE*h,int n);//每個人的密碼輸入 void ShowOutput(SLNODE*,int);//排列輸出 void PrintInformation1();//輸出程序信息和個人信息 void PrintInformation2();//程序結(jié)束信息 void PrintTime();//輸出時間 int main() { int m,n,mistake=1; SLNODE *Head; PrintInformation1();//輸出程序信息和個人信息 while(mistake) { printf(”輸入人數(shù)n:n“); scanf_s(”%d“, &n); printf(”請指定初始報數(shù)上限m(m應(yīng)必須小于等于n):n“); scanf_s(”%d“, &m); if(m>n) { printf(”輸入數(shù)據(jù)有誤,請重新輸入n“); } else mistake=0; } Head =(SLNODE *)malloc(sizeof(SLNODE)); Head->next = NULL; Head = CREATE_SL(Head,n); ShowInput(Head,n); printf(”正確的出列順序為:rn“); ShowOutput(Head,m); PrintInformation2();//程序結(jié)束信息 system(”pause“); return 0; } void PrintTime() { time_t t; time(&t); printf(”%s“, ctime(&t)); printf(”rn“); } void PrintInformation1() { printf(”實驗名稱:實驗一.約瑟夫斯問題求解rn“); printf(”學(xué)號:031650106rn“); printf(”姓名:郭硯璞rn“); printf(”====================rn“); printf(”程序運行開始,Current local time and date:“); PrintTime(); } void PrintInformation2() { printf(”rn====================rn“); printf(”程序運行結(jié)束,Current local time and date:“); PrintTime(); } SLNODE *CREATE_SL(SLNODE *h,int n) //創(chuàng)建一個h為頭指針的鏈表,h指向的結(jié)點數(shù)據(jù)域用不到 { ElemType data; int i = 1; SLNODE *p, *s; p = h; while(i<=n) { printf(”請輸入第%d個元素:t“,i); scanf_s(”%d“, &data); s =(SLNODE *)malloc(sizeof(SLNODE)); s->data[0]=i; s->data[1] = data; if(h->next == NULL) { h->next = s; } else { p->next = s; } p = s; i++; } p->next = h; return h; } void ShowInput(SLNODE *h,int n) { SLNODE *p; p = h; printf(”%d“,n); printf(”個人的密碼依次為:“); while((p->next)!= h) { p = p->next; printf(”%dt“, p->data[1]); } printf(”n“); } void ShowOutput(SLNODE *h, int m) { SLNODE *p, *s;//s用于記錄上一個節(jié)點,從而使p結(jié)點找到它將其刪除 int j = 0; s = h;//第一次執(zhí)行此函數(shù)時,h指向頭結(jié)點;后面遞歸執(zhí)行時,h剛開始指向的是上一//次輸出的結(jié)點(還沒刪除) //都用s來記錄,等那一趟程序快結(jié)束找到下一個要出列的的點時,h指向那個結(jié)點作為頭結(jié)點,并且讓p找到s指向的 //上一個結(jié)點,把它刪除。 p = h; while(j < m-1) { p = p->next; if(p->next==h)//不能讓h所指向的結(jié)點(上一次輸出的結(jié)點,暫時用作頭結(jié)點所以//還未刪除)影響小循環(huán)次數(shù) { p=p->next;//所以此處讓p多移動一下,等下一次小循環(huán)讓p順利移動到下一//個節(jié)點(從而忽略掉h指向的結(jié)點) } //等找到下一個該出列的結(jié)點時,h指向那個結(jié)點(充當(dāng)下一次的頭節(jié)點),充當(dāng)上一次頭//結(jié)點的結(jié)點利用s刪除 j++; }//此時p指向第m-1個結(jié)點 if(p->next == h)//整個程序的終止條件,依次回到上個函數(shù)結(jié)尾,相當(dāng)于全部結(jié)束了 { return; } h= p->next; p = h;//此時h和p均指向要出列的結(jié)點 printf(”%dt“, h->data[0]); j = 0;//j用于while循環(huán),使h指針指向要出列的點的前一個結(jié)點,所以及時清零 while(p->next!=s)//找s廢棄節(jié)點 { p = p->next; } s = p->next; p->next = s->next;//連接新結(jié)點 free(s);//釋放s所指空間 ShowOutput(h,h->data[1]); } 實驗二、停車場管理問題 #include ”stdio.h“ #include ”stdlib.h“ #include ”time.h“ #define Maxsize 2 //停車場最多能停的車數(shù) #define ElemType int int Prize;//每停一個時刻收費多少元 static int num = 0;//num用于記錄入隊的車所在的位置 typedef struct stack //模擬停車場的棧 { ElemType license[Maxsize];//用于存放車牌號 ElemType timeIn[Maxsize];//用于存放入停車場時間 int top; }Parking; typedef struct stack1 //退車時暫時存放 { ElemType license[Maxsize-1]; ElemType timeIn[Maxsize-1]; int top; }Backup; typedef struct road { ElemType license; struct road *next; }Road; typedef struct linkqueue//隊列模擬便道 { Road *front,*rear; }LinkQueue; void GetIn(Parking *s, LinkQueue *q, ElemType license, ElemType timeIn);//有車進(jìn)來 void GetOut(Parking *s, Backup *s1, LinkQueue *q, ElemType license, ElemType timeOut);//有車//出去 void PrintInformation1();//輸出程序信息和個人信息 void PrintInformation2();//程序結(jié)束信息 void PrintTime() { time_t t; time(&t); printf(”%s“, ctime(&t)); printf(”rn“); } void PrintInformation1() { printf(”實驗名稱:實驗二.停車場管理問題rn“); printf(”學(xué)號:031650106rn“); printf(”姓名:郭硯璞rn“); printf(”====================rn“); printf(”程序運行開始,Current local time and date:“); PrintTime(); } void PrintInformation2() { printf(”rn====================rn“); printf(”程序運行結(jié)束,Current local time and date:“); PrintTime(); } //給停車場用的配置函數(shù) Parking *Init_Parking()//置空棧 { Parking *s; s=(Parking*)malloc(sizeof(Parking)); s->top=-1; return s; } int IsEmpty_Parking(Parking *s)//判空棧 { if(s->top==-1) return 1; else return 0; } int Push_Parking(Parking *s,ElemType license,ElemType timeIn)//入棧 { if(s->top==Maxsize-1) return 0; else { s->top++; s->license[s->top]=license; s->timeIn[s->top]=timeIn; return 1; } } int Pop_Parking(Parking *s,ElemType *license,ElemType *timeIn)//出棧 { if(IsEmpty_Parking(s)) return 0; else { *license = s->license[s->top]; *timeIn = s->timeIn[s->top]; s->top--; return 1; } } //給備用棧配置的函數(shù) Backup *Init_Backup()//置空棧 { Backup *s; s =(Backup*)malloc(sizeof(Backup)); s->top =-1; return s; } int IsEmpty_Backup(Backup *s)//判空棧 { if(s->top ==-1) return 1; else return 0; } int Push_Backup(Backup *s, ElemType license, ElemType timeIn)//入棧 { if(s->top == Maxsize-1) return 0; else { s->top++; s->license[s->top] = license; s->timeIn[s->top] = timeIn; return 1; } } int Pop_Backup(Backup *s, ElemType *license,ElemType* timeIn)//出棧 { if(IsEmpty_Backup(s)) return 0; else { *license = s->license[s->top]; *timeIn = s->timeIn[s->top]; s->top--; return 1; } } //給候車便道鏈?zhǔn)疥犃信渲玫暮瘮?shù) LinkQueue *Init_LQueue()//創(chuàng)建一個帶頭結(jié)點的空隊 { LinkQueue *q; Road *p; q =(LinkQueue*)malloc(sizeof(LinkQueue)); p =(Road*)malloc(sizeof(Road)); p->next = NULL; q->front = q->rear = p; return q; } void In_LQueue(LinkQueue *q, ElemType license)//入隊 { Road *p; p =(Road*)malloc(sizeof(Road)); p->license = license; p->next = NULL; q->rear->next = p; q->rear = p; } int IsEmpty_LQueue(LinkQueue *q)//判隊空 { if(q->front == q->rear) return 1; else return 0; } int Out_LQueue(LinkQueue *q, ElemType *license)//出隊 { Road *p; if(IsEmpty_LQueue(q)) { printf(”隊空“); return 0; } else { p = q->front->next; q->front->next = p->next; *license = p->license; free(p); if(q->front->next == NULL) q->rear = q->front; return 1; } } void main() { ElemType license, time,timelast=0; //timeInlast是最近一次有車進(jìn)停車場的時間,提示以后輸入的進(jìn)場時間要大于此數(shù)值 char command;//進(jìn)入A還是離開D Parking *s; Backup *s1; LinkQueue *q; PrintInformation1();//輸出程序信息和個人信息 s = Init_Parking();//停車場 q = Init_LQueue();//便道隊列 s1 = Init_Backup();//退車時的備用棧 printf(”請輸入停車每小時需交納的費用(元)rn“); setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少 scanf(”%d“,&Prize); setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少 while(1) { setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少 Loop:printf(”請輸入操作的命令,駛?cè)胪\噲鯝,離開停車場D,查看停車場內(nèi)車數(shù)P 0 0,查看候車廠內(nèi)車數(shù)W 0 0,程序結(jié)束E 0 0:n“); scanf(”%c%d%d“,&command, &license,&time); setbuf(stdin, NULL);//使stdin輸入流由默認(rèn)緩沖區(qū)轉(zhuǎn)為無緩沖區(qū),必不可少 if(command == A) { if(time <= timelast) { printf(”輸入的時間必須大于上一次輸入的時間:t“); printf(”%dt“, timelast); printf(”請重新輸入n“); goto Loop; } else { timelast = time; GetIn(s,q,license,time); } } if(command == D) { if(time <= timelast) { printf(”輸入的時間必須大于上一次輸入的時間:t“); printf(”%dt“, timelast); printf(”請重新輸入n“); goto Loop; } else { timelast = time; GetOut(s, s1, q, license, time);//車開走的函數(shù) } } if(command == P) { if(license == 0 && time == 0) printf(”停車場內(nèi)停了%d輛車n“,s->top+1);//顯示停車場車數(shù) } if(command == W) { if(license == 0 && time == 0) printf(”侯車場內(nèi)停了%d輛車n“,num);//顯示候車場車數(shù) } if(command == E) { if(license == 0 && time == 0) { PrintInformation2();//程序結(jié)束信息 system(”pause“); return; } } } } //停車函數(shù) void GetIn(Parking *s, LinkQueue *q,ElemType license, ElemType timeIn) { if(Push_Parking(s, license, timeIn)== 1)//說明成功進(jìn)入停車場 { printf(”%d號車在%d時刻停在停車場第%d個位置nn“,license,timeIn,s->top+1); } else //棧滿,汽車要進(jìn)入便道,即入隊 { num++; In_LQueue(q,license); printf(”%d號車停在候車便道的第%d個位置nn“,license,num); } } void GetOut(Parking *s, Backup *s1,LinkQueue *q, ElemType license, ElemType timeOut) { ElemType *licen, *tim;//兩個指針賦給出棧函數(shù),用于讀取車牌號和進(jìn)停車場時間 ElemType ParkTime;//汽車在停車場停留的時間 ElemType Money;//汽車應(yīng)繳金額 licen =(ElemType*)malloc(sizeof(ElemType)); tim=(ElemType*)malloc(sizeof(ElemType)); if(IsEmpty_Parking(s))//先判斷停車場內(nèi)是否有車 { printf(”對不起!停車場已空!nn“); return; } while(s->license[s->top]!= license) { Pop_Parking(s,licen,tim); Push_Backup(s1, *licen, *tim); if(IsEmpty_Parking(s)==1) { printf(”對不起!停車場內(nèi)沒有車牌號為%d的車nn“,license); while(IsEmpty_Backup(s1)!= 1) { Pop_Backup(s1, licen, tim); Push_Parking(s, *licen, *tim); } return; } } if(s->license[s->top] == license) { ParkTime = timeOut-s->timeIn[s->top]; Money = ParkTime * Prize; printf(”汽車在停車場內(nèi)停留的時間為%d小時,應(yīng)繳費%d元nn“,ParkTime,Money); Pop_Parking(s, licen, tim); while(IsEmpty_Backup(s1)!= 1) { Pop_Backup(s1,licen,tim); Push_Parking(s,*licen,*tim); } if(IsEmpty_LQueue(q)!= 1) { Out_LQueue(q,licen); Push_Parking(s,*licen,timeOut); printf(”%d號汽車此時退出便道,進(jìn)入停車場最后一個位置nn“,*licen); num--; } } } 實驗三、管道鋪設(shè)施工的最佳方案問題 #include ”stdio.h“ #include ”stdlib.h“ #include ”time.h“ #define MaxVertexNum 100 //設(shè)置小區(qū)數(shù)最多為100 #define VertexNum 9 double LeastNum;//用于記錄最短邊長度 double LongestNum;//用于記錄最長邊長度,程序過程中不改變 double adjacent[VertexNum][VertexNum]; //鄰接矩陣,不用于處理數(shù)據(jù),而是用于暫時存儲從文件讀來的數(shù)據(jù) //進(jìn)而在鄰接表存儲數(shù)據(jù)時讀取此數(shù)組數(shù)據(jù)即可 //二維數(shù)組數(shù)據(jù)為0的元素說明之間沒有通道 //在處理完數(shù)據(jù)后,此數(shù)組會用來暫時存儲處理后的數(shù)據(jù),并寫入到另一個文件中 typedef struct node {//邊表結(jié)點 char adjvex; double weight;//權(quán)值 struct node *next; }EdgeNode; typedef struct vnode {//頂點表結(jié)點 char vertex; EdgeNode *firstedge; }VertexNode; typedef struct { VertexNode adjlist[MaxVertexNum]; int n,e; }ALGraph; void PrintInformation1();//輸出程序信息和個人信息 void PrintInformation2();//程序結(jié)束信息 void CreateALGraph(ALGraph *);//將文件中數(shù)據(jù)導(dǎo)入進(jìn)來構(gòu)建無向圖鄰接表 void MinimumSpanningTree(ALGraph *);//將無向圖轉(zhuǎn)化為最小生成樹 void ResultOutput(double *array,int n1,int n2);//將數(shù)據(jù)在控制臺顯示出來 void read_data(void);//從輸入文件讀取數(shù)據(jù)到鄰接矩陣 void cout_data(void);//將鄰接矩陣中的數(shù)據(jù)輸出到輸出文件 void read_array(double *array,int n1,int n2,FILE *fp);//內(nèi)部函數(shù),用戶無需調(diào)用 void cout_array(double *array,int n1,int n2,FILE *fp);//內(nèi)部函數(shù),用戶無需調(diào)用 void main() { ALGraph *G; PrintInformation1(); G =(ALGraph*)malloc(sizeof(ALGraph)); G->n = VertexNum;//為G指向的圖分配空間,設(shè)置點數(shù)(小區(qū)數(shù)) read_data(); CreateALGraph(G); MinimumSpanningTree(G); cout_data();//輸出到文件 ResultOutput((double *)adjacent,VertexNum,VertexNum);//輸出到控制臺 PrintInformation2(); system(”pause“); } void PrintTime() { time_t t; time(&t); printf(”%s“, ctime(&t)); printf(”rn“); } void PrintInformation1() { printf(”實驗名稱:實驗三.管道鋪設(shè)施工的最佳方案問題rn“); printf(”學(xué)號:031650106rn“); printf(”姓名:郭硯璞rn“); printf(”====================rn“); printf(”程序運行開始,Current local time and date:“); PrintTime(); } void PrintInformation2() { printf(”rn====================rn“); printf(”程序運行結(jié)束,Current local time and date:“); PrintTime(); } void CreateALGraph(ALGraph *G) { //建立無向圖的鄰接表存儲 int i=0,j=0,k=0; EdgeNode *s; for(i = 0;i < G->n;i++) { G->adjlist[i].vertex = 65 + i; printf(”t%c“,(G->adjlist[i].vertex));//控制臺輸出列表頭 G->adjlist[i].firstedge=NULL; } printf(”n“); for(k=0;k { for(j=0;j { if(adjacent[k][j]!=0) { s =(EdgeNode*)malloc(sizeof(EdgeNode)); s->adjvex = 65+j; s->weight=adjacent[k][j]; s->next = G->adjlist[k].firstedge; G->adjlist[k].firstedge = s; } } } } void read_data(void) { int i,j; FILE *fp; fp=fopen(”gyp_program3_Input.dat“,”r“);// 輸入數(shù)據(jù)文件 read_array((double *)adjacent,VertexNum,VertexNum,fp); fclose(fp); for(i = 0;i < VertexNum;i++) { for(j = 0;j < VertexNum;j++) { if(adjacent[i][j] > LongestNum) { LongestNum = adjacent[i][j];//即給LongestNum設(shè)置的初值為最大邊邊值 } } } } void read_array(double *array,int n1,int n2,FILE *fp) { int i,j; float q; for(i=0;i for(j=0;j { fscanf(fp,”%f“,&q); *array++ =(double)q; } } void cout_data(void) { FILE *fp; fp=fopen(”gyp_program3_Output.dat“,”w“);//輸出數(shù)據(jù)文件 cout_array((double *)adjacent,VertexNum,VertexNum,fp); fclose(fp); } void cout_array(double *array,int n1,int n2,FILE *fp) { int i,j; for(i = 0;i < n2;i++) { fprintf(fp, ”t%c“, 65 + i);//輸出文件里打印列表頭 } fprintf(fp,”n“); for(i=0;i { fprintf(fp,”%ct“,65+i);//輸出文件里打印行表頭 for(j=0;j { fprintf(fp,”%.1ft“,*array); array++; } fprintf(fp,”n“); } } void ResultOutput(double *array,int n1,int n2) { int i,j; for(i=0;i { printf(”%ct“,65+i);//控制臺輸出行表頭 for(j=0;j { printf(”%.1ft“,*array); array++; } printf(”n“); } } void MinimumSpanningTree(ALGraph *G) {//將無向圖轉(zhuǎn)化為最小生成樹 int i, j, k; int flag2=1,point; int start, end; EdgeNode *s; char NowAdjacent[VertexNum]; for(i=0;i { for(j = 0;j < VertexNum;j++) { adjacent[i][j] = 0;//先將鄰接矩陣所有值清零 } } NowAdjacent[0]=G->adjlist[0].vertex;//初始點放入點集 for(i=0;i //剛開始只有一個起始點,之后加入剩余的VertexNum個點,即VertexNum-1次循環(huán) { LeastNum = LongestNum;//這一步很重要,每加入一個點,應(yīng)把LeastNum初始化為//最大值,避免受之前數(shù)值的影響 for(j = 0;j < i + 1;j++)//第i次點集里有i+1個點,即比較這i+1個點與生于點邊的大//小,找最小邊的另一個點 { point = NowAdjacent[j]-A;//用于指示已經(jīng)存進(jìn)點集中的點是圖的第幾個點 s = G->adjlist[point].firstedge; while(s!= NULL) { for(k = 0;k < i + 1;k++) { if(s->adjvex == NowAdjacent[k]) { flag2 = 0;//flag2=0用于指示此時s所指的點已經(jīng)在點集內(nèi) break; } } if(flag2 == 1)//確保僅當(dāng)s指向的點是不在點集里的點時,才被比較處理 { if((LeastNum > s->weight)&&(s->weight!=0)) { end = s->adjvex-A;//flag用于指示最短邊是第幾個點 start = point; LeastNum = s->weight; } } s = s->next; flag2 = 1;//標(biāo)志位有可能已經(jīng)被清0,必須重設(shè)為1,確保不影響下一次 } //啟發(fā):對于用的不止一次的標(biāo)志位,一定不可能只單方向置位,一定是雙向置位,//否則用了一次,后面就會誤判 } adjacent[start][end] = LeastNum; adjacent[end][start] = LeastNum; NowAdjacent[i + 1] = G->adjlist[end].vertex;//向點集加入新點 } } 實驗四、內(nèi)部排序算法的實現(xiàn)與比較 #include ”stdio.h“ #include ”stdlib.h“ #include ”time.h“ const int N=3000;//隨機(jī)產(chǎn)生N個隨機(jī)整數(shù) void PrintInformation1();//輸出程序信息和個人信息 void PrintInformation2();//程序結(jié)束信息 void PrintTime(); void InsertSort(int R[], int n);//插入排序 void SelectSort(int R[], int n);//選擇排序 void BubbleSort(int R[], int n);//冒泡排序 void QuickSort(int R[],int low,int high);//快速排序 void ShellInsert(int R[],int m,int n);//快速排序 void Shellsort(int R[],int n);//希爾排序 void KeyCompareNum_pailie(); void MoveNum_pailie(); int KeyCompareNum[5]={0};//分別存儲這5種排序的關(guān)鍵字比較次數(shù) int MoveNum[5]={0};//分別存儲這5種排序的移動次數(shù) int main() { //數(shù)組設(shè)為N+1個是因為有些算法是從數(shù)組1到N存儲的,0位有的不用,有的用作了哨兵 int num0[N+1];//記錄最原先隨機(jī)產(chǎn)生的N個數(shù)字,因為num[N]每排序一次都會改變 int num[N+1];//每次排序前先讀入num0[N]數(shù)據(jù) //srand函數(shù)只增加一次就夠了,用系統(tǒng)當(dāng)前時間設(shè)置rand()隨機(jī)序列種子,保證每次運行隨機(jī)序列不一樣 srand((unsigned)(time(NULL))); for(int j = 0;j < N;j++) { num0[j] = rand(); } PrintInformation1(); for(int j=0;j { num[j] = num0[j]; } InsertSort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } SelectSort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } BubbleSort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } Shellsort(num,N); for(int j = 0;j < N;j++) { num[j] = num0[j]; } QuickSort(num,0,N-1); printf(”關(guān)鍵字比較次數(shù)按從小到大排列分別是:rn“); KeyCompareNum_pailie(); printf(”rn“); printf(”移動次數(shù)按從小到大排列分別是:rn“); MoveNum_pailie(); PrintInformation2(); system(”pause“); return 0; } void KeyCompareNum_pailie()//關(guān)鍵字比較次數(shù)排列 { int i,j,k,m; int printnum=0;//用于記錄上一次輸出的是數(shù)組KeyCompareNum的第幾個數(shù) int minimum;//用于輸出最小的數(shù)字 int maximum=0; for(i = 0;i < 5;i++) { if(maximum < KeyCompareNum[i]) maximum = KeyCompareNum[i]; } for(m = 0;m< 5;m++) { minimum = maximum; //minimum在每次輸出是都是全新的,不能受之前數(shù)值的影響,因此每次輸出第一步先//把minimum設(shè)為最大值 for(j = 0;j < 5;j++) { if((minimum >=KeyCompareNum[j])&&(KeyCompareNum[j]!= 0)) { minimum = KeyCompareNum[j]; } } for(k = 0;k < 5;k++)//編程時k原先用的還是i,結(jié)果i=4這個情況,break以后到緊接//著的外層循環(huán)時,i的數(shù)值影響到了外層循環(huán),跳了出來,因此換成了k { if(minimum == KeyCompareNum[k]) { KeyCompareNum[k] = 0; printnum = k; break; } } if(printnum == 0) printf(”直接插入排序:%dt“, minimum); if(printnum == 1) printf(”選擇排序:%dt“,minimum); if(printnum == 2) printf(”冒泡排序:%dt“, minimum); if(printnum == 3) printf(”快速排序:%dt“, minimum); if(printnum == 4) printf(”希爾排序:%dt“, minimum); } printf(”rn“); } void MoveNum_pailie()//移動次數(shù)排列 { int i, j, k, m; int printnum = 0;//用于記錄上一次輸出的是數(shù)組KeyCompareNum的第幾個數(shù) int minimum;//用于輸出最小的數(shù)字 int maximum = 0; for(i = 0;i < 5;i++) { if(maximum < MoveNum[i]) maximum = MoveNum[i]; } for(m = 0;m < 5;m++) { minimum = maximum;//minimum每次輸出是都是全新的,不能受之前數(shù)值的影響,//因此每次輸出第一步先把minimum設(shè)為最大值 for(j = 0;j < 5;j++) { if((minimum >= MoveNum[j])&&(MoveNum[j]!= 0)) { minimum = MoveNum[j]; } } for(k = 0;k < 5;k++)//編程時k原先用的還是i,結(jié)果i=4這個情況,break以后到緊接//著的外層循環(huán)時,i的數(shù)值影響到了外層循環(huán),跳了出來 {//因此換成了k if(minimum == MoveNum[k]) { MoveNum[k] = 0; printnum = k; break; } } if(printnum == 0) printf(”直接插入排序:%dt“, minimum); if(printnum == 1) printf(”選擇排序:%dt“, minimum); if(printnum == 2) printf(”冒泡排序:%dt“, minimum); if(printnum == 3) printf(”快速排序:%dt“, minimum); if(printnum == 4) printf(”希爾排序:%dt“, minimum); } printf(”rn“); } void InsertSort(int R[], int n)//插入排序 { int i, j; for(i = 2;i <= n;i++) { R[0] = R[i]; MoveNum[0]++; j = i-1; while(R[0] < R[j]) { KeyCompareNum[0]++; R[j + 1] = R[j]; MoveNum[0]++; j--; } R[j + 1] = R[0]; MoveNum[0]++; } } void SelectSort(int R[], int n)//選擇排序 { int i, j, k; for(i = 1;i < n;i++) { k = i; for(j = i + 1;j <= n;j++) if(R[j] < R[k]) { k = j; KeyCompareNum[1]++; } if(k!= i) { R[0] = R[k]; R[k] = R[i]; R[i] = R[0]; MoveNum[1]+=3; } } } void BubbleSort(int R[], int n)//冒泡排序 { int i, j, flag = 0; for(i = 1;(i < n && flag == 0);i++) { flag = 1; for(j=1;j if(R[j + 1] < R[j]) { KeyCompareNum[2]++; flag = 0; R[0] = R[j]; R[j] = R[j+1]; R[j + 1] = R[0]; MoveNum[2]+=3; } } } void QuickSort(int R[],int low,int high)//快速排序 { int i,j; i=low; j=high; R[0]=R[i]; MoveNum[3]++; while(i { while((R[j]>=R[0])&&(j>i)) { j--; KeyCompareNum[3]++; } if(j>i) { R[i]=R[j]; MoveNum[3]++; i++; } while((R[i]<=r[0])&&(j>i)) { i++; KeyCompareNum[3]++; } if(j>i) { R[j]=R[i]; MoveNum[3]++; j--; } } R[i]=R[0]; MoveNum[3]++; if(low QuickSort(R,low,i-1); if(i QuickSort(R,j+1,high); } void ShellInsert(int R[],int m,int n) {//一趟希爾排序,按間隔m劃分子序列 int temp,j; for(int i=m;i { temp=R[i]; MoveNum[4]++; j=i; while(j>=m && temp { KeyCompareNum[4]++; R[j]=R[j-m]; MoveNum[4]++; j-=m; } R[j]=temp; MoveNum[4]++; } } void Shellsort(int R[],int n)//希爾排序 { int m; m=n/2; while(m>=1) { ShellInsert(R,m,n); m=(m==2?1:(m/2)); } } void PrintTime() { time_t t; time(&t); printf(”%s“, ctime(&t)); printf(”rn“); } void PrintInformation1() { printf(”實驗名稱:實驗四.內(nèi)部排序算法的實現(xiàn)與比較rn“); printf(”學(xué)號:031650106rn“); printf(”姓名:郭硯璞rn“); printf(”====================rn“); printf(”程序運行開始,Current local time and date:“); PrintTime(); } void PrintInformation2() { printf(”rn====================rn“); printf(”程序運行結(jié)束,Current local time and date:"); PrintTime(); } 《計算機(jī)網(wǎng)絡(luò)實踐實驗報告》 實驗一 :傳輸介質(zhì)的實驗 實驗思考題: 1.左右兩側(cè)線序完全一致,但不是標(biāo)準(zhǔn)線序。問:能否當(dāng)正線使用? 2.8根線中有4根是實際用于數(shù)據(jù)傳輸。問:是哪4根? 3.直通線和交叉線實際的應(yīng)用環(huán)境是什么? 4.列出3中功能不同的測線儀,并簡述其功能。 實驗二 :常用網(wǎng)絡(luò)命令介紹 實驗思考題: 1.如何通過常用網(wǎng)絡(luò)命令判斷目標(biāo)主機(jī)的操作系統(tǒng)? 2.作為一名網(wǎng)管,應(yīng)對于網(wǎng)絡(luò)拓?fù)溆性敱M的了解。如何通過網(wǎng)絡(luò)命令判斷故障點。 3.分析網(wǎng)關(guān)的作用。 實驗三 :在WindowsServer 2003 環(huán)境下配置WWW服務(wù) 實驗思考題: 1.WWW服務(wù)的支撐組件事ISS,最新的IIS版本是什么?支撐WWW所必須的IIS組件事什么?(internet信息服務(wù)管理器公用文件 萬維網(wǎng)服務(wù)) 2.同一IP能否搭配兩個或多個WWW服務(wù)器?能 3.如何設(shè)計非80端口訪問服務(wù)器? 默認(rèn)網(wǎng)站 右鍵 屬性 tcp端口瀏覽器輸入 http://10.0.56.77:8080 4.Windows 默認(rèn)的站點主目錄是什么? C:Inetpubwwwroot 5.描述hTTP協(xié)議工作的過稱及原理。 實驗四 :在Windows Server 2003 下搭建DNS 服務(wù)器 實驗思考題: 1.把本機(jī)搭成DNS服務(wù)器,能否為主機(jī)某一網(wǎng)站分配兩個或多個域名?能 2.在同一DNS服務(wù)器內(nèi),能否為不同的網(wǎng)站(不同的IP)分配相同的域名?不能 3.在實驗實內(nèi)為本機(jī)安裝了DNS組件,但沒有添加任何記錄。在TCP/IP 屬性里,將本機(jī)的IP設(shè)成唯一的DNS 服務(wù)器。在外網(wǎng)連通的情況下,你能否通過域名 訪問百度網(wǎng)站?不能 4.在TCP/IP屬性里面,將本機(jī)IP設(shè)成唯一DNS服務(wù)器,在外網(wǎng)連通的情況下,能否通過域名訪問百度網(wǎng)站。不能 5.某主機(jī)IP掩碼網(wǎng)關(guān)配置正常,未設(shè)DNS服務(wù)器,該主機(jī)能否訪問某一網(wǎng)站,如 可以,通過什么來訪問? 能通過代理訪問 6.反向搜索區(qū)域的作用 實驗五:搭建DHCP 實驗思考題: 1.能否通過交換機(jī)充當(dāng)DHCP服務(wù)器?如可以,用二層交換機(jī)還是三層交換機(jī)? 2.DHCP服務(wù)器的IP是否必須要和IP值在同一子網(wǎng),說明原因,如果在同一子網(wǎng),該IP是否需要做排除?如果不做排除,地址租約中會出現(xiàn)什么樣的效果? 3.設(shè)計一個實驗,使租約生效。 4.DHCP服務(wù)器是否需要為客戶端分配網(wǎng)關(guān)及DNS,描述原因。 實驗六:用serv—u搭建服務(wù)器 實驗思考題: 1.serv—u中組的使用 2.課堂所列問題 實驗七:代理服務(wù)器 實驗思考題: 1.設(shè)置代理服務(wù)器的作用 2.分析代理服務(wù)器與網(wǎng)絡(luò)安全之間的關(guān)系 3.列出三個實際應(yīng)用的代理服務(wù)器軟件 江西省中小學(xué)教育教學(xué)課題研究 課程實踐 課題名稱:<<促進(jìn)班級陽光體育運動研究>> 內(nèi)容:促進(jìn)班級陽光體育運動的探究 課題類別:初中體育 課題負(fù)責(zé)人:丁釘 供稿老師:談旭 促進(jìn)班級陽光體育運動的探究 談旭供稿 “健康體魄是青少年為祖國和人民服務(wù)的基本前提,是中華民族旺盛生命力的體現(xiàn)?!苯陙黼S著中國經(jīng)濟(jì)水平持續(xù)高速發(fā)展,人民生活水平日益提高,我國青少年學(xué)生體質(zhì)健康問題卻愈來愈令人擔(dān)憂。有的學(xué)生肺活量等體能素質(zhì)持續(xù)下降、肥胖學(xué)生繼續(xù)增多、學(xué)生近視率居高不下、學(xué)生心理問題增多,對于這些狀況大家都意識到事情的嚴(yán)重性,多方通過調(diào)查分析探討導(dǎo)致學(xué)生體質(zhì)下降的原因。原因很多,其中學(xué)校方面主要是政策執(zhí)行不到位、體育教師師資力量薄弱以及體育活動缺乏科學(xué)性與實效性等問題,針對這些問題學(xué)校也及時改進(jìn)并采取一些有效措施和對策,如為了落實每天鍛煉一小時活動,體育課增加了,課外活動形式多樣了,活動內(nèi)容也豐富多彩,取得了一定成效。但是,根據(jù)我們的調(diào)查走訪發(fā)現(xiàn)許多小學(xué)的體育課與課外體育活動之間沒有很好的結(jié)合,體育課的教學(xué)內(nèi)容沒有在課外體育活動中體現(xiàn)實效性。 首先,學(xué)生在體育課上學(xué)習(xí)時間短,練習(xí)時間少,動作難以成型。如果沒有在課外體育活動中去反復(fù)練習(xí)鞏固,那么體育課學(xué)習(xí)的運動技能掌握的效果就會大打折扣。相反,則會有利于學(xué)生運動技能的深層掌握。 其次,課外體育活動的內(nèi)容多,沒有練習(xí)要求,學(xué)生在活動時淺嘗輒止,浮光掠影,沒有一定的運動技能深度。僅僅是低水平的簡單重復(fù),一段時間后,學(xué)生的練習(xí)興趣勢必減弱,造成學(xué)生活動量難以控制,練習(xí)的效果不高。如果課外體育活動適當(dāng)與體育課的教學(xué)相結(jié)合,那么這種狀況就會有所改變。 目前對于體育課或課外體育活動的實踐研究大部分是單獨研究,體育課與體育課外活動兩者有機(jī)結(jié)合的實踐研究還不多。 關(guān)于體育課與課外體育活動的觀點主要有:課外體育活動是體育課程的延伸和繼續(xù)補(bǔ)充,為此有的教育學(xué)者提出了“第二課堂”的說法。這充分地考慮到課外體育活動的作用,重視課外體育活動與教學(xué)兩者之間的緊密聯(lián)系,但是我們認(rèn)為它們之間還是有差別的。我們必須根據(jù)體育課和課外體育活動的特點,遵循體育教學(xué)規(guī)律和課外體育活動鍛煉原則,科學(xué)的把體育課與課外體育活動有機(jī)結(jié)合起來。一方面抓好課堂教學(xué)工作,另一方面,重視和發(fā)揮課外體育活動的作用,做到課內(nèi)外教練密切結(jié)合,彌補(bǔ)體育課作業(yè)形式化的問題,這樣能激發(fā)學(xué)生體育 運動興趣,有效增強(qiáng)學(xué)生體能,培養(yǎng)學(xué)生良好的意志品格,促進(jìn)學(xué)生身心健康,更好地完成學(xué)校體育任務(wù),進(jìn)一步服務(wù)學(xué)生,充分體現(xiàn)生本教育。 創(chuàng)新之處 1)體育課與課外體育活動的內(nèi)容進(jìn)行整合,使體育教學(xué)內(nèi)容能在課外體育活動中真正延伸。既豐富課外體育活動內(nèi)容,又使課內(nèi)外的教學(xué)練習(xí)相結(jié)合,彌補(bǔ)體育課作業(yè)形式化的問題,促進(jìn)學(xué)生更加扎實地掌握體育課中所學(xué)技能。 2)對課外體育活動的組織者進(jìn)行體育課中學(xué)生練習(xí)時的組織教學(xué)培訓(xùn),提高他們組織學(xué)生體育練習(xí)的指導(dǎo)能力,同時使師生明確體育課外活動的要求目的,以提高課外體育活動的質(zhì)量,提升學(xué)生在課外體育活動中技能水平。 3)體育課與課外體育活動相結(jié)合,在課外體育活動中經(jīng)常開展小型比賽或匯報展示,以賽促練,以練促學(xué),以學(xué)促教,讓學(xué)生近距離看到自己運動技能的提升,品嘗體育學(xué)習(xí)的快樂,從而自覺主動地參與學(xué)校體育活動,增強(qiáng)體能,培養(yǎng)良好的意志品格。 4)體育課與課外體育活動相結(jié)合的實踐研究的過程也是對體育教師開展教學(xué)能力和專業(yè)業(yè)務(wù)水平培訓(xùn)提升的過程,體育教師參與研究不僅可以促進(jìn)學(xué)生體能的增強(qiáng),而且可以有效提高課堂教學(xué)水平和教學(xué)質(zhì)量,更好地完成體育課的任務(wù)。 申請 2013年因我殘疾人工作其 一、沒有及時的向上級領(lǐng)導(dǎo)如實的反映工作中出現(xiàn)的問題,直接導(dǎo)致云龍鎮(zhèn)的殘疾人工作滯后,千佛村的蔣才剛精神殘疾,來找過我需要辦理殘疾證由于醫(yī)院要見人,由于沒有及時的向上級領(lǐng)導(dǎo)如實的反映又怕麻煩,導(dǎo)致一直沒有得到辦理后來一直找到市殘聯(lián)找到殘聯(lián)理事長劉令,由理事長劉令給我們打電話了鎮(zhèn)上領(lǐng)導(dǎo)才知道,引起了鎮(zhèn)上領(lǐng)導(dǎo)的高度重視由鎮(zhèn)上的領(lǐng)導(dǎo)聯(lián)系了簡陽精神病醫(yī)院為其進(jìn)行治療及精神殘疾的鑒定一切費用由鎮(zhèn)政府承擔(dān)了。其二,沒有及時了解殘疾人的需求情況和向殘疾人做好宣傳工作:石塔2組的李培貴是低保戶多年癱瘓在床,由于沒有向他好宣傳工作。其及他本人不知道殘疾人證是如何辦理導(dǎo)致了一直以為有個老證就行了所以沒有辦理。其三:有疑問的事多向領(lǐng)導(dǎo)匯報了解不能憑感覺辦事,戶口在和豐場的蔣雪婷家在云龍社區(qū),由于感覺她戶口在和豐不是云龍社區(qū)的所以不屬于云龍辦導(dǎo)致去年就能辦理的到現(xiàn)在才辦理。就因為自我的一些問題導(dǎo)致了2013年云龍鎮(zhèn)的殘疾人工作沒有進(jìn)展。直接影響了云龍鎮(zhèn)的殘疾人工作。 2014年一定從現(xiàn)在起立即改進(jìn)及其方法力爭在一個月的時間讓云龍鎮(zhèn)的殘疾人工作趕上去,做到讓云龍的殘疾人證應(yīng)辦盡辦力爭讓云龍的辦證率達(dá)到資陽市的前列,多向五合鄉(xiāng)學(xué)習(xí)五合鄉(xiāng)的殘疾人工作的經(jīng)驗力爭在最短的時間讓云龍的殘疾人工作做起來,讓云龍的殘疾人得到真正的實惠。為更多的殘疾人提供方便。做到平時多掌握殘疾人的實際情況。多宣傳多了解,盡量做到有需求就落實。不讓為殘疾人辦事成為一句空話。 申請人: 2014年4月30日第三篇:計算機(jī)網(wǎng)絡(luò)實踐實驗報告
第四篇:課程實踐
第五篇:實踐課程