二叉树线索化及其遍历方法
2018-02-27 15:00
239 查看
代码
#include<stdio.h> #include<stdlib.h> #include<Windows.h> #include<assert.h> typedef char DataType; typedef enum { LINK, THREAD }PointFlag; typedef struct BinTreeNode { struct BinTreeNode* _pLeft; struct BinTreeNode* _pRight; struct BinTreeNode* _pParent; DataType _data; PointFlag _leftThread; PointFlag _rightThread; }Node, *PNode; void InitBinTree(PNode pRoot) { pRoot = 0; } PNode BuyNode(DataType data) { PNode pNewNode = (PNode)malloc(sizeof(Node)); assert(pNewNode); pNewNode->_pLeft = NULL; pNewNode->_pRight = NULL; pNewNode->_pParent = NULL; pNewNode->_data = data; pNewNode->_leftThread = LINK; pNewNode->_rightThread = LINK; return pNewNode; } //二叉树创建 void _CreateBinTree(PNode* pRoot, DataType array[], int size, int* index, DataType invalid) { assert(index); if (*index < size && array[*index] != invalid) { *pRoot = BuyNode(array[*index]); (*index)++; _CreateBinTree(&(*pRoot)->_pLeft, array, size, index, invalid); if((*pRoot)->_pLeft) (*pRoot)->_pLeft->_pParent = (*pRoot); (*index)++; _CreateBinTree(&(*pRoot)->_pRight, array, size, index, invalid); if ((*pRoot)->_pRight) (*pRoot)->_pRight->_pParent = (*pRoot); } } void CreateBinTree(PNode* pRoot, DataType array[], int size, DataType invalid) { int index = 0; _CreateBinTree(pRoot, array, size, &index, invalid); } //前序线索化 void _PreOrderThd(PNode pRoot, PNode* prev) { if (pRoot) { if (NULL == pRoot->_pLeft)//1.处理当前结点的左指针域 { pRoot->_pLeft = (*prev); pRoot->_leftThread = THREAD; } if ((*prev) && NULL == (*prev)->_pRight)//2.处理前一个结点的右指针域 { (*prev)->_pRight = pRoot; (*prev)->_rightThread = THREAD; } (*prev) = pRoot;//3.更新 *prev if (pRoot->_leftThread == LINK)//4.线索化当前指针的左子树 _PreOrderThd(pRoot->_pLeft, prev); if (pRoot->_rightThread == LINK)//5.线索化当前指针的右子树 _PreOrderThd(pRoot->_pRight, prev); } } void PreOrderThd(PNode pRoot) { PNode prev = NULL; _PreOrderThd(pRoot, &prev); } //中序线索化 void _InOrderThd(PNode pRoot, PNode* prev) { if (pRoot) { //1.线索化当前结点的左子树 _InOrderThd(pRoot->_pLeft, prev); //2.处理当前结点的左指针域 if (NULL == pRoot->_pL c6d5 eft) { pRoot->_pLeft = (*prev); pRoot->_leftThread = THREAD; } //3.处理前一个结点的右指针域 if ((*prev) && NULL == (*prev)->_pRight) { (*prev)->_pRight = pRoot; (*prev)->_rightThread = THREAD; } //4.更新前一个结点 (*prev) = pRoot; //5.线索化当前指针的右子树 if(pRoot->_rightThread == LINK) _InOrderThd(pRoot->_pRight, prev); } } void InOrderThd(PNode pRoot) { PNode prev = NULL; _InOrderThd(pRoot, &prev); } //后续线索化 void _PostOrderThd(PNode pRoot, PNode* prev) { if (pRoot) { _PostOrderThd(pRoot->_pLeft, prev);//线索化当前结点的左子树 _PostOrderThd(pRoot->_pRight, prev);//线索化当前结点的右子树 if (NULL == pRoot->_pLeft)//处理当前结点的左指针域 { pRoot->_pLeft = (*prev); pRoot->_leftThread = THREAD; } if ((*prev) && NULL == (*prev)->_pRight)//处理前一个结点的右指针域 { (*prev)->_pRight = pRoot; (*prev)->_rightThread = THREAD; } (*prev) = pRoot;//更新前一个结点指向下一个 } } void PostOrderThd(PNode pRoot) { PNode prev = NULL; _PostOrderThd(pRoot, &prev); } //前序递归遍历 void PreOrderD(PNode pRoot) { if (pRoot) { printf("%c ", pRoot->_data); PreOrderD(pRoot->_pLeft); PreOrderD(pRoot->_pRight); } } //线索化前序遍历 void PreOrder(PNode pRoot) { PNode pCur = pRoot; while (pCur) { while (pCur->_leftThread == LINK) { printf("%c ", pCur->_data); pCur = pCur->_pLeft; } printf("%c ", pCur->_data); pCur = pCur->_pRight; } } //中序递归遍历 void InOrderD(PNode pRoot) { if (pRoot) { InOrderD(pRoot->_pLeft); printf("%c ", pRoot->_data); InOrderD(pRoot->_pRight); } } //线索化中序遍历 void InOrder(PNode pRoot) { PNode pCur = pRoot; while (pCur) { while (pCur->_leftThread == LINK)//取最左边的结点 { pCur = pCur->_pLeft; } //当且结点的左子树已处理完毕 printf("%c ", pCur->_data);//处理当前结点 while (pCur->_rightThread == THREAD)//开始处理后续结点,转移到右子树(访问连载一起的后续结点) { pCur = pCur->_pRight; printf("%c ", pCur->_data); } pCur = pCur->_pRight;//开始处理当前结点的右子树 } } //后续递归遍历 void PostOrderD(PNode pRoot) { if (pRoot) { PostOrderD(pRoot->_pLeft); PostOrderD(pRoot->_pRight); printf("%c ", pRoot->_data); } } //线索化后续遍历 void PostOrder(PNode pRoot) { PNode pCur = pRoot; PNode prev = NULL; while (pCur) { while (pCur && pCur->_leftThread == LINK)//找到最左边的结点 pCur = pCur->_pLeft; while (pCur->_rightThread == THREAD)//访问连载一起的后续结点 { printf("%c ", pCur->_data); prev = pCur; pCur = pCur->_pRight; } if (pCur == pRoot && (NULL == pCur->_pRight || prev == pCur->_pRight))//根节点 { printf("%c ", pCur->_data); return; } while (pCur && pCur->_pRight == prev)//访问当前结点 { printf("%c ", pCur->_data); prev = pCur; pCur = pCur->_pParent; } if (pCur && pCur->_rightThread == LINK)//开始访问右子树 { pCur = pCur->_pRight; } } } int main() { char array[] = { 'A','B','D','#','#','#','C','E','#','#','F' }; PNode pRoot = NULL; CreateBinTree(&pRoot, array, sizeof(array) / sizeof(array[0]), '#'); //前序线索化 PreOrderD(pRoot); printf("\n"); PreOrderThd(pRoot); PreOrder(pRoot); printf("\n"); //中序线索化 //InOrderD(pRoot); //printf("\n"); //InOrderThd(pRoot); //InOrder(pRoot); //printf("\n"); //后续线索化 //PostOrderD(pRoot); //printf("\n"); //PostOrderThd(pRoot); //PostOrder(pRoot); //printf("\n"); system("pause"); return 0; }
相关文章推荐
- 二叉树线索化、遍历的实现及其原理
- 算法与数据结构(三) 二叉树的遍历及其线索化(Swift版)
- 【C++】二叉树的创建方法及其遍历的递归与非递归方法总结
- 二叉树前序、中序和后序的遍历方法(递归、用栈和使用线索化)
- 二叉树的先序,中序,后序及其非递归遍历的方法
- C++实现二叉树及其线索化和遍历
- 二叉树的各种遍历方法
- 二叉树的四种遍历 (六个方法递归 非递归都有 包含二叉树的创建java方法)
- 关于二叉树的几种遍历方法
- Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
- 二叉树的创建以及遍历方法
- Robson方法遍历二叉树
- java实现二叉树的构建以及3种遍历方法
- C++之二叉树的创建、查找、四种次序的周游遍历方法以及内存的释放
- 二叉树先序遍历,中序遍历,后序遍历递归非递归方法
- 二叉树的循环遍历方法,Java实现。利用栈和arraylist
- java 遍历arrayList的四种方法及其效率对比
- 二叉树的三种遍历方法(递归和非递归)
- Java List遍历方法 及其效率对比
- java实现二叉树的建立及遍历方法