Visual C++ 6.0調(diào)試功能 圖解教程(3)--實(shí)例二
Posted on 2008-08-19 17:30 ∪∩BUG 閱讀(1846) 評(píng)論(2) 編輯 收藏 所屬分類: VC++/MFC學(xué)習(xí)筆記樹(shù)和二叉樹(shù)
-
實(shí)驗(yàn)?zāi)康?/span>
1.熟悉二叉樹(shù)的二叉鏈表存儲(chǔ)結(jié)構(gòu);
2.掌握構(gòu)造二叉樹(shù)的方法;
3.加深對(duì)二叉樹(shù)的遍歷的理解。
二.需求分析
本程序演示用C++編寫(xiě),完成按先序遍歷生成二叉樹(shù),先序遍歷打印輸出二叉樹(shù), 后序遍歷打印輸出二叉樹(shù), 中序遍歷打印輸出二叉樹(shù), 層序遍歷打印輸出二叉樹(shù), 先序遍歷方法交換左右子樹(shù),求樹(shù)的高度,求樹(shù)的葉子結(jié)點(diǎn)個(gè)數(shù).
輸入值的范圍:建立一棵二叉時(shí),要求結(jié)點(diǎn)的的左右孩子為空時(shí)輸入0代替.所有輸入值必須為整形.輸入的結(jié)點(diǎn)個(gè)數(shù):若為單邊二叉樹(shù)(全只有左結(jié)點(diǎn)或全只有右結(jié)點(diǎn))則為任意個(gè)數(shù);若非單邊二叉則要求結(jié)點(diǎn)最多的層個(gè)數(shù)不得超過(guò)MAXSIZE的值.
輸出形式:輸出時(shí)如果結(jié)點(diǎn)的左右指針這空則以" #"代替輸出.
程序所能完成的功能:程序能完成按先序遍歷生成二叉樹(shù),先序遍歷打印輸出二叉樹(shù), 后序遍歷打印輸出二叉樹(shù), 中序遍歷打印輸出二叉樹(shù), 層序遍歷打印輸出二叉樹(shù), 先序遍歷方法交換左右子樹(shù),求樹(shù)的高度,求樹(shù)的葉子結(jié)點(diǎn)個(gè)數(shù).操作.
測(cè)試數(shù)據(jù)
A建立二叉樹(shù)中輸入1230000 生成一棵樹(shù)123####
B交換左右子樹(shù)得到一棵二叉樹(shù)1#2#3##
C按層序遍歷樹(shù)得到一棵二叉樹(shù)1#2#3##
D求二叉樹(shù)的高度得到高度3
E求葉子結(jié)點(diǎn)個(gè)數(shù)得到個(gè)數(shù)1
三.設(shè)計(jì)概要
(1)為了實(shí)現(xiàn)上述程序的功能,需要定義二叉樹(shù)的抽象數(shù)據(jù)類型:
ADT BiTree is{
數(shù)據(jù)對(duì)象:D={ai|ai∈IntegerSet,i=0,1,2,…,n,n≥0}
數(shù)據(jù)關(guān)系:R={<ai,ai+1>|ai,ai+1 ∈D}
基本操作:
creat()
操作結(jié)果:建立一棵二叉樹(shù)
preorder()
初始條件:二叉樹(shù)已經(jīng)存在
操作結(jié)果:先序遍歷顯示二叉樹(shù)
preordertswap()
初始條件: 二叉樹(shù)已經(jīng)存在
操作結(jié)果:交換二叉樹(shù)的左右子樹(shù)
theight()
初始條件: 二叉樹(shù)已經(jīng)存在
操作結(jié)果:輸出二叉樹(shù)的高度
tleaves()
初始條件:
操作結(jié)果:輸出二叉樹(shù)的葉子結(jié)點(diǎn)個(gè)數(shù)
levelorder()
初始條件: 二叉樹(shù)已經(jīng)存在
操作結(jié)果:層序遍歷顯示二叉樹(shù)
}ADT BiTree
(2) 本程序包含兩個(gè)類和一個(gè)結(jié)構(gòu)體類型
A基類:隊(duì)列類SeQueue有5個(gè)函數(shù)
1.構(gòu)造函數(shù) SeQueue()
2.析構(gòu)函數(shù) ~SeQueue()
3.進(jìn)隊(duì)函數(shù) AddQ(NodeType x)
4.出隊(duì)函數(shù) DelQ()
5.判斷非空函數(shù) IsEmpty()
B派生類:二叉樹(shù)類BiTree有20個(gè)函數(shù)
1主函數(shù) main()
2. 構(gòu)造函數(shù) BiTree()
3. 析構(gòu)函數(shù) ~BiTree()
4. 建立樹(shù)函數(shù) creat0()
5. 先序遍歷函數(shù) void preorder()
6. 中序遍歷函數(shù) inorder()
7. 后序遍歷函數(shù) postorder()
8.層序遍歷函數(shù) levelorder()
9. 交換左右子樹(shù)函數(shù) preordertswap()
10. 求二叉樹(shù)高度函數(shù) theight()
11. 求二叉樹(shù)葉子結(jié)點(diǎn)個(gè)數(shù)函數(shù) tleaves()
12. 建立二叉樹(shù)遞歸算法函數(shù) *creat()
13. 先序遍歷遞歸算法函數(shù) preorder(NodeType *p)
14. 中序遍歷遞歸算法函數(shù) inorder(NodeType *p)
15. 后序遍歷遞歸算法函數(shù) postorder(NodeType *p)
16. 按層遍歷算法函數(shù) levelorder(NodeType *p)
17. 先序遍歷方法交換左右子樹(shù)函數(shù) preorderswap(NodeType *p)
18. 求二叉樹(shù)高度遞歸算法函數(shù) height(NodeType *p)
19. 求二叉樹(shù)葉子結(jié)點(diǎn)個(gè)數(shù)的遞歸算法函數(shù) leaves(NodeType *p)
20. 刪除二叉樹(shù)所有結(jié)點(diǎn)函數(shù) destroy(NodeType* &p)
C結(jié)構(gòu)體類型NodeType
(3)本程序的三個(gè)文件
1.頭文件BiTree.h
2.源文件 Queue.cpp
BiTree.cpp
(4)函數(shù)之間的關(guān)系
四.詳細(xì)設(shè)計(jì)

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

