1、全部代码编程方式 , 直接上代码
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
//二叉树
typedef struct BiTNode{
int data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree; //定义的时候有写typedef,就可以直接使用这两个变量名定义
//栈
typedef struct stack{
BiTNode data[MAXSIZE];
int top; //初始指向-1 指针停留在栈顶元素上 0是栈底元素 99是栈顶元素
}SqStack;
/*====================================================下面是栈的功能=================================================*/
/**
初始化栈
*/
void initStack(SqStack *s){
s->top = -1;
}
//栈是否为空
int isEmpty(SqStack s){
if(s.top <= -1) return 1;
return 0;
}
//栈是否已满
int isFull(SqStack s){
if(s.top >= 99) return 1;
return 0;
}
/**
入栈
*/
int push(SqStack *s,BiTree e){
if(isFull(*s)) return 0;
s->data[++(s->top)] = *e;
return 1;
}
/**
出栈
*/
int pop(SqStack *s,BiTNode *e){
if(isEmpty(*s)) return 0;
*e = s->data[s->top--];
return 1;
}
/**
从上到下打印栈元素
每5个一换行
*/
void printStack(SqStack s){
int n = s.top; //n为当前头指针 向下遍历
int count = 0; //计数器
for(; n >= 0 ; n--){
BiTNode t = s.data[n]; //获取栈顶指针的树节点的data值
printf("%d\t",t.data);
if(++count % 5 == 0) printf("\n");
}
}
/*===================================================栈的功能在这结束=================================================*
/*====================================================下面是树的功能 ================================================*/
/**
创建结点
*/
BiTNode* createNode(int data){
BiTNode* newNode = (BiTNode*)malloc(sizeof(BiTNode));
newNode->data = data;
newNode->lchild = NULL;
newNode->rchild = NULL;
return newNode;
}
/**
插入结点
(其实这样创建出来的是一颗二叉搜索树)
*/
BiTNode* insertNode(BiTree root , int data){
if(root == NULL) return createNode(data); //树为空 直接创建根节点
//树不为空
if(data < root->data){
//插入的值小于当前结点值 递归往左子树放
root->lchild = insertNode(root->lchild,data); //记得r->l '=' 否则不会挂到树上
}else{
//否则递归插入右子树
root->rchild = insertNode(root->rchild,data);
}
return root;
}
/*
访问结点
*/
void visit(BiTree tree){
printf("%d ",tree->data);
}
/**
递归: 先序遍历
*/
void preTraversal(BiTree tree){
if(tree == NULL) return;
visit(tree); //放在这里是前序
preTraversal(tree->lchild);
//放在这里是中序
preTraversal(tree->rchild);
//放在这里是后序
return;
}
/**
**********************
**非递归遍历: 使用栈**
** 中序 **
**********************
*/
void inTraByStack(BiTree tree){
//建立一个遍历指针
//结点弹出栈后依靠它指向弹出的元素 从而实现回到上一层的效果
BiTree p = tree;
SqStack s;
initStack(&s);
while(p || !isEmpty(s)){
if(p){
visit(q);
push(&s,p); //注意是结点压入栈
p = p->lchild; //向左孩子
}else{
BiTree q; //王道书上写的应该有点问题 这里需要一个额外变量来接收 不然会出问题
pop(&s,q); //栈顶元素弹出之后 p就指向这个元素了
visit(q);
p = q->rchild; //q是弹出的栈顶元素,那么此时就相当于反倒上一层的父节点了,让p等于父节点的右子树 再重新开始遍历
}
}
}
/*============================================树的功能在这里结束===========================================*/
int main(){
BiTree root = createNode(5);
insertNode(root,2);
insertNode(root,4);
insertNode(root,7);
insertNode(root,8);
insertNode(root,1);
insertNode(root,3);
/*
5
/ \
2 7
/ \ \
1 4 8
/
3
*/
// preTraversal(root);
//printf(" ::%d ",root->data);
inTraByStack(root);
//测试栈
// SqStack s;
// initStack(&s);
//
// int i = 0;
//
// while(!isFull(s)){
// push(&s,i++);
// }
// printStack(s);
//
// int e;
// while(!isEmpty(s)){
// pop(&s,&e);
// printf("%d\t",e);
// }
return 0;
}
1.1 递归遍历代码部分
/**
递归: 先序遍历
*/
void preTraversal(BiTree tree){
if(tree == NULL) return;
visit(tree); //放在这里是前序
preTraversal(tree->lchild);
//放在这里是中序
preTraversal(tree->rchild);
//放在这里是后序
return;
}
1.2 中序非递归遍历(非递归的三种遍历方式写法不像递归变化那么简单 后续更新)
/**
**********************
**非递归遍历: 使用栈**
** 中序 **
**********************
*/
void inTraByStack(BiTree tree){
//建立一个遍历指针
//结点弹出栈后依靠它指向弹出的元素 从而实现回到上一层的效果
BiTree p = tree;
SqStack s;
initStack(&s);
while(p || !isEmpty(s)){
if(p){
visit(q);
push(&s,p); //注意是结点压入栈
p = p->lchild; //向左孩子
}else{
BiTree q; //王道书上写的应该有点问题 这里需要一个额外变量来接收 不然会出问题
pop(&s,q); //栈顶元素弹出之后 p就指向这个元素了
visit(q);
p = q->rchild; //q是弹出的栈顶元素,那么此时就相当于反倒上一层的父节点了,让p等于父节点的右子树 再重新开始遍历
}
}
}
2.力扣递归写法
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void inorder(struct TreeNode* root,int ans[], int *index){
if(root){
inorder(root -> left,ans,index);
ans[(*index)++] = root -> val;
inorder(root -> right,ans,index);
}
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
int index = 0 ;
if(root){
static int ans[100] = {-1}; //或者是静态分配数组
// int *ans = malloc(sizeof(int) * 101); //或者是动态分配内存
int index = 0;
inorder(root,ans,&index);
*returnSize = index;
return ans;
}
else{
*returnSize = 0;
return NULL;
}
}