一、二叉树的创建与遍历
二叉树,子树最多有两个节点
前序遍历
根——>左——>右
我们先找到根也就是A
左就是左边的这些,这也是一个树也要根据根,左,右的顺序,B,D,遍历结束
右是右边的这三个,也是一个树,根据根,左,右的顺序,C ,F,G
#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
//下面是我们树的一个节点
typedef struct TreeNode {
char data;
struct TreeNode* Ichild;//左指针
struct TreeNode* Rchild;//右指针
}TreeNode;
//创建树
//要想改变实参c语言中只能使用二次指针
/*这里要传入二重指针,因为我们的目的是在函数体内部改变(*T)的指向,只有传入二重才能改变一
重指针的指向,否则无效,就像想改变一个变量,我们需要取地址传入。*/
void createTree(TreeNode** T,char* data,int* index) //直接输入data一个序列去创建二叉树,index去遍历这个串,T是节点空间的指针
{
char ch;
ch = data[*index];
*index += 1;//这是反引用,意思是索引下移
scanf("%c\n", &ch);//接受我们传入的字符
if (ch == '#') {
//空节点
*T = NULL;//代表该结点为空
}
//开辟一个节点存放数据,生成子树
else {
//非空节点
*T = (TreeNode*)malloc(sizeof(TreeNode));//开辟空间
(*T) ->data = ch;//将传入的data存放到开辟的空间中去
//递归法
createTree(&((*T)->Ichild),data,index);//左子树
createTree(&((*T)->Rchild),data,index);//右子树
}
}
//遍历
void preorder(TreeNode* T) {
if (T == NULL) {
return;
}
else {
//先办事
printf("%c", T->data);//打印
//递归,处理孩子
preorder(T->Ichild);
preorder(T->Rchild);
}
}
void inorder(TreeNode* T) {
if (T == NULL) {
return;
}
else {
inorder(T->Ichild);//处理左孩子
printf("%c", T->data);//办事
inorder(T->Rchild);//处理右孩子
}
}
void postorder(TreeNode* T) {
if (T == NULL) {
return;
}
else {
postorder(T->Ichild);//处理左孩子
postorder(T->Rchild);//处理右孩子
printf("%c", T->data);//办事
}
}
int main(int argc, char* argv[]) {
int index = 0;
TreeNode* T;
createTree(&T,argv[1],&index);
preorder(T);
printf("\n");
inorder(T);
printf("\n");
postorder(T);
printf("\n");
return 0;
}
二、二叉树的分层遍历
遍历顺序分层来就是 A B G /C D H /E F
个人理解:
你出去了之后就要换你儿子进来一换多,寡王没儿子就不用进
#include<stdio.h>
#include<stdlib.h>
//二叉树
typedef struct TreeNode {
char data;
struct TreeNode* Ichild;
struct TreeNode* Rchild;
}TreeNode;
//队列
typedef struct QueueNode {
TreeNode* data;
struct QueueNode* pre;
struct QueueNode* next;
} QueueNode;
//创建树
void createTree(TreeNode** T, char* data,int*index) {
char ch;
ch = data[*index];
*index += 1;
if (ch = '#') {
*T = NULL;
}
else {
*T = (TreeNode*)malloc(sizeof(TreeNode));
(*T)->data = ch;
createTree(&((*T)->Ichild), data, index);//左子树
createTree(&((*T)->Rchild), data, index);//右子树
}
}
//创建队
QueueNode* initQueue() {
QueueNode* Q = (QueueNode*)malloc(sizeof(QueueNode));//为队列创建头节点
Q->data = NULL;//初始化
Q->next = Q;//双链表指向自己,就是初始化
Q->pre = Q;
return Q;
}
void preOrder(TreeNode* T) {
if (T == NULL) {
return;
}
else {
printf("%c ", T->data);
preOrder(T->Ichild);
preOrder(T->Rchild);
}
}
//入队
void enQueue(TreeNode* data, QueueNode* Q) {
QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));//创建新的节点空间
node->data = data;//赋值
//尾插法
node->pre = Q;//node节点的pre指向头节点
node->next = Q;
Q->pre->next = node;//最后一个节点的next指针指向node,我们有一个空的头节点
Q->pre = node;//Q的头部指向它
}
//判断队列是否满
int isEmpty(QueueNode* Q) {
if (Q->next == Q) {
return 1;
}
else {
return 0;
}
}
//出队
QueueNode* deQueue(QueueNode* Q) {
if (isEmpty(Q)) {
return NULL;
}
else {
QueueNode* node = Q->next;
Q->next->next->pre = Q;
Q->next = Q->next->next;
return node;
}
}
void levelTraverse(QueueNode* Q, TreeNode* T) {
enQueue(T, Q);
while (!isEmpty(Q)) {
QueueNode* node = deQueue(Q);//接受出队的节点
printf("%c ", node->data->data);
if (node->data->Ichild) //左儿子存在
{
enQueue(node->data->Ichild, Q);
}
if (node->data->Rchild)//右儿子存在
{
enQueue(node->data->Rchild, Q);
}
}
}
int main(int argc, char* argv[]) {
TreeNode* T;
int index = 0;
QueueNode* Q = initQueue();
createTree(&T, argv[1], &index);//argv[1]表示程序运行以后输入的第二个字符
preOrder(T);
printf("\n");
levelTraverse(Q, T);
printf("\n");
return 0;
}