樹3-二叉樹非遞迴遍歷(棧)
複製根結點, 初始值FALSE, 入棧
彈出, 如果是FALSE,
將根節點將更新為TRUE, 其子結點(初始值FALSE)一併入棧
[A,B,C] (前序遍歷, 入棧順序:C,B,A 輸出順序: A,B,C)
再彈出, 如果是TRUE則輸出
引入鏈式棧標頭檔案
#include "linkedStack.h"
鏈式棧標頭檔案
#ifndef LINKEDSTACK_H
#define LINKEDSTACK_H
#include <stdlib.h>
//鏈式棧的結點
typedef struct LinkNode{
struct LinkNode *next;
} LinkNode;
//鏈式棧
typedef struct LinkStack{
LinkNode head; //鏈式棧的頭結點
int size; //棧的元素數量
} LinkStack;
//初始化
LinkStack* Init_LinkStack(){
LinkStack *stack = (LinkStack*)malloc(sizeof(LinkStack));
stack->head.next = NULL;
stack->size=0;
return stack;
};
//入棧(頭插法)
void Push_LinkStack(LinkStack* stack, LinkNode *data){
if(stack==NULL) return;
if(data==NULL) return;
//插入結點的後繼指向第一個結點
data->next = stack->head.next;
//頭結點的後繼指向插入結點
stack->head.next = data;
//鏈式棧長度++
stack->size++;
};
//返回棧頂元素
LinkNode* Top_LinkStack(LinkStack* stack){
if(stack==NULL) return NULL;
if(stack->size==0) return NULL;
return stack->head.next;
};
//出棧
void Pop_LinkStack(LinkStack* stack){
if(stack==NULL) return;
if(stack->size==0) return;
//第一個有效結點
LinkNode *pNext = stack->head.next;
//刪除第一個有效結點(跳過)
stack->head.next = pNext->next;
//鏈式棧長度--
stack->size--;
};
//返回棧元素個數
int Size_LinkStack(LinkStack* stack){
if(stack==NULL) return -1;
return stack->size;
};
//清空
void Clear_LinkStack(LinkStack* stack){
if(stack==NULL) return;
stack->head.next = NULL;
stack->size = 0;
};
//銷燬
void FreeSpace_LinkStack(LinkStack*
二叉樹結點
//二叉樹結點
typedef struct BinaryNode{
char ch;
struct BinaryNode *lChild;
struct BinaryNode *rChild;
} BinaryNode;
鏈式棧結點
//棧結點
typedef struct BiTreeStackNode{
LinkNode node; //支援鏈式棧的必要部分 (為什麼不是指標?)
BinaryNode* root; //二叉樹結點
int flag;
} BiTreeStackNode;
建立棧中的結點
//建立棧中的結點
BiTreeStackNode* CreateBiTreeStackNode(BinaryNode *node, int flag){
//將二叉樹結點作為元素壓入棧中
BiTreeStackNode *newNode = (BiTreeStackNode*)malloc(sizeof(BiTreeStackNode));
newNode->root = node;
newNode->flag = flag;
return newNode;
}
非遞迴遍歷
//非遞迴遍歷
void NonRecursion(BinaryNode* root){
//建立棧
LinkStack *stack = Init_LinkStack();
//把根節點扔進棧中(初始化為FALSE)
Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(root, MY_FALSE));
//棧非空時, 遍歷
while(Size_LinkStack(stack)>0){
//取出棧頂元素
BiTreeStackNode *node = (BiTreeStackNode*)Top_LinkStack(stack);
//彈出棧頂元素
Pop_LinkStack(stack);
//是否彈出的結點是否為空, 為空則跳過這次迴圈
if(node->root==NULL){
continue;
}
//判斷結點的flag, 如果true, 輸出
if(node->flag==MY_TRUE){
cout << node->root->ch << " ";
}else{// false, 更新根節點flag+左右子樹壓棧
//當前結點的右結點入棧
Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(node->root->rChild, MY_FALSE));
//當前結點的左結點入棧
Push_LinkStack(stack, (LinkNode*)CreateBiTreeStackNode(node->root->lChild, MY_FALSE));
//根節點更新為TRUE
node->flag = MY_TRUE;
Push_LinkStack(stack, (LinkNode*)node);
}
}
cout << endl;
}
釋放二叉樹
//釋放二叉樹
void FreeSpaceBinaryTree(BinaryNode* root){
if(root==NULL) return;
//釋放左子樹
FreeSpaceBinaryTree(root->lChild);
//釋放右子樹
FreeSpaceBinaryTree(root->rChild);
//釋放當前結點
free(root);
}
建立二叉樹
void CreateBinaryTree(){
//建立結點
BinaryNode node1 = {'A',NULL,NULL};
BinaryNode node2 = {'B',NULL,NULL};
BinaryNode node3 = {'C',NULL,NULL};
BinaryNode node4 = {'D',NULL,NULL};
BinaryNode node5 = {'E',NULL,NULL};
BinaryNode node6 = {'F',NULL,NULL};
BinaryNode node7 = {'G',NULL,NULL};
BinaryNode node8 = {'H',NULL,NULL};
//建立結點關係
node1.lChild = &node2;
node2.rChild = &node3;
node3.lChild = &node4;
node3.rChild = &node5;
node1.rChild = &node6;
node6.rChild = &node7;
node7.rChild = &node8;
//二叉樹非遞迴輸出
NonRecursion(&node1);
FreeSpaceBinaryTree(&node1);
}
測試
int main(){
CreateBinaryTree();
cout << endl;
system("pause");
return 0;
}