#include<stdio.h>
#include<stdlib.h>
/*
1.了解二叉树
1.1 基本概念
2.二叉树的遍历
*/
//描述单一个体
typedef struct treeNode
{
char data; //数据域字符表示
struct treeNode* LChild;
struct treeNode* RChild;
}TREE,*LPTREE;
//创建二叉树
LPTREE createNode(char data)
{
LPTREE newNode = (LPTREE)malloc(sizeof(TREE));
newNode->data = data;
newNode->LChild = NULL;
newNode->RChild = NULL;
return newNode;
}
//没有规律的树
void insertNode(LPTREE parentNode, LPTREE LChild, LPTREE RChild)
{
parentNode->LChild = LChild;
parentNode->RChild = RChild;
}
//打印当前结点中的元素
void printCurNodeData(LPTREE curData)
{
printf("%c\t", curData->data);
}
//递归遍历
//先序:根 左 右
void preOrder(LPTREE root)
{
if (root != NULL)
{
printCurNodeData(root);
preOrder(root->LChild);
preOrder(root->RChild);
}
}
//中序
void midOrder(LPTREE root)
{
if (root != NULL)
{
midOrder(root->LChild);
printCurNodeData(root);
midOrder(root->RChild);
}
}
//后序
void lastOrder(LPTREE root)
{
if (root != NULL)
{
lastOrder(root->LChild);
lastOrder(root->RChild);
printCurNodeData(root);
}
}
//非递归的遍历
/*
把走过的结点位置入栈,并且打印走过的结点
无路可走的时候出栈,回退
找当前结点右边是否存在结点
*/
void preOderByStack(LPTREE root)
{
if (root == nullptr) //空树
return;
LPTREE stack[10]; //存储每次打印的位置
int stackTop = -1; //栈顶标记
LPTREE pMove = root; //从根结点开始做打印
while (stackTop != -1 || pMove)
{
//根 左 右
//找到最左边
while (pMove)
{
//把路径入栈 + 打印走过的结点
printf("%c\t", pMove->data);
stack[++stackTop] = pMove;
pMove = pMove->LChild;
}
//无路可走的处理
if (stackTop != -1)
{
pMove = stack[stackTop--]; //获取栈顶元素并出栈
pMove = pMove->RChild; //去到右边结点
}
}
}
//中序非递归
//左 根 右
/*
1.定义一个移动的指针,移动到最左边,把走过的地方入栈
2.无路的时候,出栈,打印当前结点中的元素
3.出栈后打印当前结点元素,判断当前结点是否存在右边,如果存在就去右边
*/
void minOrderByStack(LPTREE root)
{
if (!root) return;
LPTREE stack[10];
int stackTop = -1;
LPTREE pMove = root;
while (stackTop != -1||pMove)
{
//走到最左边,把走过的节点入栈
while (pMove)
{
stack[++stackTop] = pMove;
pMove = pMove->LChild;
}
//无路可走的时候出栈
if (stackTop != -1)
{
pMove = stack[stackTop--]; //出栈,获取栈顶元素
printf("%c\t", pMove->data);
pMove = pMove->RChild;
}
}
}
//后序非递归
//左 右 根
void lastOrderByStack(LPTREE root)
{
if (!root) return;
LPTREE stack[10];
int stackTop = -1;
LPTREE pMove = root;
LPTREE pLastVisit = NULL; //访问标记
//pMove走到最左边
while (pMove)
{
stack[++stackTop] = pMove;
pMove = pMove->LChild;
}
while (stackTop != -1)
{
pMove = stack[stackTop--];
//当前结点左右是否被访问
if (pMove->RChild == NULL || pMove->RChild == pLastVisit)
{
//如果被访问就打印当前结点中的数据
printf("%c\t", pMove->data);
pLastVisit = pMove; //改变标记的位置
}
else
{
//右边没有被访问
stack[++stackTop] = pMove;
pMove = pMove->RChild;
while (pMove)
{
stack[++stackTop] = pMove;
pMove = pMove->LChild;
}
}
}
}
int main()
{
//创建各个结点
LPTREE A = createNode('A');
LPTREE B = createNode('B');
LPTREE C = createNode('C');
LPTREE D = createNode('D');
LPTREE E = createNode('E');
LPTREE F = createNode('F');
LPTREE G = createNode('G');
//连接结点,构成二叉树
insertNode(A, B, C);
insertNode(B, D, NULL);
insertNode(C, E, F);
insertNode(D, NULL, G);
printf("先序遍历:\n");
preOrder(A);
printf("\n");
preOderByStack(A);
printf("\n中序遍历:\n");
midOrder(A);
printf("\n");
minOrderByStack(A);
printf("\n后序遍历:\n");
lastOrder(A);
printf("\n");
lastOrderByStack(A);
printf("\n");
system("pause");
return 0;
}
二叉树的存储和遍历
猜你喜欢
转载自blog.csdn.net/weixin_44795839/article/details/104295664
今日推荐
周排行