终于到树了~刚开始做题,就遇到了各种问题QAQ ,强迫症的我总是想找二叉树和链表的相似点,最终选择了放弃QAQ
因为开始用C++,和C有些地方不同,所以了解了一下
首先是指针的引用作为形式参数,即指针的地址,在C中的就是指针的指针。为什么要用二级指针呢?你想呀,当我们想通过一个函数改变一个变量的值时,都是向函数传递变量的地址,当那个变量是指针变量时,形参就是指针的地址啦,即二级指针
然后是由delete和new函数牵扯的栈内存和堆内存的区别,new只能在堆中分配空间,delete则是释放由new申请的内存,两者一起使用,就像C中的malloc和free函数一样。至于栈内存和堆内存的区别,栈内存是程序自动向操作系统申请分配和回收的,速度快,程序员无法控制;而堆内存是程序员向操作系统申请的,分配速度较慢,地址不连续,此外,申请了一定要销毁,否则会导致内存泄漏
好了,说了这么多,其实我就是想贴一下怎样创建和遍历二叉树的代码的~ 遍历用的是递归遍历,不得不说代码真的好简洁,不过效率应该不会太高,至于非递归的遍历方法,等我有心情再说吧(逃
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef struct node
{
char data;
struct node *lchild,*rchild;
}BTree,*Tree;
void Create(Tree &T) //先序建立二叉树,注意传递指针的引用
{
char c;
cin >> c;
if(c == ',')
T = NULL;
else
{
T = new BTree; //栈上指针T指向新分配的堆内存
T->data = c;
Create(T->lchild);
Create(T->rchild);
}
}
void PreOrder(Tree T) //先序遍历
{
if(T)
{
cout << T->data;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void InOrder(Tree T) //中序遍历
{
if(T)
{
InOrder(T->lchild);
cout << T->data;
InOrder(T->rchild);
}
}
void PostOrder(Tree T) //后序遍历
{
if(T)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
cout << T->data;
}
}
void LevelOrder(Tree T) //层序遍历
{
queue<Tree> q;
Tree temp;
if(T)
q.push(T);
while(!q.empty())
{
temp = q.front();
cout << temp->data;
q.pop();
if(temp->lchild)
q.push(temp->lchild);
if(temp->rchild)
q.push(temp->rchild);
}
}
void Delele(Tree &T) //销毁二叉树中的各个结点,和创建一样,参数为二叉指针的地址,即指针的指针
{
if(T)
{
Delele(T->lchild);
Delele(T->rchild);
delete T; //delete释放由new在堆中申请的内存,但是通过变量声明的方式由系统所分配的栈内存不能用delete删除
T = NULL; //即堆上内存释放,栈上指针T并不销毁,此时T指向的地址未知(危险!)应该把T置空
}
}
int main()
{
Tree T = NULL; //定义二叉指针后先置空
Create(T);
PreOrder(T);
cout << "\n";
InOrder(T);
cout << "\n";
PostOrder(T);
cout << "\n";
LevelOrder(T);
cout << "\n";
Delele(T);
return 0;
}