五.心得:
這次實(shí)驗(yàn)不僅能鞏固理解遞歸的方法,另一方面很能考驗(yàn)運(yùn)用指針的能力,還有就是數(shù)據(jù)類型要使用得當(dāng).從levelorder(NodeType *p)函數(shù)來(lái)看,首先, DelQ()的返回類型要與BiTree二叉樹(shù)結(jié)點(diǎn)指針的類型一至.其次,在遞歸過(guò)程中,傳入AddQ(NodeType x)是整個(gè)結(jié)點(diǎn)的內(nèi)容而不是一個(gè)指針.值得討論的是,在定義存儲(chǔ)隊(duì)列的數(shù)組時(shí)如何節(jié)省存儲(chǔ)空間?因?yàn)檩斎氲慕Y(jié)點(diǎn)個(gè)數(shù):若為單邊二叉樹(shù)(全只有左結(jié)點(diǎn)或全只有右結(jié)點(diǎn))則為任意個(gè)數(shù)(實(shí)驗(yàn)上這時(shí)只需要兩個(gè)存儲(chǔ)空間);若非單邊二叉則要求結(jié)點(diǎn)最多的層個(gè)數(shù)不得超過(guò)MAXSIZE的值.后者時(shí)MAXSIZE的值(由性質(zhì)2得)應(yīng)該為2(h-1) (h為樹(shù)的高度).這一點(diǎn)如何實(shí)現(xiàn)呢?BiTree類是SeQueue類的子類,height()函數(shù)是BiTree類的函數(shù),如果能把高度傳入SeQueue類的構(gòu)造函數(shù)就可以通過(guò)一個(gè)for()語(yǔ)句來(lái)求得一個(gè)合適的值用以初始化MAXSIZE.那么就大大的節(jié)省了內(nèi)存空間,并且還能實(shí)現(xiàn)輸入節(jié)點(diǎn)的個(gè)數(shù)為任意的.但把高度傳入SeQueue類的構(gòu)造函數(shù)如何實(shí)現(xiàn)?還有其他要考慮的問(wèn)題,我在今后的學(xué)習(xí)中深入了解.
六.使用說(shuō)明
程序名為No4.exe運(yùn)行環(huán)境為DOS,執(zhí)行后顯示:
在" 請(qǐng)輸入您的選擇(0,1,2,3,4,5,6):"后輸入數(shù)字選擇執(zhí)行的功能.
測(cè)試結(jié)果:
1)選擇1.后輸入1240003500600.(如右圖的一棵二叉樹(shù))
2)選擇4得
3)選擇5得
4)選擇2得
5)選擇3得
6)選擇6或輸入非"0,1,2,3,4,5,6"的數(shù)字
七.調(diào)試過(guò)程
本程序主要對(duì)按層序遍歷操作功能進(jìn)行調(diào)試.用Visual Studio 2008演示.首先把BiTree.h中的" #define MAXSIZE 30"改成" #define MAXSIZE 4",目的是從Visual Studio 2008的監(jiān)視(Watch)窗口中得到更好的觀察效果.
- 將光標(biāo)移置BiTree.cpp文件的void BiTree::levelorder(NodeType *p)和第一條語(yǔ)句處Ctrl+F10開(kāi)始調(diào)試
- 選擇1.后輸入1240003500600.(如右圖的一棵二叉樹(shù))
再選擇3.
-
這時(shí)Debugger仍停留在void BiTree::levelorder(NodeType *p)的第一條語(yǔ)句上.可以從自動(dòng)監(jiān)視窗口中看到已經(jīng)建立了一棵二叉樹(shù),指針P指向二叉樹(shù)的根結(jié)點(diǎn).
-
在監(jiān)視窗口1中輸入變量名:q,t進(jìn)行觀察,F10單步調(diào)試,這時(shí)Debugger停留在 SeQueue q; 語(yǔ)句處
可以在監(jiān)視1窗口中看到對(duì)象q的指針t都未合法初始化.
-
斷續(xù)F10單步調(diào)試兩步,這時(shí)Debugger停留在if(p)語(yǔ)句處,如圖:
在監(jiān)視1窗口輸入!p進(jìn)行觀察,這時(shí)!p值為0,即if(p)判斷語(yǔ)句值為真.
可以進(jìn)入f(p)執(zhí)行,F10斷續(xù),當(dāng)Debugger停留在q.AddQ(*p)語(yǔ)句時(shí)可以從調(diào)用堆棧窗口中看到現(xiàn)在調(diào)用的函數(shù)為F11步入SeQueue類的AddQ(*p)函數(shù).
-
這進(jìn)Debugger停留在AddQ(*p)函數(shù)的第一條語(yǔ)句上.同可以從調(diào)用堆棧窗口中看到現(xiàn)在調(diào)用的函數(shù)為AddQ(*p)
在監(jiān)視2窗口中輸入rear, elem[rear]進(jìn)行觀察.同時(shí)在自動(dòng)窗口中可以看到變量X已經(jīng)指向二叉樹(shù)的根結(jié)點(diǎn).
-
斷續(xù)F10真到AddQ(NodeType x)結(jié)束語(yǔ)句處,可以從監(jiān)視2窗口看到根結(jié)點(diǎn)已經(jīng)入隊(duì)
-
F10后可以看到調(diào)用堆棧窗口中當(dāng)前調(diào)用的是levelorder(NodeType *p)函數(shù),同時(shí)在監(jiān)視1窗口中輸入!q.IsEmpty()觀察到值為true,即可以進(jìn)入while()控制語(yǔ)句執(zhí)行.
F10單步至 t = &(q.DelQ())處,并F11步入q.DelQ(),這時(shí)Debugger停留在DelQ()的第一條語(yǔ)句上,可以從調(diào)用堆棧窗口中看到當(dāng)前調(diào)用的是DelQ()函數(shù).
-
在監(jiān)視3窗口中輸入q進(jìn)行觀察.斷續(xù)F10到Debugger停留在DelQ()函數(shù)的return q語(yǔ)句時(shí)可以從監(jiān)視窗口3中看到根結(jié)點(diǎn)已經(jīng)出隊(duì)
同時(shí)在自動(dòng)窗口中可以看到從DelQ()函數(shù)返回了出隊(duì)結(jié)點(diǎn)并賦給了指針t
-
F10單步調(diào)試直到Debugger停留在levelorder(NodeType *p)函數(shù)的cout << t->data語(yǔ)句上,這時(shí)可以在調(diào)用堆棧窗口中看到當(dāng)前調(diào)用的是levelorder(NodeType *p)函數(shù),在監(jiān)視窗口1中輸入t->date進(jìn)行觀察,已經(jīng)取得根結(jié)點(diǎn)數(shù)據(jù)域的值
-
F10單步調(diào)試一步可以在DOS窗口中看到已經(jīng)輸出根結(jié)點(diǎn)
- Shift+F5退出調(diào)試,完成調(diào)試演示.