#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef struct BSTreeNode {
struct BSTreeNode * pLeft; // prev
struct BSTreeNode * pRight; // next
int data;
} BSTreeNode;
BSTreeNode * CreateNode(int data)
{
BSTreeNode *pNode = (BSTreeNode *)malloc(sizeof(BSTreeNode));
assert(pNode);
pNode->data = data;
pNode->pLeft = pNode->pRight = NULL;
return pNode;
}
// 如果存在,插入失败返回 -1, 否则插入成功,返回 0
int Insert(BSTreeNode **pRoot, int data)
{
// 递归
// 1. 空树处理
// 2. 相等处理
// 3. 小于根
// 4. 大于根
assert(pRoot != NULL);
if (*pRoot == NULL) {
// 空树
*pRoot = CreateNode(data);
// 记得返回
return 0;
}
if ((*pRoot)->data == data) {
return -1;
}
if (data < (*pRoot)->data) {
// 1. 记得返回
// 2. 取地址(字段)
return Insert(&((*pRoot)->pLeft), data);
}
else {
return Insert(&((*pRoot)->pRight), data);
}
}
BSTreeNode *pPrev = NULL; // 留个作业,不要全局变量
// 1. 中序
// 2. 有了结点,怎么构造双向链表
// 1)前驱 + 当前结点
// 2)当前结点 + 后继
void HandleNode(BSTreeNode *pRoot)
{
// 1. 中序过来了
// 2. pLeft 是可以更改的
//printf("%d ", pRoot->data);
if (pPrev != NULL) {
pPrev->pRight = pRoot;
}
pRoot->pLeft = pPrev;
// 不断记录 prev
pPrev = pRoot;
}
void InOrderLoop(BSTreeNode *pRoot)
{
BSTreeNode *pCur = pRoot;
BSTreeNode *pTop;
BSTreeNode *stack[100];
int top = 0;
while (pCur != NULL || top > 0) {
while (pCur) {
stack[top++] = pCur;
pCur = pCur->pLeft;
}
// 后序的区别
// 不能直接出栈,需要右子树也遍历完
// 判断右子树遍历完的方式
// 1. 右孩子为 NULL
// 2. 通过一个遍历(pLast)记录上次遍历完的子树
// 当 pTop->pRight == pLast
pTop = stack[top - 1];
top--;
printf("%d ", pTop->data);
pCur = pTop->pRight;
}
}
void PostOrderLoop(BSTreeNode *pRoot)
{
BSTreeNode *pCur = pRoot;
BSTreeNode *pTop;
BSTreeNode *pLast = NULL;
BSTreeNode *stack[100];
int top = 0;
while (pCur != NULL || top > 0) {
while (pCur) {
stack[top++] = pCur;
pCur = pCur->pLeft;
}
// 后序的区别
// 不能直接出栈,需要右子树也遍历完
// 判断右子树遍历完的方式
// 1. 右孩子为 NULL
// 2. 通过一个遍历(pLast)记录上次遍历完的子树
// 当 pTop->pRight == pLast
pTop = stack[top - 1];
if (pTop->pRight == NULL || pTop->pRight == pLast) {
printf("%d ", pTop->data);
top--;
pLast = pTop;
continue;
}
pCur = pTop->pRight;
}
}
void InOrder(BSTreeNode *pRoot)
{
if (pRoot == NULL) {
return;
}
InOrder(pRoot->pLeft);
HandleNode(pRoot);
InOrder(pRoot->pRight);
}
void Test()
{
BSTreeNode *pRoot = NULL;
Insert(&pRoot, 5);
Insert(&pRoot, 1);
Insert(&pRoot, 3);
Insert(&pRoot, 4);
Insert(&pRoot, 2);
Insert(&pRoot, 8);
Insert(&pRoot, 6);
Insert(&pRoot, 7);
Insert(&pRoot, 9);
PostOrderLoop(pRoot);
printf("\n");
}