今天继续在leetcode上做题,遇到了对称二叉树这道题。二叉树是我从来没学过的一种数据结构,今天借此机会也初步认识了一下二叉树。
这种数据结构大概就长这样。跟链表类似,树也有节点这个概念,而且定义节点的方法也跟链表类似。既然叫做树,就会有根和枝,在数据结构这里枝叫做边。由下图可见树有分支结构,图中的数字就为树的节点,节点分支下来的节点就为子节点,有子节点就会有父节点。二叉树是一种特殊的树,他的每个结点下最多只有两个子节点,一个左节点一个右节点。
1
/ \
2 2
/ \ / \
3 4 4 3
节点创建
先从节点创建讲起
typedef struct TreeNode
{
char val;
struct TreeNode *left, *right;//递归定义
}TreeNode;
可以看到其实跟链表节点的定义有些相似,同样是有数据域和指针域。两个指针分别指向这个节点下的左节点和右节点。
二叉树创建
这里的代码用了引用的代码。感谢这位博主的博客,从里面学习了很多。
void creatTree(TreeNode **t) {
char s;
TreeNode *q;
s = getchar();
if (s=='#') {
*t = NULL;
return ;
}
q = (TreeNode *)malloc(sizeof(TreeNode));
if (q == NULL) {
printf("memory alloc failure!");
exit(0);
}
q->val = s;
*t = q;
//递归建立
creatTree(&q->left);;
creatTree(&q->right);
}
//先序遍历二叉树
void Preorder(TreeNode *t) {
if (t != NULL) {
printf("%c",t->val);
Preorder(t->left);
Preorder(t->right);
}
}
int main() {
TreeNode *t=NULL;
creatTree(&t);
cout << "the tree is :" << endl;
Preorder(t);
cout << endl;
cout<<isSymmetric(t)<<endl;
system("pause");
return 0;
}
这里用的是先序遍历创建二叉树,遍历顺序有先序、中序和后序。先序大概意思是先访问跟节点在遍历左子树最后遍历右子树。遍历顺序的具体意思还不太清楚,今天刚开始学,具体内容等后面学习清楚后在更新。
大部分博客里面关于二叉树操作的代码都用了递归这种方法,这也让我不得不去了解递归。拿这个创建二叉树为例子,可以看来函数的定义里面又调用了这个函数,递归可以大致认为函数调用了他自己。具体可以看看李永乐老师讲汉诺塔这个视频链接这里讲一下啊创建的流程。首先输入一个字符存到一个新建节点的数据域里。这是根节点。然后递归再次调用函数自己,但这时传入的参数是指向刚刚创建的节点的左子节点的指针,这时创建左子节点。这个阶段你输入的字符全都存为左子节点,直到我们输入’#'时不再创建左子节点转成创建右子节点。拿例子来说明一下。如果我们要得到
1
/ \
2 6
/ \ / \
3 4 4 5
这个二叉树,执行代码时我们就输入*123##4##64##5##*前面的123全是来创建最左边的子节点。然后两个##说明3后不再创建左右节点,退到2,因为2还差一个右节点,输入4创建,再次输入两个#表示4后不再创建任何节点,然后退到1,因为1也差一个右节点,输入6创建,接下来先创建6的左节点4然后是右节点5。
今天刚刚认识这种数据结构,学的也非常浅,上面是我对一些知识点的理解。等我以后对树更深入学习后再来更新。