日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

蓝桥杯青少年创意编程C++组赛前集训教程包

發(fā)布時(shí)間:2024/1/8 c/c++ 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝桥杯青少年创意编程C++组赛前集训教程包 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1
藍(lán)橋杯青少年創(chuàng)意編程C++組
賽前集訓(xùn)教程包
版本-190919
藍(lán)橋杯大賽組
2
目錄
第01 課基本數(shù)據(jù)類型及運(yùn)算符................................................................................................... 4
1.1、基本數(shù)據(jù)類型及類型轉(zhuǎn)換.............................................................................................. 4
1.2、變量與常量.......................................................................................................................5
1.3、字符與字符串...................................................................................................................6
1.4、運(yùn)算符...............................................................................................................................6
第02 課基本程序結(jié)構(gòu)....................................................................................................................8
2.1、順序結(jié)構(gòu)程序設(shè)計(jì)...........................................................................................................8
2.2、分支結(jié)構(gòu)程序設(shè)計(jì)...........................................................................................................9
2.3、循環(huán)結(jié)構(gòu)程序設(shè)計(jì)........................................................................................................ 12
第03 課數(shù)組................................................................................................................................. 16
3.1、一維數(shù)組及二維數(shù)組.................................................................................................... 16
3.2、數(shù)組的輸入和輸出........................................................................................................ 18
3.3、數(shù)組元素的遍歷............................................................................................................ 20
3.4、數(shù)組元素排序................................................................................................................ 20
3.5、字符數(shù)組........................................................................................................................ 24
第04 課函數(shù)................................................................................................................................. 25
4.1、函數(shù)的定義和使用........................................................................................................ 25
4.2、函數(shù)的遞歸調(diào)用............................................................................................................ 27
3
4.3、變量的作用域:局部變量和全局變量........................................................................27
第05 課簡(jiǎn)單算法......................................................................................................................... 28
5.1、進(jìn)制轉(zhuǎn)換........................................................................................................................ 28
5.2、模擬算法........................................................................................................................ 29
5.3、枚舉算法........................................................................................................................ 31
第06 課基本數(shù)據(jù)結(jié)構(gòu)................................................................................................................. 34
6.1、結(jié)構(gòu)體............................................................................................................................ 34
6.2、棧.................................................................................................................................... 35
6.3、隊(duì)列................................................................................................................................ 38
6.4、樹.................................................................................................................................... 41
6.5、圖.................................................................................................................................... 47
第07 課指針................................................................................................................................. 48
7.1、概念................................................................................................................................ 48
7.2、引用與運(yùn)算.................................................................................................................... 49
7.3、指針與數(shù)組。................................................................................................................ 50
第08 課基本算法......................................................................................................................... 51
8.1、高精度算法.................................................................................................................... 51
8.2、遞推算法........................................................................................................................ 52
8.3、分治算法........................................................................................................................ 52
8.4、貪心算法........................................................................................................................ 53
8.5、搜索算法(寬度優(yōu)先搜索、深度優(yōu)先搜索)............................................................54
8.6、動(dòng)態(tài)規(guī)劃算法................................................................................................................ 55
4
第01 課基本數(shù)據(jù)類型及運(yùn)算符
1.1、基本數(shù)據(jù)類型及類型轉(zhuǎn)換
1. 基本數(shù)據(jù)類型
整型:int、longlong
int 與long long 的存儲(chǔ)范圍不同,一般情況下我們用int 即可,但是如果題目
中給的數(shù)據(jù)范圍較大,則選擇使用long long。
布爾型:bool
布爾類型只有兩個(gè)值,false 和true。通常用來判斷條件是否成立。
字符型:char
char 類型的變量代表的是單個(gè)字符,
例如:
char a;//定義一個(gè)字符型變量
cin>>a;//從鍵盤輸入一個(gè)字符存入變量a 中。
a=‘*’;//給變量a 賦一個(gè)字符’*’。
注意:字符是用單引號(hào)來表示’’。
實(shí)型:float、double
float 與double 的精確度不同,如果題目沒有特別要求,我們一般使用double,
如果題目明確告訴你使用單精度浮點(diǎn)數(shù)數(shù)據(jù)類型或者float,則要使用float。
2. 數(shù)據(jù)類型的轉(zhuǎn)換
5
(1)自動(dòng)類型轉(zhuǎn)換(隱式類型轉(zhuǎn)換)
在不同數(shù)據(jù)類型的混合運(yùn)算中,編譯器會(huì)隱式地進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,稱為自動(dòng)類
型轉(zhuǎn)換。
自動(dòng)類型轉(zhuǎn)換遵循下面的規(guī)則:
①若參與運(yùn)算的數(shù)據(jù)類型不同,則先轉(zhuǎn)換成同一類型,然后進(jìn)行運(yùn)算。
②轉(zhuǎn)換按數(shù)據(jù)長(zhǎng)度增加的方向進(jìn)行,以保證精度不降低。例如int 類型和long
類型運(yùn)算時(shí),先把int 類型轉(zhuǎn)成long 類型后再進(jìn)行運(yùn)算。
③在賦值運(yùn)算中,賦值號(hào)兩邊的數(shù)據(jù)類型不相同時(shí),將把右邊表達(dá)式值的類
型轉(zhuǎn)換為左邊變量的類型。如果右邊表達(dá)式值的數(shù)據(jù)類型長(zhǎng)度比左邊長(zhǎng)時(shí),將丟
失一部分?jǐn)?shù)據(jù)。
④在賦值語句中,賦值號(hào)兩邊數(shù)據(jù)類型一定是相兼容的類型,如果等號(hào)兩邊
數(shù)據(jù)類型不兼容,語句在編譯時(shí)會(huì)報(bào)錯(cuò)。
(2)強(qiáng)制類型轉(zhuǎn)換(顯示類型轉(zhuǎn)換)
自動(dòng)類型轉(zhuǎn)換不能實(shí)現(xiàn)目的時(shí),可以顯式進(jìn)行類型轉(zhuǎn)換,稱為強(qiáng)制類型轉(zhuǎn)換。
一般形式:(數(shù)據(jù)類型)(表達(dá)式)
注意:數(shù)據(jù)類型加小括號(hào)這個(gè)整體才是強(qiáng)制類型轉(zhuǎn)換的符號(hào),后面的表達(dá)式可以
加小括號(hào),也可以不加,如果不加的話則遵循就近原則,誰離得強(qiáng)制類型轉(zhuǎn)換符
號(hào)近,系統(tǒng)則強(qiáng)制類型轉(zhuǎn)換誰。
例:int a;a=(int)1.5;a 的值為1。
1.2、變量與常量
1. 變量
6
變量可以看作是存儲(chǔ)數(shù)據(jù)的小盒子,一個(gè)小盒子里面只能存放一個(gè)具體的值,而
且這個(gè)值可以改變。
例如:inta= 3;a 就是一個(gè)變量
2. 常量
常量是固定值,在程序執(zhí)行期間不會(huì)改變。這些固定的值,又叫做字面量。
常量可以是任何的基本數(shù)據(jù)類型,可分為整型數(shù)字、浮點(diǎn)數(shù)字、字符、字符串和
布爾值。
常量就像是常規(guī)的變量,只不過常量的值在定義后不能進(jìn)行修改。
1.3、字符與字符串
1、字符就是單個(gè)字符,字符串就是多個(gè)字符的集合。
2、單個(gè)空白字符和空白字符串是兩個(gè)概念,在C++中字符就是單個(gè)字符,字符
串是用\0 結(jié)尾的,字符和字符串在操作上也不同,復(fù)制等等是不一樣的。
字符串簡(jiǎn)介:
字符串或串(String)是由數(shù)字、字母、下劃線組成的一串字符。一般記為
s="a1a2···an"(n>=0)。它是編程語言中表示文本的數(shù)據(jù)類型。在程序設(shè)計(jì)中,
字符串(string)為符號(hào)或數(shù)值的一個(gè)連續(xù)序列,如符號(hào)串(一串字符)或二進(jìn)制數(shù)字
串(一串二進(jìn)制數(shù)字)。
1.4、運(yùn)算符
1. 賦值運(yùn)算符
在C++里面,一個(gè)等號(hào)“=”代表的是賦值,賦值運(yùn)算符是將賦值運(yùn)算符右側(cè)
7
的值賦值給左側(cè)的變量。
2. 算術(shù)運(yùn)算符
C++中有5 個(gè)基本的算術(shù)運(yùn)算符:+(加)-(減)、*(乘)、/(除)、%(取余)。
注意:
① 兩個(gè)整數(shù)相除,得到的結(jié)果值保留整數(shù)位
② 取余運(yùn)算符兩邊的數(shù)字必須都得是整數(shù)
3. 邏輯運(yùn)算符
C++中有三個(gè)基本的邏輯運(yùn)算符:&&(與)、||(或)、!(非)
邏輯非:經(jīng)過邏輯非運(yùn)算,其結(jié)果與原來相反。
邏輯與:若參加運(yùn)算的某個(gè)條件不成立,其結(jié)果就不成立,只有當(dāng)參加運(yùn)算的所
有條件都成立,其結(jié)果才成立。
邏輯或:若參加運(yùn)算的某個(gè)條件成立,其結(jié)果就成立,只有當(dāng)參加運(yùn)算的所有條
件都不成立,其結(jié)果才不成立。
4. 關(guān)系運(yùn)算符
C++中有六個(gè)基本的關(guān)系運(yùn)算符:>(大于)、>=(大于等于)、<(小于)、<=
(小于等于)、==(等于)、!=(不等于)
符號(hào)意義舉例
> 大于10>5
>= 大于等于10>=10
< 小于10<5
<= 小于等于10<=10
8
== 等于10==5
!= 不等于10!=5
第02 課基本程序結(jié)構(gòu)
2.1、順序結(jié)構(gòu)程序設(shè)計(jì)
1. 輸入語句:
cin 是C++的輸入語句,與cout 語句一樣,為了敘述方便,常常把由cin 和運(yùn)
算符”>>”實(shí)現(xiàn)輸入的語句稱為輸入語句或cin 語句。
cin 語句的一般格式為:
cin>>變量1>>變量2>>……>>變量n;
與cout 類似,一個(gè)cin 語句可以分寫成若干行,如
cin>>a>>b>>c>>d;
也可以寫成
cin>>a;
cin>>b;
cin>>c;
cin>>d;
以上書寫變量值均可以以從鍵盤輸入:1 2 3 4
也可以分多行輸入數(shù)據(jù):
1
2 3
9
4
2. 輸出語句:
cout 語句一般格式為:
cout<<項(xiàng)目1<<項(xiàng)目2<<…<<項(xiàng)目n;
功能:
(1)如果項(xiàng)目是表達(dá)式,則輸出表達(dá)式的值。
(2)如果項(xiàng)目加引號(hào),則輸出引號(hào)內(nèi)的內(nèi)容。
輸出總結(jié):
cout<<項(xiàng)目1<<項(xiàng)目2<<…<<項(xiàng)目n;
①輸出語句可以輸出多項(xiàng)內(nèi)容,用<<連接;
②如果輸出項(xiàng)目是"2+3",則輸出2+3;
③如果輸出項(xiàng)目是2+3,則輸出5;
④如果輸出遇到endl,則換行。
3. 輸出格式控制:
2.2、分支結(jié)構(gòu)程序設(shè)計(jì)
1. if-else 語句
一般形式:if(表達(dá)式){
語句塊1
}else{
語句塊2
10
}
判斷表達(dá)式的邏輯值,當(dāng)表達(dá)式的值非0,則執(zhí)行語句塊1,當(dāng)表達(dá)式的值為0
的時(shí)候,執(zhí)行語句塊2.
2. switch 語句
switch 語句是多分支選擇語句,也叫開關(guān)語句。switch 語句基本格式及框架圖
如下:
switch(表達(dá)式){
case 常量表達(dá)式1:[語句組1] [break;]
case 常量表達(dá)式2:[語句組2] [break;]
……
case 常量表達(dá)式n:[語句組n] [break;]
[default:語句組n+1]
}
功能:首先計(jì)算表達(dá)式的值,case 后面的常量表達(dá)式值逐一與之匹配,當(dāng)某一
個(gè)case 分支中的常量表達(dá)式值與之匹配時(shí),則執(zhí)行該分支后面的語句組,然后
順序執(zhí)行之后的所有語句,直到遇到break 語句或switch 語句的右括號(hào)“}”為
止。如果switch 語句中包含default,default 表示表達(dá)式與各分支常量表達(dá)式
的值都不匹配時(shí),執(zhí)行其后面的語句組,通常將default 放在最后。
規(guī)則:
(1)合法的switch 語句中的表達(dá)式,其取值只能是整型、字符型、布爾型或者
枚舉型
(2)常量表達(dá)式是由常量組成的表達(dá)式,值的類型與表達(dá)式類型相同。
11
(3)任意兩個(gè)case 后面的常量表達(dá)式值必須各不相同,否則將引起歧義
(4)“語句組”可以使一個(gè)語句也可以是一組語句
(5)基本格式中的[ ]表示可選項(xiàng)
3. 分支語句嵌套
在if 語句中又包含一個(gè)或多個(gè)if 語句稱為if 語句的嵌套。一般形式如下:
if( )
if( )語句1
else 語句2
else
if( )語句3
else 語句4
應(yīng)當(dāng)注意if 與else 的配對(duì)關(guān)系。else 總是與它上面最近的、且未配對(duì)的if 配對(duì)。
假如寫成:
if( )
if( )語句1
else
if( )語句2
else 語句3
編程序者把第一個(gè)else 寫在與第一個(gè)if(外層if)同一列上,希望else 與第一個(gè)
if 對(duì)應(yīng),但實(shí)際上else 是與第二個(gè)if 配對(duì),因?yàn)樗鼈兿嗑嘧罱?#xff0c;而且第二個(gè)if
并未與任何else 配對(duì)。為了避免誤用,最好使每一層內(nèi)嵌的if 語句都包含else
子句(如本節(jié)開頭列出的形式),這樣if 的數(shù)目和else 的數(shù)目相同,從內(nèi)層到外
12
層一一對(duì)應(yīng),不致出錯(cuò)。
如果if 與else 的數(shù)目不一樣,為實(shí)現(xiàn)程序設(shè)計(jì)者的企圖,可以加花括號(hào)來確定
配對(duì)關(guān)系。例如:
if( )
{
if ( ) 語句1
} //這個(gè)語句是上一行if 語句的內(nèi)嵌if
else 語句2//本行與第一個(gè)if 配對(duì)
這時(shí){ }限定了內(nèi)嵌if 語句的范圍,{ }外的else 不會(huì)與{ }內(nèi)的if 配對(duì)。關(guān)系清楚,
不易出錯(cuò)。
2.3、循環(huán)結(jié)構(gòu)程序設(shè)計(jì)
1. while 語句
while 死循環(huán)結(jié)構(gòu):
(1)格式:
while(1) {
循環(huán)語句;
}
(2)功能
不斷地執(zhí)行循環(huán)體中的語句。
代碼有兩部分:
(1)while(1)
13
(2)花括號(hào){ 循環(huán)語句; }
while(表達(dá)式)語句的格式與功能
(1)格式
格式1:
while(表達(dá)式)
語句;
格式2:
while(表達(dá)式){
語句1;
語句2;
……
}
(2)功能
當(dāng)表達(dá)式的值非0 時(shí),不斷地執(zhí)行循環(huán)體中的語句。所以,用while 語句實(shí)現(xiàn)的
循環(huán)被稱為“當(dāng)型循環(huán)”。
2. for 語句
for 循環(huán)格式
格式1:
for(循環(huán)變量初始化;循環(huán)條件;循環(huán)變量增量)
語句;
格式2:
for(循環(huán)變量初始化;循環(huán)條件;循環(huán)變量增量) {
14
語句1;
語句2;
……
}
3. do-while 語句
do{
語句;
}while(表達(dá)式);
do-while 循環(huán)與while 循環(huán)的不同在于:它先執(zhí)行循環(huán)中的語句,然后再判斷
表達(dá)式是否為真;如果為真則繼續(xù)循環(huán),如果為假,則終止循環(huán)。因此,do-while
循環(huán)至少要執(zhí)行一次循環(huán)語句。
4、循環(huán)結(jié)構(gòu)嵌套
循環(huán)的嵌套:
(1)一個(gè)循環(huán)體內(nèi)包含著另一個(gè)完整的循環(huán)結(jié)構(gòu),就稱為嵌套循環(huán)。
(2)內(nèi)嵌的循環(huán)又可以嵌套循環(huán),從而構(gòu)成多重循環(huán)。
(3)三種循環(huán)可以相互嵌套。下面都是合法的嵌套。
①while() ②do ③for( ; ;)
{ … { …
{ …
while() do
for( ; ; )
{….. {…
15
{ …
} }while(); }
… ...

} }while();
}
④while() ⑤do
⑥for( ; ; )
{ … { …
{ …
do for( ; ;)
while()
{….. {…
{ …
}while(); } }
… ...

} }while();
}
注意:
①嵌套的循環(huán)控制變量不應(yīng)同名,以免造成混亂。
②內(nèi)循環(huán)變化快,外循環(huán)變化慢。
16
③正確確定循環(huán)體。
④循環(huán)控制變量與求解的問題掛鉤。
5. break 語句
break 語句的格式和用法
(1)格式
break;
(2)功能
中斷所在循環(huán)體,跳出本層循環(huán)。
第03 課數(shù)組
3.1、一維數(shù)組及二維數(shù)組
1. 一維數(shù)組
申請(qǐng)10 個(gè)整數(shù)數(shù)據(jù)類型的變量可以這么寫:int a[10];
int a[10];這行語句代表同時(shí)定義了10 個(gè)整型變量,就如同10 個(gè)“小房子”并
排放在了一起。
那么我們?nèi)绾问褂眠@些變量呢?
首先,[ ]里的數(shù)字表示需要定義的變量的個(gè)數(shù),我們這里定義了10 個(gè)。這10
個(gè)變量分別用a[0]、a[1]、a[2]、a[3]、a[4]、a[5]、a[6]、a[7]、a[8]、a[9]來
表示。
注意:我們要表達(dá)數(shù)組中某一個(gè)元素的格式是:數(shù)組名[下標(biāo)]。在C++中,下標(biāo)
是從0 開始的,所以一個(gè)大小為n 的數(shù)組,它的有效下標(biāo)是0~n-1。
17
0 是下標(biāo),a[0]用來存值
數(shù)組:由具有相同數(shù)據(jù)類型的固定數(shù)量的元素組成的結(jié)構(gòu)。
例如:int a[10];
double b[10], c[5];
注意:數(shù)組定義時(shí)的一個(gè)關(guān)鍵點(diǎn)是數(shù)組的長(zhǎng)度如何選擇。
數(shù)組元素的引用:
(1)下標(biāo)可以是整型常量或整型表達(dá)式;
a[3]=3;
或: int i=3;
a[i]=3;
(2)下標(biāo)在0~4 之內(nèi), 即a[0]~a[4],
注意:下標(biāo)不要超范圍
(3)可以單獨(dú)針對(duì)每個(gè)元素賦值,
如:a[4] = 5;
也可以這么用:
int i = 4;
a[i] = 5;
(4)每個(gè)元素都是一個(gè)變量,數(shù)組是“一組變量”,而不是一個(gè)變量。
2. 二維數(shù)組
二維數(shù)組定義的一般格式:
類型名數(shù)組名[常量表達(dá)式1][常量表達(dá)式2];
通常二維數(shù)組中的第一維表示行下標(biāo),第二維表示列下標(biāo)。
18
行下標(biāo)和列下標(biāo)都是從0 開始的。例如:
int num[4][6];
二維數(shù)組的使用與一維數(shù)組類似,引用的格式為:
數(shù)組名[下標(biāo)1][下標(biāo)2]
使用數(shù)組時(shí)特別注意下標(biāo)不能越界。
使用二維數(shù)組時(shí),需要區(qū)分是處理行數(shù)據(jù)、列數(shù)據(jù),還是處理所有數(shù)據(jù)的行列下
標(biāo)。
遍歷一個(gè)二維數(shù)組要使用二重循環(huán)。
3.2、數(shù)組的輸入和輸出
1. 一維數(shù)組的輸入輸出。
利用一層for 循環(huán)實(shí)現(xiàn)控制下標(biāo)的變化從而實(shí)現(xiàn)對(duì)一維數(shù)組元素的輸入以及輸
出。
例如:for(int i=0; i<5; ++i){
cin>> a[i];
}
利用循環(huán)實(shí)現(xiàn)了對(duì)一維數(shù)組元素的輸入。
2. 二維數(shù)組的輸入輸出
二維數(shù)組的輸入方式有兩種:
(1)按行輸入:
輸入n 行m 列數(shù)據(jù)(n、m 均小于100):
int n, m, a[105][105];
19
cin>> n >> m;
for(int i=1; i<=n; i++){ //行數(shù)變化
for(int j=1; j<=m; j++){ //列數(shù)變化
cin>> a[i][ j]; //按行輸入
}
}
(2)按列輸入:
輸入n 行m 列數(shù)據(jù)(n、m 均小于100) :
int n, m;
cin>> n >> m;
for(int j=1; j<=m; j++){ //列數(shù)變化
for(int i=1; i<=n; i++){ //行數(shù)變化
cin>> a[i][ j]; //按列輸入
}
}
二維數(shù)組的輸出我們只需要掌握住按行輸出即可:
for(int i=1;i<=n;i++){//控制行數(shù)
for(int j=1;j<=m;j++){
cout<<a[i][ j]<<" ";
}
cout<<endl;
}
20
3.3、數(shù)組元素的遍歷
1. 一維數(shù)組的遍歷
將存放在一維數(shù)組中的元素依次查看一遍并尋找符合條件的數(shù)的過程就是對(duì)一
維數(shù)組的遍歷。
2. 二維數(shù)組的遍歷
二維數(shù)組遍歷和一維數(shù)組遍歷類似,只不過在遍歷到一維元素時(shí),由于元素是一
維數(shù)組還需要遍歷,構(gòu)成雙重循環(huán)。使用雙重循環(huán)遍歷二維數(shù)組時(shí),外層循環(huán)的
次數(shù)使用數(shù)組元素的行數(shù)來進(jìn)行控制,內(nèi)層循環(huán)的次數(shù)是使用每個(gè)一維數(shù)組的元
素的,也就是二維數(shù)組的列數(shù)來進(jìn)行控制。
3.4、數(shù)組元素排序
1. 選擇排序
選擇排序:是一種簡(jiǎn)單直觀的排序算法。它的工作原理是每一次從待排序的數(shù)據(jù)
元素中選出最小(或最大)的一個(gè)元素,存放在序列的起始位置,然后,再從剩
余未排序元素中繼續(xù)尋找最小(大)元素,然后放到已排序序列的末尾。以此類
推,直到全部待排序的數(shù)據(jù)元素排完。
例如,6 個(gè)數(shù)按照從小到大排序:
#include <iostream>
using namespace std;
int main( ) {
int a[6] , i , j , t;
for ( i=0 ; i<6 ; i++)
21
cin>> a[i];
for ( i=0 ; i<5; i++)
for ( j=i+1 ; j<6; j++)
if ( a[i]>a[ j] ) {
t=a[i] ;
a[i]=a[j] ;
a[j]=t ;
}
for ( i=0 ; i<6 ; i++)
cout<< a[i] << " ";
return 0;
}
可推廣到n 個(gè)數(shù)的選擇排序
2. 冒泡
冒泡排序是一種計(jì)算機(jī)科學(xué)領(lǐng)域的較簡(jiǎn)單的排序算法。它重復(fù)地走訪過要排序的
元素列,依次比較兩個(gè)相鄰的元素,如果他們的順序錯(cuò)誤就把他們交換過來。走
訪元素的工作是重復(fù)地進(jìn)行直到?jīng)]有相鄰元素需要交換,也就是說該元素已經(jīng)排
序完成。
這個(gè)算法的名字由來是因?yàn)樵酱?#xff08;小)的元素會(huì)經(jīng)由交換慢慢“浮”到數(shù)列的頂
端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會(huì)上浮到頂端一
樣,故名“冒泡排序”。
例如:5 個(gè)數(shù)按照從小到大排序:
22
#include <iostream>
using namespace std;
int main( ) {
int a[5] , i , j , t;
for ( i=0 ; i<5 ; i++)
cin>> a[i];
for ( i=0 ; i<4 ; i++)//比較了四輪
for ( j=0 ; j<4 ; j++)//每輪需要四次比較
if ( a[j]>a[j+1] ) {
t=a[ j] ;
a[j]=a[ j+1] ;
a[j+1]=t ;
}
for ( i=0 ; i!=5 ; i++)
cout<< a[i] << " ";
return 0;
}
可推廣到n 個(gè)數(shù)的冒泡排序。
3. 桶排序
現(xiàn)在如果需要將輸入的5 個(gè)數(shù)(范圍是0~9)從小到大排序,該怎么辦
例如輸入2 5 2 1 8,則輸出1 2 2 5 8。首先我們先申請(qǐng)一個(gè)大小為10 的數(shù)組,int
a[10],編號(hào)為a[0]~[9],并初始化為0。
23
我們現(xiàn)在只需將“小房間的值加1”就可以了,例如:2 出現(xiàn)了,就將a[2]的
值加1。
實(shí)現(xiàn)過程:
#include<iostream>
using namespace std;
int main(){
int i,j,t, a[10]={0}; //數(shù)組初始化為0
for(i=1;i<=5;i++){ //循環(huán)讀入5 個(gè)數(shù)
cin>>t; //把每一個(gè)數(shù)讀到變量t 中
a[t]++; // t 所對(duì)應(yīng)小房子中的值增加1
}
for(i=0;i<=9;i++){ //依次判斷0~9 這個(gè)10 個(gè)小房子
for(j=1;j<=a[i];j++) //出現(xiàn)了幾次就打印幾次
cout<<i<<‘‘;
}
return 0;
}
這種形式的排序就是桶排序,桶排序是要借助于數(shù)組來實(shí)現(xiàn)的,我們將每個(gè)數(shù)組
元素看作一個(gè)桶,每出現(xiàn)一個(gè)數(shù),就在對(duì)應(yīng)編號(hào)的桶里面放一個(gè)小旗子,最后只
要數(shù)一數(shù)每個(gè)桶里面有幾個(gè)小旗子就OK 了。
24
3.5、字符數(shù)組
1. 一維字符數(shù)組
我們將char 類型定義的數(shù)組叫做字符數(shù)組,也可以叫它字符串。
字符數(shù)組的定義格式如下:char 數(shù)組名[元素個(gè)數(shù)];
cin 和scanf 輸入方式是沒法讀入空格,回車,tab 的,如果我們的字符串中需
要空格,可以用gets()來讀入一行字符串
例如:
char a[10];
gets(a);
cout<<a;
注意:gets()函數(shù)可以保留空格,遇到回車結(jié)束,需要一個(gè)頭文件<cstdio>
字符數(shù)組初始化的兩種方式:
char a[10];
(1)char a[10]={‘c’,’o’,’d’。,’u’,’c’,’k’};//一些單個(gè)字符
(2)char a[10]={“coduck"}; //一個(gè)字符串
輸入:
char a[10];
(1)無空格的字符串輸入:
1.利用循環(huán)輸入:
for(int i=0;i<=9;i++){
cin>>a[i]; //輸入固定長(zhǎng)度為10 的字符數(shù)組。
25
}
2.直接cin;
cin>>a; //可以輸入小于等于10 的字符數(shù)組
有空格的字符串輸入:
1.gets(a); //gets 函數(shù)可以保留空格,遇到回車結(jié)束!加頭文件<cstdio>
說明:遇到?jīng)]有空格的字符串,可以用cin>>數(shù)組名;來輸入。遇到有空格的字
符串,可以用gets(數(shù)組名);來輸入
輸出:
cout<<a;
說明:cout 輸出遇到‘\0’結(jié)束。
2. 二維字符數(shù)組
我們可以借助一個(gè)二維數(shù)組來存儲(chǔ)多個(gè)字符串,這個(gè)二維字符數(shù)組的每一行都是
一個(gè)單獨(dú)的字符串。
第04 課函數(shù)
4.1、函數(shù)的定義和使用
函數(shù)定義
前面我們用過了很多C++標(biāo)準(zhǔn)函數(shù),但是這些標(biāo)準(zhǔn)函數(shù)并不能滿足所有
需求。當(dāng)我們需要特定的功能函數(shù)時(shí),這就需要我們要學(xué)會(huì)自定義函數(shù),根據(jù)需
求定制想要的功能。
函數(shù)定義的語法:
26
返回類型函數(shù)名(參數(shù)列表)
{
函數(shù)體
}
關(guān)于函數(shù)定義的幾點(diǎn)說明:
(1)自定義函數(shù)符合“根據(jù)已知計(jì)算未知”這一機(jī)制,參數(shù)列表相當(dāng)于已知,
是自變量,函數(shù)名相當(dāng)于未知,是因變量。如1.1 參考代2 中max 函數(shù)的功能
是找出兩個(gè)數(shù)的最大數(shù),參數(shù)列表中x 相當(dāng)于已知——自變量,max 函數(shù)的值
相當(dāng)于未知——因變量。
(2)函數(shù)名是標(biāo)識(shí)符,一個(gè)程序中除了主函數(shù)名必須為main 外,其余函數(shù)的
名字按照標(biāo)識(shí)符的取名規(guī)則命名。
(3)參數(shù)列表可以是空的,即無參函數(shù),也可以有多個(gè)參數(shù),參數(shù)之間用逗號(hào)
隔開,不管有沒有參數(shù),函數(shù)名后的括號(hào)不能省略。參數(shù)列表中的每個(gè)參數(shù),由
參數(shù)類型說明和參數(shù)名組成。如max 函數(shù)的參數(shù)列表數(shù)有兩個(gè)參數(shù),兩個(gè)參數(shù)
類型分別是int,int,兩個(gè)參數(shù)名分別是a,b。
(4)函數(shù)體是實(shí)現(xiàn)函數(shù)功能的語句,除了返回類型是void 的函數(shù),其他函數(shù)
的函數(shù)體中至少有一條語句是“return 表達(dá)式;”用來返回函數(shù)的值。執(zhí)行函
數(shù)過程中碰到return 語句,將在執(zhí)行完return 語句后直接退出函數(shù),不去執(zhí)行
后面的語句。
(5)返回值的類型一般是前面介紹過的int、double、char 等類型,也可以是
數(shù)組。有時(shí)函數(shù)不需要返回任何值,例如函數(shù)可以只描述一些過程用printf 向
屏幕輸出一些內(nèi)容,這時(shí)只需定義的數(shù)返回類型為void,并且無須使用return
27
返回函數(shù)的值。
函數(shù)使用時(shí),函數(shù)名必須與函數(shù)定義時(shí)完全一致,實(shí)參與形參個(gè)數(shù)相等,類型一
致,按順序一一對(duì)應(yīng)。被調(diào)用函數(shù)必須是已存在的函數(shù),如果調(diào)用庫函數(shù),一定
要包含相對(duì)應(yīng)的頭文件。
4.2、函數(shù)的遞歸調(diào)用
函數(shù)之間有三種調(diào)用關(guān)系:主函數(shù)調(diào)用其他函數(shù)、其他函數(shù)互相調(diào)用、函數(shù)遞歸
調(diào)用
C++程序從主函數(shù)開始執(zhí)行,主函數(shù)由操作系統(tǒng)調(diào)用,主函數(shù)可以調(diào)用其他函
數(shù),其他函數(shù)之間可以互相調(diào)用,但不能調(diào)用主函數(shù),所有函數(shù)是平行的,可以
嵌套調(diào)用,但不能嵌套定義。
4.3、變量的作用域:局部變量和全局變量
作用域描述了名稱在文件的多大范圍內(nèi)可見可使用。C++程序中的變量按作用
域來分,有全局變量和局部變量
全局變量:定義在函數(shù)外部沒有被花括號(hào)括起來的變量稱為全局變量。
全局變量的作用域是從變量定義的位置開始到文件結(jié)束。由于全局變量是在函數(shù)
外部定義的,因此對(duì)所有函數(shù)而言都是外部的,可以在文件中位于全局變量定義
后面的任何函數(shù)中使用。
局部變量:定義在函數(shù)內(nèi)部作用域?yàn)榫植康淖兞烤植孔兞俊:瘮?shù)的形參
和在該函數(shù)里定義的變量都被稱為該函數(shù)的局部變量。
注意:全局變量和局部變量都有生命周期,變量從被生成到被撤銷的這
28
段時(shí)間就稱為變量的生存期, 實(shí)際上就是變量占用內(nèi)存的時(shí)間。局部變量的生命
周期是從函數(shù)被調(diào)用的時(shí)刻開始到函數(shù)結(jié)束返回主函數(shù)時(shí)結(jié)束。而全局變量的生
命周期與程序的生命周期是一樣的。若程序中全局變量與局部變量同名,且同時(shí)
有效,則以局部變量?jī)?yōu)先。即在局部變量的作用范圍內(nèi),全局變量不起作用。
第05 課簡(jiǎn)單算法
5.1、進(jìn)制轉(zhuǎn)換
1、r 進(jìn)制數(shù)(非十進(jìn)制數(shù))轉(zhuǎn)化成十進(jìn)制數(shù):
各種進(jìn)位制轉(zhuǎn)換為十進(jìn)制的方法:分別寫出二進(jìn)制數(shù)、八進(jìn)制數(shù)和十六
進(jìn)制數(shù)的按權(quán)展開式,再按十進(jìn)制運(yùn)算規(guī)則求和得到的值,即為轉(zhuǎn)換后的十進(jìn)制
數(shù)。
2、十進(jìn)制數(shù)轉(zhuǎn)化成r 進(jìn)制數(shù):
分整數(shù)和小數(shù)兩部分分別轉(zhuǎn)換處理,最后再求和。
整數(shù)部分的轉(zhuǎn)換方法是:不斷的除以r 取余數(shù),直到商為0,余數(shù)從下
到上排列(除r 取余,逆序排列);小數(shù)部分的轉(zhuǎn)換方法是:不斷乘以r 取整數(shù),
整數(shù)從上到下排列(乘r 取整,順序排列)。
3、二進(jìn)制、八進(jìn)制、十六進(jìn)制數(shù)間的轉(zhuǎn)換:
二進(jìn)制、八進(jìn)制、十六進(jìn)制之間的對(duì)應(yīng)規(guī)則如下:每3 位二進(jìn)制對(duì)應(yīng)1
位八進(jìn)制數(shù);每4 位二進(jìn)制對(duì)應(yīng)1 位十六進(jìn)制數(shù)。
(1)二進(jìn)制轉(zhuǎn)化成八(十六)進(jìn)制:分為如下三個(gè)步驟
整數(shù)部分:小數(shù)點(diǎn)為基準(zhǔn)從右向左按三(四)位進(jìn)行分組
29
小數(shù)部分:小數(shù)點(diǎn)為基準(zhǔn)從左向右按三(四)位進(jìn)行分組
不足補(bǔ)零
(2)八(十六)進(jìn)制轉(zhuǎn)換為二進(jìn)制
八進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù):只需將1 位八進(jìn)制數(shù)轉(zhuǎn)為3 位二進(jìn)制數(shù)。
十六進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制數(shù):只需將1 位十六進(jìn)制數(shù)轉(zhuǎn)為4 位二進(jìn)制數(shù)。
5.2、模擬算法
在我們所解決的題目中,有一類問題是模擬一個(gè)游戲的對(duì)弈過程,或者模擬一項(xiàng)
任務(wù)的操作過程,進(jìn)行統(tǒng)計(jì)計(jì)分,判斷輸贏等。這些問題很難建立數(shù)學(xué)模型用特
定算法解決,一般只能采用“模擬”法。用模擬法解決必須關(guān)注以下幾個(gè)問題:
審題要仔細(xì),游戲規(guī)則不能錯(cuò);分析要全面,各種特例不能丟;編程要細(xì)心,測(cè)
試運(yùn)行要到位。
例如:
有一天,一只蚱蜢像往常一樣在草地上愉快地跳躍,它發(fā)現(xiàn)了一條寫滿了英文字
母的紙帶。蚱蜢只能在元音字母(A、E、I、O、U)間跳躍,一次跳躍所需的能
力是兩個(gè)位置的差。紙帶所需的能力值為蚱蜢從紙帶開頭的前一位置根據(jù)規(guī)則調(diào)
到紙帶結(jié)尾的后一個(gè)位置的過程中能力的最大值。
蚱蜢想知道跳躍紙帶所需能力值(最小)是多少。如下圖所示,紙帶所需能
力值(最小)是4.
【輸入格式】
30
一行一個(gè)字符串,字符串場(chǎng)不超過100.
【輸出格式】
一行一個(gè)整數(shù),代表(最小)能力值。
【輸入樣例】
KMLPTGFHNBVCDRFGHNMBVXWSQFDCVBNHTJKLPMNFVCKMLPTGFH
NBVCDRFGHNMBVXWSQFDCVBNHTJKLPMNFVC
【輸出樣例】
85
【問題分析】
從頭到尾枚舉紙帶的每一個(gè)字母,按照規(guī)則模擬蚱蜢在元音字母間跳躍的過程,
打擂臺(tái)記錄能力值。
【示例代碼】
#include<bits/stdc++.h>
using namespace std;
int main(){
freopen("grasshopper.in","r",stdin);
freopen("grasshopper.out","w",stdout);
string a;
cin>>a;
int ans=0,pre=0;
for(int i=0;i<a.length();i++){
if(a[i]=='A'||a[i]=='E'||a[i]=='I'||a[i]=='O'||a[i]=='U'||a[i]=='Y'){
31
if(ans<=(i+1-pre)){
ans=i+1-pre;
}
pre=i+1;
}
}
if(ans<=a.length()+1-pre){
ans=a.length()+1-pre;
}
cout<<ans<<endl;
return 0;
}
5.3、枚舉算法
計(jì)算機(jī)的特點(diǎn)之一就是運(yùn)算速度快,善于重復(fù)做一件事。“窮舉”正是基于這一
特點(diǎn)的最古老的算法。它一般是在一時(shí)找不出解決問題的更好途徑,即從數(shù)學(xué)上
找不到求解的公式或規(guī)則時(shí),根據(jù)問題中的“約束條件”,將解的所有可能情況
一一列舉出來,然后再逐個(gè)驗(yàn)證是否符合整個(gè)問題的求解要求,從而求得問題的
可行解或者最優(yōu)解。
例題:火柴棒等式
【問題描述】
給出n 根火柴棒,可以拼出多少個(gè)形如“A+B=C”的等式?
32
等式中的A、B、C 是用火柴棒拼出的整數(shù)(若該數(shù)非零,則最高位不能是0)。
用火柴棒拼數(shù)字0~9 的拼法如下圖所示。
需要注意以下幾點(diǎn):
(1) 加號(hào)與等號(hào)各自需要兩根火柴棒。
(2) 如果A ≠ B,則A+B=C 與B+A=C 視為不同的等式(A、B、C 均大
于或等于0)。
(3) n 根火柴棒必須全部用上(n≤24)。
【輸入樣例】
14
【輸出樣例】
2
【樣例說明】
兩個(gè)等式分別為:0+1=1 和1+0=1。
【問題分析】
首先,預(yù)處理每個(gè)數(shù)字(0~9)需要用幾根火柴棒,存儲(chǔ)在數(shù)組f 中。然后,
窮舉a 和b,算出它們的和c,再判斷下列約束條件是否成立:f (a)+ f (b)
+ f (c)= n-4。現(xiàn)在的問題是:a 和b 的范圍有多大?可以發(fā)現(xiàn)盡量用數(shù)字
1 拼成的數(shù)比較大,分析可知最多不會(huì)超過1111。程序?qū)崿F(xiàn)時(shí),分別用三個(gè)循
環(huán)語句預(yù)處理好所有兩位數(shù)、三位數(shù)、四位數(shù)構(gòu)成所需要的火柴棒數(shù)量。
【示例代碼】
#include<bits/stdc++.h>
33
using namespace std;
int f[10000];
int main(){
freopen("matches.in","r",stdin);
freopen("matches.out","w",stdout);
f[0]=6;f[1]=2;f[2]=5;f[3]=5;f[4]=4;
f[5]=5;f[6]=6;f[7]=3;f[8]=7;f[9]=6;
for(int i=10;i<=99;++i){
f[i]=f[i/10]+f[i%10];
}
for(int i=100;i<=999;++i){
f[i]=f[i/100]+f[i/10%10]+f[i%10];
}
for(int i=1000;i<=9999;++i){
f[i]=f[i/1000]+f[i/100%10]+f[i/10%10]+f[i%10];
}
int n,total=0;
cin>>n;
for(int a=0;a<=1111;++a){
for(int b=0;b<=1111;++b){
int c=a+b;
if(f[a]+f[b]+f[c]==n-4){
34
total++;
}
}
}
cout<<total<<endl;
return 0;
}
第06 課基本數(shù)據(jù)結(jié)構(gòu)
6.1、結(jié)構(gòu)體
1、結(jié)構(gòu)體的定義:
在存儲(chǔ)和處理大批量數(shù)據(jù)時(shí),一般會(huì)使用數(shù)組來實(shí)現(xiàn),但是每一個(gè)數(shù)據(jù)
的類型及含義必須一樣。如果需要把不同類型、不同含義的數(shù)據(jù)當(dāng)作一個(gè)整體來
處理,比如1000 個(gè)學(xué)生的姓名、性別、年齡、體重、成績(jī)等,怎么辦?C++
提供了結(jié)構(gòu)體。
C++中的結(jié)構(gòu)體是由一系列具有相同類型或不同數(shù)據(jù)類型的數(shù)據(jù)構(gòu)成的數(shù)
據(jù)集合。使用結(jié)構(gòu)體,必須要先聲明一個(gè)結(jié)構(gòu)體類型,再定義和使用結(jié)構(gòu)體變量。
結(jié)構(gòu)體類型的聲明格式如下:
struct 類型名{
數(shù)據(jù)類型1 成員名1;
數(shù)據(jù)類型2 成員名2;
35

};
也可以把結(jié)構(gòu)體類型聲明和變量定義在一起,格式如下:
struct 類型名{
數(shù)據(jù)類型1 成員名1;
數(shù)據(jù)類型2 成員名2;

}變量名;
2、結(jié)構(gòu)體變量的使用:
結(jié)構(gòu)體變量具有以下特點(diǎn):
(1)可以對(duì)結(jié)構(gòu)體變量的整體進(jìn)行操作。例如,swap(a[i],a[ j])。
(2)可以對(duì)結(jié)構(gòu)體變量的成員進(jìn)行操作。
引用結(jié)構(gòu)體變量中的成員的格式為:結(jié)構(gòu)體變量名.成員名
(3)結(jié)構(gòu)體變量的初始化方法與數(shù)組類似。
student s={"xiaomming",'f',16,169};
6.2、棧
1、棧的基本概念:
棧(Stack)是限制在表的一端進(jìn)行插入和刪除操作的線性表
后進(jìn)先出LIFO(Last In First Out)
先進(jìn)后出FILO(First In Last Out)
棧頂(Top):允許進(jìn)行插入、刪除操作的一端,又陳偉表尾。用棧頂指針(top)
36
來指示棧頂元素。
空棧:當(dāng)表中沒有元素時(shí)稱為空棧。
2、棧的順序表示與實(shí)現(xiàn):
棧的順序存儲(chǔ)結(jié)構(gòu)簡(jiǎn)稱為順序棧,和線性表類似,用一維數(shù)組來存儲(chǔ)棧。
3、棧的應(yīng)用
(1)括號(hào)匹配檢查
【題目描述】
假設(shè)表達(dá)式中允許包含圓括號(hào)和方括號(hào)兩種括號(hào),其嵌套的順序隨意,如([]())
或[([][])]等為正確的匹配,[(])或([]()或(()))均為錯(cuò)誤的匹配。本題的任務(wù)是檢驗(yàn)
一個(gè)給定的表達(dá)式中的括號(hào)是否匹配正確。
輸入一個(gè)只包含圓括號(hào)和方括號(hào)的字符串,判斷字符串中的括號(hào)是否匹配,
匹配就輸出“OK”,不匹配就輸出“Wrong”。
【輸入】
一行字符,只含有圓括號(hào)和方括號(hào),個(gè)數(shù)小于255
【輸出】
匹配就輸出一行文本“OK“,不匹配就輸出一行文本”Wrong”
【樣例輸入】
[(])
【樣例輸出】
Wrong
【解決思路】
使用棧來實(shí)現(xiàn),首先輸入字符串,遍歷字符串:
37
如果是左括號(hào),進(jìn)棧;
如果是右括號(hào),跟棧頂數(shù)據(jù)比較
如果和棧頂?shù)淖罄ㄌ?hào)匹配,出棧
如果不匹配,輸出“Wrong"
遍歷結(jié)束后,棧中還有括號(hào),輸出“Wrong”;沒有,輸出“Ok”
【代碼示例】
#include<iostream>
#include<string>
using namespace std;
int main()
{
char a[256];
string s;
int i,top;
cin>>s;
top=0;
for(i=0;i<s.size();i++)
{
if(s[i]=='('||s[i]=='[')
{
a[++top]=s[i];;
}
38
if(s[i]==')')
{
if(a[top]=='(') top--;
else
{ top++; }
}
if(s[i]==']')
{
if(a[top]=='[') top--;
else
{ top++; }
}
}
if(top==0) cout<<"OK"<<endl;
else cout<<"Wrong"<<endl;
return 0;
}
(2)鐵軌問題
6.3、隊(duì)列
1、隊(duì)列定義
隊(duì)列是一種先進(jìn)先出(FIFO)的線性表。只能在線性表的一端進(jìn)行插入操作,
39
在另一端進(jìn)行刪除操作。類似與生活中的排隊(duì)購票,先來先買,后來后買。
在不斷入隊(duì)、出隊(duì)的過程中,隊(duì)列將會(huì)呈現(xiàn)初以下幾種狀態(tài):
隊(duì)滿:隊(duì)列空間已被全被占用
隊(duì)空:隊(duì)列中沒有任何元素。
溢出:當(dāng)隊(duì)列滿時(shí),卻還有元素要入隊(duì),就會(huì)出現(xiàn)“上溢”;當(dāng)隊(duì)列已
空,卻還要做“出隊(duì)”操作,就會(huì)出現(xiàn)“下溢”。兩種情況合在一起稱為隊(duì)列的
“溢出”。
2、隊(duì)列的應(yīng)用
【題目描述】
假設(shè)在周末舞會(huì)上,男士們和女士們進(jìn)入舞廳時(shí),各自排成一隊(duì)。跳舞開始時(shí),
依次從男隊(duì)和女隊(duì)的隊(duì)頭上各出一人配成舞伴。規(guī)定每個(gè)舞曲能有一對(duì)跳舞者。
若兩隊(duì)初始人數(shù)不相同,則較長(zhǎng)的那一隊(duì)中未配對(duì)者等待下一輪舞曲。現(xiàn)要求寫
一個(gè)程序,模擬上述舞伴配對(duì)問題。(0<m,n,k<1000)
【輸入】
第一行男士人數(shù)m 和女士人數(shù)n;
第二行舞曲的數(shù)目k。
【輸出】
共k 行,每行兩個(gè)數(shù),表示配對(duì)舞伴的序號(hào),男士在前,女士在后。
【樣例輸入】
2 4
6
40
【樣例輸出】
1 1
2 2
1 3
2 4
1 1
2 2
【解題思路】
顯然,舞伴配對(duì)的順序符合“先進(jìn)先出”,所以用兩個(gè)隊(duì)列分別存放男士隊(duì)伍和
女士隊(duì)伍,然后模擬k 次配對(duì):每次取各隊(duì)隊(duì)頭元素“配對(duì)”輸出,并進(jìn)行“出
隊(duì)”和重新“入隊(duì)”的操作。
【代碼示例】
#include<iostream>
using namespace std;
int main(){
int a[10001],b[10001],f1=1,f2=1,r1,r2,k1=1;
int m,n,k;
cin>>m>>n>>k;
r1=m;r2=n;
for(int i=1;i<=m;i++) a[i]=i;
for(int j=1;j<=n;j++) b[j]=j;
while(k1<=k){
41
cout<<a[f1]<<" "<<b[f1]<<endl;
r1++;a[r1]=a[f1];f1++;
r2++;b[r2]=b[f2];f2++;
k1++;
}
return 0;
}
6.4、樹
1、樹
(1)樹的定義
樹(Tree)是n( n≥0 )個(gè)結(jié)點(diǎn)的有限集,它或?yàn)榭諛? n=0) ;或?yàn)榉强諛?對(duì)于非空樹
T:
有且僅有一個(gè)稱之為根的結(jié)點(diǎn);
除根結(jié)點(diǎn)以外的其余結(jié)點(diǎn)可分為m(m> 0)個(gè)互不相交的有限集T1,T2, ...Tm,
其中每一個(gè)集合本身又是一棵樹,并且稱為根的子樹( SubTree )。
(2)基本術(shù)語
根——即根結(jié)點(diǎn)(沒有前驅(qū))
葉子——即終端結(jié)點(diǎn)(沒有后繼)
森林——指m 棵不相交的樹的集合(例如刪除A 后的子樹個(gè)數(shù))
有序樹——結(jié)點(diǎn)各子樹從左至右有序,不能互換(左為第一)
無序樹——結(jié)點(diǎn)各子樹可互換位置。
42
雙親——即上層的那個(gè)結(jié)點(diǎn)(直接前驅(qū))
孩子——即下層結(jié)點(diǎn)的子樹的根(直接后繼)
兄弟——同一雙親下的同層結(jié)點(diǎn)(孩子之間互稱兄弟)
堂兄弟——即雙親位于同一層的結(jié)點(diǎn)(但并非同一雙親)
祖先——即從根到該結(jié)點(diǎn)所經(jīng)分支的所有結(jié)點(diǎn)
子孫——即該結(jié)點(diǎn)下層子樹中的任一結(jié)點(diǎn)
結(jié)點(diǎn)——即樹的數(shù)據(jù)元素
結(jié)點(diǎn)的度——結(jié)點(diǎn)掛接的子樹數(shù)
結(jié)點(diǎn)的層次——從根到該結(jié)點(diǎn)的層數(shù)(根結(jié)點(diǎn)算第一層)
終端結(jié)點(diǎn)——即度為0 的結(jié)點(diǎn),即葉子
分支結(jié)點(diǎn)——即度不為0 的結(jié)點(diǎn)(也稱為內(nèi)部結(jié)點(diǎn))
樹的度——所有結(jié)點(diǎn)度中的最大值
樹的深度——指所有結(jié)點(diǎn)中最大的層數(shù)
(3)樹的存儲(chǔ)結(jié)構(gòu)
方法1:數(shù)組,稱為“父親表示法”
const int m = 10;//樹的結(jié)點(diǎn)數(shù)
struct node
{
int data, parent;//數(shù)據(jù)域、指針域
};
node tree[m];
43
優(yōu)缺點(diǎn):利用了樹中除根結(jié)點(diǎn)外每個(gè)結(jié)點(diǎn)都有唯一的父結(jié)點(diǎn)這個(gè)性質(zhì)。很容易找
到樹根,但找孩子時(shí)需要遍歷整個(gè)線性表。
方法2:樹型單鏈表結(jié)構(gòu),稱為“孩子表示法”。每個(gè)結(jié)點(diǎn)包括一個(gè)數(shù)據(jù)域和一
個(gè)指針域(指向若干子結(jié)點(diǎn))。稱為”孩子表示法”。假設(shè)樹的度為10 ,樹的結(jié)點(diǎn)
僅存放字符,則這棵樹的數(shù)據(jù)結(jié)構(gòu)定義如下:
const int m = 10; / /樹的度
typedef struct node ;
typedef node *tree;
struct node
{
char data;//數(shù)據(jù)域
tree child[m];//指針域,指向若干孩子結(jié)點(diǎn)
}
tree t;
缺陷:只能從根(父)結(jié)點(diǎn)遍歷到子結(jié)點(diǎn),不能從某個(gè)子結(jié)點(diǎn)返回到它的父結(jié)點(diǎn)。但
程序中確實(shí)需要從某個(gè)結(jié)點(diǎn)返回到它的父結(jié)點(diǎn)時(shí);就需要在結(jié)點(diǎn)中多定義一個(gè)指
針變量存放其父結(jié)點(diǎn)的信息。這種結(jié)構(gòu)又叫帶逆序的樹型結(jié)構(gòu)。
方法3 :樹型雙鏈表結(jié)構(gòu),稱為”父親孩子表示法”。每個(gè)結(jié)點(diǎn)包括一個(gè)數(shù)據(jù)
域和二個(gè)指針域(一個(gè)指向若干子結(jié)點(diǎn),一個(gè)指向父結(jié)點(diǎn))。假設(shè)樹的度為10 ,樹
的結(jié)點(diǎn)僅存放字符,則這棵樹的數(shù)據(jù)結(jié)構(gòu)定義如下:
const int m= 10; / /樹的度
typedef struct node;
44
typedef node *tree;//聲明tree 是指向node 的指針類型
struct node
{
char data; // 數(shù)據(jù)域
tree child[m]; //指針域,指向若干孩子結(jié)點(diǎn)
tree father ; / /指針域,指向父親結(jié)點(diǎn)
};
tree t;
方法4 :二叉樹型表示法,稱為”孩子兄弟表示法”。也是一種雙鏈表結(jié)構(gòu),但
每個(gè)結(jié)點(diǎn)包括一個(gè)數(shù)據(jù)域和二個(gè)指針域( 一個(gè)指向該結(jié)點(diǎn)的第一個(gè)孩子結(jié)點(diǎn),一
個(gè)指向該結(jié)點(diǎn)的下一個(gè)兄弟結(jié)點(diǎn))。稱為”孩子兄弟表示法”。假設(shè)樹的度為10 ,
樹的結(jié)點(diǎn)僅存放字符,則這棵樹的數(shù)據(jù)結(jié)構(gòu)定義如下:
typedef struct node; ,
typedef node *tree;
struct node
{
char data; //數(shù)據(jù)域
tree firstchild, next;
//指針域,分別指向第一個(gè)孩子結(jié)點(diǎn)和下一個(gè)兄弟結(jié)點(diǎn)};
};
tree t;
(4)樹的遍歷
45
在應(yīng)用樹結(jié)構(gòu)解決問題時(shí),往往要求按照某種次序獲得樹中全部結(jié)點(diǎn)的信息,這種
操作叫作樹的遍歷。遍歷的方法有多種,常用的有:
A、先序(根)遍歷:先訪問根結(jié)點(diǎn),再從左到右按照先序思想遍歷各棵子樹。如上圖
先序遍歷的結(jié)果為:125634789 ;
B、后序(根)遍歷:先從左到右遍歷各棵子樹,再訪問根結(jié)點(diǎn)。如上圖后序遍歷的結(jié)
果為: 562389741 ;
C、層次遍歷:按層次從小到大逐個(gè)訪問,同一層次按照從左到右的次序。如上圖
層次遍歷的結(jié)果為: 123456789 ;
D、葉結(jié)點(diǎn)遍歷:有時(shí)把所有的數(shù)據(jù)信息都存放在葉結(jié)點(diǎn)中,而其余結(jié)點(diǎn)都是用來
表示數(shù)據(jù)之間的某種分支或?qū)哟侮P(guān)系,這種情況就用這種方法。如上圖按照這個(gè)
思想訪問的結(jié)果為: 56389 ;
2、二叉樹
(1)二叉樹的定義
二叉樹( Binary Tree)是n( n≥0 )個(gè)結(jié)點(diǎn)所構(gòu)成的集合,它或?yàn)榭諛? n= 0) ;或?yàn)?br /> 非空樹,對(duì)于非空樹T:
a )有且僅有一個(gè)稱之為根的結(jié)點(diǎn);
b )除根結(jié)點(diǎn)以外的其余結(jié)點(diǎn)分為兩個(gè)互不相交的子集T 和T2,分別稱為的左子樹
和右子樹,且和72 本身又都是二叉樹。
(2)二叉樹的基本特點(diǎn)
a)結(jié)點(diǎn)的度小于等于2
b)有序樹(子樹有序,不能顛倒)
46
二叉樹的五種不同的形態(tài)
(3)二叉樹的性質(zhì)
性質(zhì)1:在二叉樹的第i 層上之多有2^(i-1)個(gè)結(jié)點(diǎn)
性質(zhì)2:深度為k 的二叉樹至多有2^k-1 個(gè)結(jié)點(diǎn)
性質(zhì)3:對(duì)于任何一棵二叉樹,若2 度的結(jié)點(diǎn)數(shù)有n_2 個(gè),則葉子數(shù)n_0 必定
為n_2+1(即n_0=n_2+1)
特殊形態(tài)的二叉樹
a)滿二叉樹:一顆深度為k 且有2^k-1 個(gè)結(jié)點(diǎn)的二叉樹。
b)完全二叉樹:深度為k 的,有n 個(gè)結(jié)點(diǎn)的二叉樹,當(dāng)且僅當(dāng)其每一個(gè)結(jié)點(diǎn)都
與深度為k 的滿二叉樹中編號(hào)從1 至n 的結(jié)點(diǎn)一一對(duì)應(yīng)
性質(zhì)4:具有n 個(gè)結(jié)點(diǎn)的完全二叉樹的深度必為[log_2?n ]+1
性質(zhì)5:對(duì)完全二叉樹,若從上至下、從左至右編號(hào),則編號(hào)為i 的結(jié)點(diǎn),其左
孩子編號(hào)必為2i,其右孩子編號(hào)必為2i+1;其雙親的編號(hào)為i/2;
(4)二叉樹的順序存儲(chǔ)
實(shí)現(xiàn):按滿二叉樹的結(jié)點(diǎn)層次編號(hào),依次存放二叉樹中的數(shù)據(jù)元素
(5)遍歷二叉樹
遍歷定義一一指按某條搜索路線遍訪每個(gè)結(jié)點(diǎn)且不重復(fù)(又稱周游)。
遍歷用途一一它是樹結(jié)構(gòu)插入、刪除、修改、查找和排序運(yùn)算的前提,是二叉樹
一切運(yùn)算的基礎(chǔ)和核心。
DLR——先序遍歷,即先根再左再右
47
LDR——中序遍歷,即先左再根再右
LRD——后序遍歷,即先左再右再根
6.5、圖
1、圖的相關(guān)概念
(1)圖是由一個(gè)頂點(diǎn)的集合V 和一個(gè)頂點(diǎn)間關(guān)系的集合E 組成:記為G=(V,E)
V :頂點(diǎn)的有限非空集合。
E :頂點(diǎn)間關(guān)系的有限集合(邊集)。
存在一個(gè)結(jié)點(diǎn)v,可能含有多個(gè)前驅(qū)結(jié)點(diǎn)和后繼結(jié)點(diǎn)。
(2)圖中頂點(diǎn)之間的連線若沒有方向,則稱這條連線為邊,稱該圖為無向圖。
(3)圖中頂點(diǎn)之間的連線若有方向,則稱這條連線為弧,則稱該圖為有向圖。
(4)完全圖稠密圖稀疏圖
在一個(gè)無向圖中,如果任意兩頂點(diǎn)都有一條直接邊相連接,則稱該圖為無向完
全圖。一個(gè)含有n 個(gè)頂點(diǎn)的無向完全圖中,n(n-1)/2 條邊。
在一個(gè)有向圖中,如果任意兩頂點(diǎn)之間都有方向互為相反的兩條弧相連接,則
稱該圖為有向完全圖。在一個(gè)含有n 個(gè)頂點(diǎn)的有向完全圖中,n(n-1)條邊。
若一個(gè)圖接近完全圖,稱為稠密圖。邊數(shù)很少的圖被稱為稀疏圖。
(5)度
a)頂點(diǎn)的度( degree )是指依附于某頂點(diǎn)v 的邊數(shù),通常記為TD(v)
結(jié)論:圖中所有頂點(diǎn)的度=邊數(shù)的兩倍
b)出度入度
對(duì)有向圖來說
48
頂點(diǎn)的出度:以頂點(diǎn)v 為始點(diǎn)的弧的數(shù)目,記為OD(v)。頂點(diǎn)的入度:以頂點(diǎn)v 為終
點(diǎn)的弧的數(shù)目,記為ID(v)。頂點(diǎn)的度: TD(v)=ID(v) + OD(v).
(6)權(quán)網(wǎng)絡(luò)
與邊有關(guān)的數(shù)據(jù)信息稱為權(quán)
邊上帶權(quán)的圖稱為網(wǎng)圖或網(wǎng)絡(luò)
弧或邊帶權(quán)的圖分別稱為有向網(wǎng)或無向網(wǎng)
(7)路徑
簡(jiǎn)單路徑:序列中頂點(diǎn)不重復(fù)出現(xiàn)的路徑
簡(jiǎn)單回路(簡(jiǎn)單環(huán)):除第一個(gè)頂點(diǎn)與最后一個(gè)頂點(diǎn)之外,其他頂點(diǎn)不重復(fù)出現(xiàn)
的回路。
2、圖的存儲(chǔ)結(jié)構(gòu)
(1)鄰接矩陣(有向圖,無向圖,網(wǎng)圖分別如何存儲(chǔ))
(2)鄰接表(了解)
鄰接矩陣:代碼書寫簡(jiǎn)單,找鄰接點(diǎn)慢
鄰接表:代碼書寫較復(fù)雜,找鄰接點(diǎn)快
第07 課指針
7.1、概念
(1)指針也是一個(gè)變量。和普通變量不同的是,指針變量李存儲(chǔ)的數(shù)據(jù)是一個(gè)
內(nèi)存地址。
(2)指針變量的定義:
49
類型名*指針變量名
int *p;
(3)指針變量賦值
a)先定義變量,再賦值
int a=3,*p;
p=&a;
b)定義變量的同時(shí),進(jìn)行賦值。
int a=3,*p=&a;
注意:只能用同類型變量的地址進(jìn)行賦值
7.2、引用與運(yùn)算
1、指針的引用
引用指針時(shí),首先要理解指針變量與普通變量的區(qū)別和對(duì)應(yīng)關(guān)系。例如,定義一
個(gè)指針變量“int *p;”和一個(gè)普通變量“int a;”,關(guān)于兩者之間的各種引用方
式對(duì)應(yīng)關(guān)系如下:
(1)“p”等同于“&a”,表示的是內(nèi)存地址
(2)“*p”等同于“a”,表示變量里存儲(chǔ)的實(shí)際數(shù)據(jù)
(3)“*p=3;”等同于“a=3;”,表示變量的賦值方式。
2、指針的運(yùn)算
如果定義的是局部指針變量,其地址就是隨機(jī)的,直接操作會(huì)引發(fā)不可預(yù)測(cè)
的錯(cuò)誤。所以,指針變量一定要初始化后才能引用。
由于指針變量存儲(chǔ)的是內(nèi)存地址,所以也可以執(zhí)行加法、減法運(yùn)算,一般用
50
來配合數(shù)組進(jìn)行尋址操作。
7.3、指針與數(shù)組。
在C++中,數(shù)組名在一定意義上可以被看成指針。“數(shù)組的指針”是指整
個(gè)數(shù)組在內(nèi)存中的起始地址,“數(shù)組元素的指針”是數(shù)組中某個(gè)元素所占存儲(chǔ)單
元的地址。例如,"int a[10],*p;p=a;“就表示定義了一個(gè)指針p,指向a
數(shù)組在內(nèi)存中的起始地址a[0]。一般可以使用“下標(biāo)法”訪問數(shù)組元素,如a[5];
也可以使用“地址法”訪問數(shù)組元素,因?yàn)閿?shù)組名就代表數(shù)組在內(nèi)存中的起始地
址,也就是a[0]的地址,如a+4 就表示a[4]的地址;當(dāng)然,也可以通過“指針
法”訪問數(shù)組元素,通過數(shù)組的指針或者數(shù)組元素的指針訪問數(shù)組元素,能使目
標(biāo)程序質(zhì)量更高,占用內(nèi)存更少,運(yùn)行速度更快。
四、函數(shù)指針及擴(kuò)展
程序中需要處理的數(shù)據(jù)都保存在內(nèi)存空間,而程序以及函數(shù)同樣也保存在內(nèi)
存空間。C++支持通過函數(shù)的人口地址(指針)訪問函數(shù)。另一方面,有些函數(shù)在
編寫時(shí)要調(diào)用其他的輔助函數(shù),但是尚未確定,在具體執(zhí)行時(shí),再為其傳遞輔助
函數(shù)的地址。比如排序函數(shù)sort(a,a+n,cmp),其中的比較函數(shù)cmp 是根據(jù)
需要傳遞給sort 的,就是傳遞了一個(gè)函數(shù)指針。
函數(shù)指針就是指向函數(shù)的指針變量,定義格式如下:
類型名(*函數(shù)名) (參數(shù));
例如,"int(*f) (int a,int b);",規(guī)范來說,此處的“函數(shù)名”應(yīng)該稱為“指針
的變量名”。
51
第08 課基本算法
8.1、高精度算法
計(jì)算機(jī)最初、也是最重要的應(yīng)用就是數(shù)值運(yùn)算。在編程進(jìn)行數(shù)值運(yùn)算時(shí),有時(shí)
會(huì)遇到運(yùn)算的精度要求特別高,遠(yuǎn)遠(yuǎn)超過各種數(shù)據(jù)類型的精度范圍;有時(shí)數(shù)據(jù)又特
別大,遠(yuǎn)遠(yuǎn)超過各種數(shù)據(jù)類型的極限值。這種情況下,就需要進(jìn)行“高精度運(yùn)算”。
高精度運(yùn)算首先要處理好數(shù)據(jù)的接收和存儲(chǔ)問題,其次要處理好運(yùn)算過程中的
“進(jìn)位”和“借位”問題。
【題目描述】
輸入n,輸出n!的精確值,n!=1x2x3......xn,1<n<1000
【輸入】
一個(gè)整數(shù)n
【輸出】
n!的值
【樣例輸入】
2
【問題分析】
假設(shè)已經(jīng)計(jì)算好(n-1)!,那么對(duì)于求n!,就是用一個(gè)整數(shù)去乘以一個(gè)高精度
數(shù)。只要用n 乘以(n-1)!的每一位(從低位開始),同時(shí)不斷處理進(jìn)位。
52
8.2、遞推算法
“遞推”是計(jì)算機(jī)解題的一種常用方法。利用“遞推法"解題首先要分析歸
納出“遞推關(guān)系”。比如經(jīng)典的斐波那契問題,用f(i)表示第i 項(xiàng)的值,則
f(1)=0,f(2)=1,在n>2 時(shí),,存在遞推關(guān)系:f(n)=f(n-1)+f(n-2) 。
在遞推問題模型中,每個(gè)數(shù)據(jù)項(xiàng)都與它前面的若干數(shù)據(jù)項(xiàng)(或后面的若干數(shù)據(jù)
項(xiàng))存在一定的關(guān)聯(lián),這種關(guān)聯(lián)一般是通過一個(gè)“遞推關(guān)系式”來描述的。求
解問題時(shí),需要從初始的一個(gè)或若干個(gè)數(shù)據(jù)項(xiàng)出發(fā),通過遞推關(guān)系式逐步推進(jìn),
從而推導(dǎo)出最終結(jié)果。這種求解問題的方法叫“遞推法”。其中,初始的若干數(shù)
據(jù)項(xiàng)稱為“遞推邊界”。
解決遞推問題有三個(gè)重點(diǎn):一是建立正確的遞推關(guān)系式;二是分析遞推關(guān)系式
的性質(zhì);三是根據(jù)遞推關(guān)系式編程求解。
8.3、分治算法
“分治”是一種常用的解題策略。它是將一個(gè)難以直接解決的大問題,分解成若
干規(guī)模較小的、相互獨(dú)立的、相同或類似的子問題,分而治之,再合成得到問
題的解。根據(jù)“平衡子問題”的思想,一般會(huì)把問題分解成兩個(gè)規(guī)模相等的子問
題,也就是“二分法”,比如經(jīng)典的二分查找(由半查找)問題。
例:找偽幣。
【問題描述】
給出16 個(gè)一模一樣的硬幣,其中有1 個(gè)是偽造的,并且那個(gè)傷造的硬幣比真的硬
幣要輕一些,本題的任務(wù)是找出這個(gè)偽造的硬幣。為了完成這一任務(wù),將提供一
合可用來比較兩組硬幣重量的儀器,可以指導(dǎo)兩組硬幣孰輕孰重。
53
【問題分析】
方法1 窮舉法
依次比較硬幣1 與硬幣2、硬幣3 和硬幣4、硬幣5 和硬幣6……最多通過8 次
比較來判斷偽造幣的存在并找出這個(gè)偽幣。
方法2 二分法
把16 個(gè)硬幣的情況看成一個(gè)大問題。第一步,把這一大問題分成兩個(gè)小問題,
隨機(jī)選擇8 個(gè)硬幣作為第一組(A 組),剩下的8 個(gè)硬幣作為第二組(B 組)。第二步,
利用儀器判斷偽幣在A 組還是在B 組中,如果在A 組中則再把A 組中的8 個(gè)硬幣
隨機(jī)分成2 組,每組4 個(gè)再去判斷...這樣,只要(必須)4 次比較一定能找出偽幣。
方法3 三分法
把16 個(gè)硬幣分成3 組(A 組5 個(gè)、B 組5 個(gè)、C 組6 個(gè)),利用儀器比較A、B 兩
組,一次就可以判斷出偽幣在A、B 、C 哪一組中。假如在C 組中,則再把C 組
中的6 個(gè)分成3 組(2 個(gè)、2 個(gè)、2 個(gè)),再用儀器比較一次判斷出在哪一組。然
后再比較1 次就能判斷出2 個(gè)硬幣中哪個(gè)是偽幣。這樣,只要2~3 次比較便能
找出偽幣。
8.4、貪心算法
貪心法的基本思想
貪心法是從問題的某個(gè)初始解出發(fā),采用逐步構(gòu)造最優(yōu)解的方法,向給定的
目標(biāo)前進(jìn)。在每一個(gè)局部階段, 都做一個(gè)“看上去最優(yōu)的決策,并期望通過每
一次所做的局部最優(yōu)選擇產(chǎn)生出一個(gè)全局最優(yōu)解。做出貪心決策的依據(jù)稱為“貪
心策略”。要注意的是,貪心策略一旦做出,就不可再更改。
54
與遞推不同的是,貪心嚴(yán)格意義上說只是一種策略或方法,而不是算法。推
進(jìn)的每一步不是依據(jù)某一個(gè)固定的遞推式,而是做一個(gè)當(dāng)時(shí)“看似最佳”的貪心
選擇(操作),不斷將問題歸納為更小的相似子問題。所以,歸納、分析、選擇正確
合適的貪心策略,是解決貪心問題的關(guān)鍵。
8.5、搜索算法(寬度優(yōu)先搜索、深度優(yōu)先搜索)
1、寬度優(yōu)先搜索
寬度優(yōu)先搜索的基本思想
寬度優(yōu)先搜索(Breadth First Search, BFS),簡(jiǎn)稱寬搜,又稱為廣度優(yōu)先搜
索。它是從初始結(jié)點(diǎn)開始,應(yīng)用產(chǎn)生式規(guī)則和控制策略生成第一層結(jié)點(diǎn),同時(shí)檢
查目標(biāo)結(jié)點(diǎn)是否在這些生成的結(jié)點(diǎn)中。若沒有,再用產(chǎn)生式規(guī)則將所有第一層結(jié)
點(diǎn)逐一拓展,得到第二層結(jié)點(diǎn),并逐一檢查第二層結(jié)點(diǎn)是否包含目標(biāo)結(jié)點(diǎn)。若沒
有,再用產(chǎn)生式規(guī)則拓展第二層結(jié)點(diǎn)。如此依次拓展,檢查下去,直至發(fā)現(xiàn)目標(biāo)
結(jié)點(diǎn)為止。如果拓展完所有結(jié)點(diǎn),都沒有發(fā)現(xiàn)目標(biāo)結(jié)點(diǎn),則問題無解。
在搜索的過程中,寬度優(yōu)先搜索對(duì)于結(jié)點(diǎn)是沿著深度的斷層拓展的。如果要
拓展第n+1 層結(jié)點(diǎn),必須先全部拓展完第n 層結(jié)點(diǎn)。對(duì)于同層結(jié)點(diǎn)來說,它們
對(duì)于問題的解的價(jià)值是相同的。所以,這種搜索方法一定能保證找到最短的解序
列。也就是說,第一個(gè)找到的目標(biāo)結(jié)點(diǎn),一定是應(yīng)用產(chǎn)生式規(guī)則最少的。因此,
寬度優(yōu)先搜索算法適合求最少步驟或者最短解序列這類最優(yōu)解問題。
2、深度優(yōu)先搜索
深度優(yōu)先搜索(Depth First Search,DFS),簡(jiǎn)稱深搜,其狀態(tài)“退回一步”的順
序符合“后進(jìn)先出”的特點(diǎn),所以采用“棧”存儲(chǔ)狀態(tài)。深搜的空間復(fù)雜度較小,
55
因?yàn)樗淮鎯?chǔ)了從初始狀態(tài)到當(dāng)前狀態(tài)的條搜索路徑。但是深搜找到的第一個(gè)解
不一定是最優(yōu)解,要找最優(yōu)解必須搜索整棵“搜索樹”。所以,深搜適用于要求
所有解方案的題目。
深搜可以采用直接遞歸的方法實(shí)現(xiàn),其算法框架如下:
void dfs (dep:integer,參數(shù)表);{
自定義參數(shù);
if(當(dāng)前是目標(biāo)狀態(tài)){
輸出解或者作計(jì)數(shù)、評(píng)價(jià)處理;
}else
for(i = 1; i <=狀態(tài)的拓展可能數(shù); i++)
if(第i 種狀態(tài)拓展可行){
維護(hù)自定義參數(shù);
dfs(dep+1,參數(shù)表);
}
}
8.6、動(dòng)態(tài)規(guī)劃算法
動(dòng)態(tài)規(guī)劃是一種將問題實(shí)例分解為更小的、相似的子問題,并存儲(chǔ)子問題的解
而避免計(jì)算重復(fù)的子問題,以解決最優(yōu)化問題的算法策略。動(dòng)態(tài)規(guī)劃實(shí)際上就是
一種排除重復(fù)計(jì)算的算法,更具體的說,就是用空間換取時(shí)間。
能采用動(dòng)態(tài)規(guī)劃求解的問題的一般要具有3 個(gè)性質(zhì):
(1)最優(yōu)化原理:問題的最優(yōu)解所包含的子問題的解也是最優(yōu)的
56
(2)無后效性:即某階段狀態(tài)一旦確定,就不受這個(gè)狀態(tài)以后決策的影響。
(3)有重疊子問題:即子問題之間是不獨(dú)立的,一個(gè)子問題在下一階段決策中可能
被多次使用到。
動(dòng)態(tài)規(guī)劃問題的一般解題步驟
1、判斷問題是否具有最優(yōu)子結(jié)構(gòu)性質(zhì),若不具備則不能用動(dòng)態(tài)規(guī)劃。
2、把問題分成若干個(gè)子問題(分階段)
3、建立狀態(tài)轉(zhuǎn)移方程(遞推公式)。
4、找出邊界條件。
5、將已知邊界值帶入方程。
6、遞推求解。

總結(jié)

以上是生活随笔為你收集整理的蓝桥杯青少年创意编程C++组赛前集训教程包的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。