二叉树的链式存储结构--二叉链表
1 二叉树的链式存储结构
//二叉链表的结点结构定义
typedef int TElemType;
typedef struct BiTNode { TElemType data; struct BiTNode *lchild; struct BiTNode *rchild; }BiTNode; typedef struct BiTNode *BiTree;
结构示意图如下:
2 二叉树的遍历方法
(1)前序遍历:先访问根结,然后前序遍历左子树,再前序遍历右子树。下面这颗二叉树的前序遍历结果为ABDHKECFIGJ
//二叉树的前序遍历递归算法 void PreOrderTraverse(BiTree T) { if (T == NULL) { return } printf("%c", T->data); PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild); }
(2)中序遍历:先中序遍历左子树,然后访问根结点,最后再中序遍历右子树。上面这颗二叉树的中序遍历结果为HKDBEAIFCGJ
//二叉树的中序遍历递归算法 void InOrderTraverse(BiTree T) { if (T == NULL) { return } PreOrderTraverse(T->lchild); printf("%c", T->data); PreOrderTraverse(T->rchild); }
(3)后序遍历:先后续遍历左子树,再后续遍历右子树,最后访问根结点。上面这颗二叉树的后序遍历结果为KHDEBIFJGCA
//二叉树的后序遍历递归算法 void InOrderTraverse(BiTree T) { if (T == NULL) { return } PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild); printf("%c", T->data); }
3 二叉树的建立
如果我们要建立一个下图中左图这样的树,为了能让每个结点确认是否有左右孩子,我们对它进行了扩展,变成右图的样子。也就是将二叉树中没有结点的空指针引出一个续结点,其值为一个特定的值“#”。我们称这种处理过的二叉树为原二叉树的扩展二叉树。扩展二叉树就可以做到一个遍历序列确定一棵二叉树了。比如右图的遍历序列就为AB#D##C##。
我们把刚才前序遍历序列用键盘挨个输入,就创建出一棵二叉树了。
//按前序输入二叉树中结点的值 void createBiTree(BiTree *T) { TElemType ch; scanf("%d", &ch); if (ch == 0) { //0表示空结点 *T = NULL; } else { *T = (BiTree)malloc(sizeof(BiTNode)); if (!*T) { exit(OVERFLOW); } (*T)->data = ch; //生成根结点 createBiTree(&(*T)->lchild); //构造左子树 createBiTree(&(*T)->rchild); //构造右子树 } }
其实建立二叉树,也是利用了递归的思想。只不过在原来应该打印结点的地方,改成了生成结点,给结点赋值的操作而已。