二叉树的链式结构的非递归遍历
二叉樹的鏈式結構的非遞歸遍歷
一. 非遞歸前序遍歷和非遞歸中序遍歷
1.????Stack.h
#ifndef__STACK_H__
#define__STACK_H__
#include<stdio.h>
#include<stdlib.h>
// 棧的初始化大小
#defineSTACK_INIT_SIZE 8
// 棧滿的時候增加的容量
#defineSTACK_INCR_SIZE 8
// 重命名了棧中數據元素的數據類型
typedef structBinTreeNode *StackElemType;
// 定義了棧的結構
typedef structStack
{
?????? StackElemType *base;????? //??? 棧底指針
?????? StackElemType *top;???????? // ? 棧頂指針
?????? int capacity;?????????????? //??? 棧的容量
}Stack;
// 棧中函數的聲明
intinitStack(struct Stack *);
intincrStack(struct Stack *);
int isEmpty(structStack *);
int isFull(structStack *);
int push(structStack *, StackElemType);
int pop(structStack *);
int getHead(structStack *, StackElemType);
#endif
2.????Stack.c
#include"stack.h"
/*
?* 函數名 :initStack
?* 函數參數 :struct Stack *stack (棧管理結構的地址)
?* 函數功能 :初始化棧的結構
?* 函數返回值 :return 0
?*
?*/
intinitStack(struct Stack *stack)
{
?????? stack->base = (StackElemType*)malloc(sizeof(StackElemType)*STACK_INIT_SIZE);
?????? if(stack->base == NULL)
?????? {
????????????? printf("malloc error!!!\n");
????????????? return -1;
?????? }
?????? stack->top = stack->base;
?????? stack->capacity = STACK_INIT_SIZE;
?????? return 0;
}
/*
?* 函數名 :?????? incrStack
?* 函數參數 :struct Stack *stack(棧的管理結構地址)
?* 函數功能 : 在棧滿了的時候給棧增加容量
?* 函數返回值 : return 0
?*/
intincrStack(struct Stack *stack)
{
?????? StackElemType *newBase = (StackElemType*)realloc(stack->base, sizeof(StackElemType)*(stack->capacity +STACK_INCR_SIZE));
?????? if(NULL == newBase)
?????? {
????????????? return -1;
?????? }
?????? stack->base = newBase;
?????? stack->top = stack->base +stack->capacity;
?????? stack->capacity += STACK_INCR_SIZE;
?????? return 0;
}
/*
?* 函數名 :isFull
?* 函數參數 :struct Stack *stack (棧的管理結構地址)
?* 函數功能 : 判斷棧是否滿棧
?* 函數返回值 : 如果棧是滿返回1 否則返回0
?*/
int isFull(structStack *stack)
{
?????? return (stack->base +stack->capacity) == stack->top ? 1 : 0;
}
/*
?* 函數名 :isEmpty
?* 函數參數 : struct Stack *stack (棧的管理結構指針)
?* 函數功能 : 判斷棧是否是空棧
?* 函數返回值 : 如果是空棧返回1 否則返回0
?*/
int isEmpty(structStack *stack)
{
?????? return stack->top == stack->base ?1 : 0;
}
/*
?* 函數名 :?????? push
?* 函數參數 :參數 1 struct Stack *stack(棧管理結構地址)
?*???????????????? ? 參數 2 StackElemType item 入棧的數據元素
?* 函數功能 : 入棧操作
?* 函數返回值 : return 0
?*/
int push(structStack *stack, StackElemType item)
{
?????? if(isFull(stack) &&incrStack(stack) == -1)
?????? {
????????????? printf("內部不足!!!\n");
????????????? return -1;
?????? }
??????
?????? *(stack->top) = item;
?????? stack->top ++;
?????? return 0;
}
/*
?* 函數名 :getHead
?* 函數參數 :參數 1 struct Stack *stack(棧管理結構的地址)
?*???????????參數 2 StackElemType *item 出棧數據元素存放的地方
?* 函數功能 : 獲取棧頂元素的值
?* 函數返回值 : return 0
?*/
int getHead(structStack *stack, StackElemType *item)
{
?????? if(isEmpty(stack))
?????? {
????????????? return 0;
?????? }
?????? *item = *(stack->top - 1);
?????? return 0;
}
/*
?* 函數名 :pop
?* 函數參數 :struct Stack *stack(棧管理結構的地址)
?* 函數功能 : 出棧
?* 函數返回值 : return 0
?*/
int pop(structStack *stack)
{
?????? if(isEmpty(stack))
?????? {
????????????? return 0;
?????? }
?????? stack->top --;
?????? return 0;
}
3.????BinTree.h
#ifndef__BINTREE_H__
#define__BINTREE_H__
#include<stdio.h>
#include<stdlib.h>
#include"stack.h"
// typedef關鍵字是用來重命名數據類型的 這里重命名了數結點中有效數據的類型
typedef intBinTreeElemType;
// 定義了樹的結點類型??
typedef structBinTreeNode
{
?????? BinTreeElemType data;?????????????????? // 1. 結點中有效數據
?????? struct BinTreeNode *leftChild;?????? // 2. 結點的左孩子指針
?????? struct BinTreeNode *rightChild;???? // 3. 結點的右孩子指針
}BinTreeNode;
// 定義了樹的結構
typedef structBinTree
{
?????? struct BinTreeNode *root;????????????? // 1. 樹根的指針
?????? char refvalue;???????????????????????????????? // 2. 定義了結點為空的標志位
}BinTree;
// 函數的聲明
intinitBinTree(struct BinTree *);
intcreateBinTree(struct BinTree *);
intpreOrder(struct BinTree *tree);
int inOrder(structBinTree *);
intpostOrder(struct BinTree);
#endif
4.????BinTree.c
#include"BinTree.h"
/*
?*? 函數名 : initBinTree
?*? 函數參數 : struct BinTree *tree(樹結構的地址)
?*? 函數的功能 :在我們創建一顆二叉樹的時候,對二叉樹進行初始化
?*???????????????? 1.將根結點的指針 指向為NULL 避免野指針
?*???????????????? 2.使用 '#' 作為空結點的標志
?*? 函數的返回值 : return 0
?*/
intinitBinTree(struct BinTree *tree)
{
?????? tree->root = NULL;
?????? tree->refvalue = '#';
?????? return 0;
}
/*
?*? 函數名 :createBinTree
?*? 函數參數 :struct BinTree *tree(樹結構的地址)
?*? 函數的功能 :創建一顆二叉樹這個方法是給用戶調用的
?*? 函數的返回值 :return 0
?*
?*/
intcreateBinTree(struct BinTree *tree)
{
?????? __createBinTree(tree,&(tree->root));
?????? return 0;
}
/*
?*? 函數名 :__createBinTree
?*? 函數參數 :參數1 struct BinTree *tree (樹的地址)
?*????????????參數2 struct BinTreeNode **t(二重指針 自己理解)
?*? 函數功能 : 這個方法是內部的方法 被createBinTree函數調用
?*? 函數返回值 : return 0
?*/
int__createBinTree(struct BinTree *tree, struct BinTreeNode **t)
{
?????? // 測試字符串 ABC##DE##F##G#H##
?????? char item;
?????? scanf("%c", &item);
?????? if(item == tree->refvalue)
?????? {
????????????? *t = NULL;
?????? }
?????? else
?????? {
????????????? *t = (struct BinTreeNode*)malloc(sizeof(struct BinTreeNode));
????????????? (*t)->data = item;
????????????? (*t)->leftChild =(*t)->rightChild = NULL;????
????????????? __createBinTree(tree,&((*t)->leftChild));
????????????? __createBinTree(tree,&((*t)->rightChild));
?????? }
?????? return 0;
}
/*
?*? 函數名 :preOrder
?*? 函數參數 :struct BinTree *tree (樹的地址)
?*? 函數功能 :非遞歸前序遍歷二叉樹
?*? 函數返回值 :return 0
?*/
intpreOrder(struct BinTree *tree)
{
?????? printf("遞歸前序遍歷二叉樹 : ");
?????? __preOrder(tree->root);
?????? printf("\n");
?????? return 0;
}
/*
?*? 函數名 :__preOrder
?*? 函數參數 :struct BinTreeNode *t (樹中結點的指針)
?*? 函數功能 :該函數是內部函數被preOrder函數調用
?*? 函數返回值 :return 0
?*/
int__preOrder(struct BinTreeNode *t)
{
?????? struct BinTreeNode *p = t;
?????? struct Stack stack;
?????? initStack(&stack);
?????? push(*stack, p);
?????? while(!isEmpty(&stack))
?????? {
????????????? getHead(&stack, &p);
????????????? pop(&stack);
????????????? printf("%c",p->data);
????????????? if(p->rightChild != NULL)
????????????? {
???????????????????? push(&stack,p->rightChild);
????????????? }
????????????? if(p->leftChild != NULL)
????????????? {
???????????????????? push(&stack,p-leftChild);
????????????? }
?????? }
?????? return 0;
}
// 中序遍歷二叉樹
int inOrder(structBinTree *tree)
{
?????? printf("遞歸中序遍歷二叉樹 : ");
?????? __inOrder(tree->root);
?????? printf("\n");
?????? return 0;
}
?
?
int__inOrder(struct BinTreeNode *t)
{
?????? struct BinTreeNode *p = t;
?????? struct Stack stack;
?????? initStack(&stack);
?????? push(&stack, p);
?????? while(!isEmpty(&stack))
?????? {
????????????? while(p->leftChild != NULL)
????????????? {
???????????????????? p = p->leftChild;
???????????????????? push(&stack, p);
????????????? }
????????????? getHead(&stack, &p);
????????????? pop(&stack);
????????????? printf("%c",p->data);
????????????? if(p->rightChild != NULL)
????????????? {
???????????????????? p = p->rightChilsd;
???????????????????? push(&stack, p);
????????????? }
?????? }
?????? return 0;
}
5.????Main.c
#include"BinTree.h"
?
int main(int argc,char &argv)
{
?????? struct BinTree tree;
?????? // 初始化二叉樹
?????? initBinTree(&tree);
?????? // 創建二叉樹
?????? createBinTree(&tree);
?????? // 非遞歸前序遍歷
?????? preOrder(&tree);
?????? // 非遞歸中序遍歷
?????? inOrder(&tree);
?????? // 非遞歸后續遍歷
?????? postOrder(&tree);
?????? return 0;
}
二. 非遞歸后序遍歷
1.????Stack.h
#ifndef__STACK_H__
#define__STACK_H__
#include<stdio.h>
#include<stdlib.h>
// 棧的初始化大小
#defineSTACK_INIT_SIZE 8
// 棧滿的時候增加的容量
#defineSTACK_INCR_SIZE 8
// 重命名了棧中數據元素的數據類型
typedef structStackNode StackElemType;
// 定義了棧的結構
typedef structStack
{
?????? StackElemType *base;????? //??? 棧底指針
?????? StackElemType *top;???????? // ? 棧頂指針
?????? int capacity;?????????????? //??? 棧的容量
}Stack;
?
// 配合后續遍歷使用棧中保存的數據類型
typedefenum{L,R}FLAG;
typedef structStackNode
{
?????? struct BinTreeNode *brAddress;
?????? FLAG flag;
}StackNode;
?
// 棧中函數的聲明
intinitStack(struct Stack *);
intincrStack(struct Stack *);
int isEmpty(structStack *);
int isFull(structStack *);
int push(structStack *, StackElemType);
int pop(structStack *);
int getHead(structStack *, StackElemType);
#endif
2.????Stack.c
同上
3.????BinTree.h
同上
4.????BinTree.c
// 后序遍歷二叉樹
intpostOrder(struct BinTree *tree)
{
?????? printf("遞歸中序遍歷二叉樹 : ");
??????
?????? __postOrder(tree->root);
??????
?????? printf("\n");
?????? return 0;
}
?
?
int__postOrder(struct BinTreeNode *t)
{
?????? struct BinTreeNode *p = t;
?????? struct Stack stack;
?????? initStack(&stack);
?????? struct StackNode stNode;
?
?????? do
?????? {
????????????? while(p != NULL)
????????????? {
???????????????????? stNode.btAddress = p;
???????????????????? stNode.flag = L;
???????????????????? push(&stack, stNode);
???????????????????? p = p->leftChild;
????????????? }
?????????????
????????????? getHead(&stack, &stNode);
????????????? pop(&stack);
?????????????
????????????? if(stNode.flag == R)
????????????? {
???????????????????? printf("%c",stNode.brAddress->data);
???????????????????? continue;
????????????? }
????????????? if(stNode.flag = L)
????????????? {
???????????????????? stNode.flag = R;
???????????????????? push(&stack, stNode);
???????????????????? p =stNode.btAddress->rightChild;
????????????? }
?????????????
?????????????
?????????????
?????? }while(!isEmpty(&stack));
??????
}
其余代碼同上
5.????Main.c
同上
?
總結
以上是生活随笔為你收集整理的二叉树的链式结构的非递归遍历的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二叉树的链式结构递归遍历实现
- 下一篇: bit 位图