递归
先来看下treeview的简单应用:
一、nodes
二、往节点里面添加内容
下面再给大家复习下递归:
什么叫递归呢?“和尚讲故事”,就是方法自己调自己,这就是递归。
三、方法自己调自己
我们先调下T1方法,让大家看个东西:
四、让大家看的东西
五、调用堆栈
用堆栈来监视一下:
一开始调了main方法
再调T1方法
再调T2方法
注意一下顺序,类似于栈结构,先进来在最下面,后进来在最上面。
刚T2方法执行完毕,T2方法没了。
调完之后,从栈里面出来了。
再看下我调Say方法。
一开始还是调的main方法,
一直在调Say方法,这个栈越来愈大,直到系统报错。
六、溢出,系统报错
递归里面注意的地方:一定要有终止条件。
接下来我们看两个例子:
七、这个方法的执行结果是什么呢?
如果代码中加上:index++; 又是什么答案呢?
不让用VS测试的时候,自己可以在纸上用纸和笔划一下。
有一些个公司喜欢用这种装逼的题目当面试题的。
答案是4a4b,为什么是这样呢?
我们画图进行分析:
八、例一分析图示
对于初学者来讲,这幅图可能还是比较的抽象,所以,建议调试一下。
九、例一分析图示二
十、例二代码
大家再想想,这段代码的输出结果。考验人类思维极限呦。
下面我们还是画个图就行演示:
十一、例二分析图
n在自己的作用域范围内,互不影响。
在做一个程序的时候,能用循环做的,就不要用递归来做。用递归的话,效率极其低下。
想深入研究的朋友可以看下关于:尾递归优化的问题。
在上面两个题目中递归因为栈,才能记住,执行完后面调的方法之后返回去调没有执行完的方法里面的语句。
下面我们看下递归加载和递归删除:
十二、TreeView控件的基本使用
点击按钮加载表中数据到TreeView上。
递归加载子节点插入代码位置:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Data.SqlClient; 10 11 namespace _04数据递归加载到TreeView与递归删除 12 { 13 public partial class Form1 : Form 14 { 15 public Form1() 16 { 17 InitializeComponent(); 18 } 19 20 private void Form1_Load(object sender, EventArgs e) 21 { 22 //1.窗体运行的时候,把节点清空 23 treeView1.Nodes.Clear(); 24 //3.加载父id为0的数据到treeview以及父id对应的值。 25 DataTable dt = GetDataByParentId(0); 26 LoadCity(treeView1.Nodes, dt); 27 } 28 //4.循环进行绑定 29 private void LoadCity(TreeNodeCollection treeNodeCollection, DataTable dt) 30 { 31 //遍历dt中的每一行 32 foreach (DataRow dr in dt.Rows) 33 { 34 int id = Convert.ToInt32(dr[0]); 35 string areaName=dr[1].ToString(); 36 //5.每增加一个节点 37 TreeNode tnode = treeNodeCollection.Add(areaName); 38 tnode.Tag = id; 39 //6.根据当前节点的Id,获取该节点下的所有子节点 40 DataTable dtSub = GetDataByParentId(id); 41 //递归加载 42 LoadCity(tnode.Nodes,dtSub); 43 } 44 } 45 //2.写个方法--根据父Id获取数据的,为了方便我们这里使用DataTable,当然最好还是用list集合。 46 private DataTable GetDataByParentId(int pid) 47 { 48 DataTable dt = new DataTable(); 49 string sql = "Select AreaId,AreaName from TblArea where AreaPid=@pid"; 50 string constr = "Data Source=HY-PC;Initial Catalog=9月27新建数据库;Integrated Security=True"; 51 //SqlDataAdapter内部有两个参数--sql语句和连接字符串 52 using (SqlDataAdapter adapter = new SqlDataAdapter(sql, constr)) 53 { 54 //设置参数 55 adapter.SelectCommand.Parameters.Add(new SqlParameter("@pid",pid)); 56 //动态填充 57 adapter.Fill(dt); 58 return dt; 59 } 60 } 61 } 62 }
为什么这的递归没有死循环呢?
foreach就是它的终结条件。
紧接着我们看下递归删除:
十三、递归删除
递归这块,刚接触可能会不太熟,多练几次就熟啦。
作者近期文章列表:
C#基础教程(完全免费,献给代码爱好者的最好礼物。注:本作者分享自己精心整理的C#基础教程,无任何商业目的。 希望与更多的代码爱好者交流心得,也请高手多多指点!!!) |
|
三层 | 三层(一) |
三层相关案例(及常见的错误) | |
三层实例(内涵Sql CRUD) | |
SQL数据库 ADO.net | 数据库的应用图解一 |
数据库的应用详解二 | |
ADO.NET(内涵效率问题) | |
ADO.NET实例教学一 | |
面向过程,面向对象中高级 | 面向过程,面向对象的深入理解一 |
面向过程,面向对象的深入理解二 | |
面向对象的深入理解三 | |
winform基础 | Winform基础 |
winform中常用的控件 | |
面向过程 | 三种循环的比较 |
C#中的方法(上) | |
我们常见的数组 | |
面向对象 | 思想的转变 |
C#中超级好用的类 | |
C#中析构函数和命名空间的妙用 | |
C#中超级好用的字符串 | |
C#中如何快速处理字符串 | |
值类型和引用类型及其它 | |
ArrayList和HashTable妙用一 | |
ArrayList和HashTable妙用二 | |
文件管理File类 | |
多态 | |
C#中其它一些问题的小节 | |
GDI+ | 这些年我收集的GDI+代码 |
这些年我收集的GDI+代码2 | |
HTML概述以及CSS | 你不能忽视的HTML语言 |
你不能忽视的HTML语言2精编篇 | |
你不能忽视的HTML语言3 | |
CSS基本相关内容--中秋特别奉献 | |
CSS基本相关内容2 | |
JavaScript基础 | JavaScript基础一 |
jQuery | jQuery(内涵: jquery选择器) |