C语言创建二叉树数据结构, 以及各种遍历
RT,上数据结构课时写的, 注释后面再补上.
上课时, 听得不是很认真, 先放在这里, 等后面再来慢慢理解.
使用时, 首先会创建根结点, 依次创建左孩子, 左孩子.
输入0表示该结点为空.
创建左/右孩子的时候, 又把左/右孩子当作根结点, 递归创建属于它们的左右孩子.
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct BiTree{ int data; struct BiTree* lchild; struct BiTree* rchild; }BiTree, *PBiTree; typedef struct Stack{ BiTree* data[128]; int top; }Stack; void stack_init(Stack* pStack) { memset(pStack, 0, sizeof(Stack)); pStack->top = -1; } BiTree* stack_pop(Stack* pStack) { if(pStack->top == -1) return NULL; return pStack->data[pStack->top--]; } BiTree* stack_get_top(Stack* pStack) { if(pStack->top == -1) return NULL; else return pStack->data[pStack->top]; } int stack_push(Stack* pStack, BiTree* pBiTree) { if(pStack->top == 127) return 0; pStack->data[++pStack->top] = pBiTree; return 1; } int stack_is_empty(Stack* pStack) { return pStack->top == -1; } int bitree_create(BiTree** ppBiTree) { int data; for(;;){ printf("输入节点的值:"); if(scanf("%d", &data) == 1) break; fflush(stdin); } if(data == 0){ (*ppBiTree) = NULL; return 1; }else{ (*ppBiTree) = (PBiTree)malloc(sizeof(BiTree)); if(!*ppBiTree){ perror("内存分配失败"); return 0; }else{ memset(*ppBiTree, 0, sizeof(BiTree)); (*ppBiTree)->data = data; bitree_create(&(*ppBiTree)->lchild); bitree_create(&(*ppBiTree)->rchild); } } return 1; } //释放二叉树 void bitree_free(BiTree* pBiTree) { if(pBiTree){ bitree_free(pBiTree->lchild); bitree_free(pBiTree->rchild); free(pBiTree); pBiTree = NULL; } } /*先序遍历非递归算法*/ void PreOrderTraverse(BiTree* pBiTree) { Stack stk; BiTree* pb = pBiTree; stack_init(&stk); while(pb || !stack_is_empty(&stk)){ while(pb){ printf("%d ", pb->data); stack_push(&stk, pb); pb = pb->lchild; } pb = stack_pop(&stk); pb = pb->rchild; } } /*先序遍历递归算法*/ void PreOrderTraverse2(BiTree* pBiTree) { if(pBiTree){ printf("%d ", pBiTree->data);//显示数据 PreOrderTraverse2(pBiTree->lchild);//访问左孩子 PreOrderTraverse2(pBiTree->rchild);//访问右孩子 } } /* 中序遍历递归算法 */ void InOrderTraverse2(BiTree* pBiTree) { if(pBiTree){ InOrderTraverse2(pBiTree->lchild); printf("%d ", pBiTree->data); InOrderTraverse2(pBiTree->rchild); } } /* 中序遍历递归算法2 */ void InOrderTraverse3(BiTree* pBiTree) { Stack stk; BiTree* pb = NULL; stack_init(&stk); pb = pBiTree; while(pb || !stack_is_empty(&stk)){ if(pb){ stack_push(&stk, pb);//根指针进栈 pb = pb->lchild;//遍历左子树 }else{ //根指针出栈, 访问根结点, 遍历右子树 pb = stack_pop(&stk); printf("%d ", pb->data); pb = pb->rchild; } } } /* 中序遍历非递归算法 */ void InOrderTraverse(BiTree* pBiTree) { Stack stk; BiTree* pb = NULL; stack_init(&stk);//保存结点的栈 stack_push(&stk, pBiTree);//根指针进栈 while(!stack_is_empty(&stk)){ while((pb=stack_get_top(&stk))) stack_push(&stk, pb->lchild);//向左走到尽头 pb = stack_pop(&stk);//最后一个空指针出栈 if(!stack_is_empty(&stk)){ pb = stack_pop(&stk);//得到最后一个结点/左孩子 printf("%d ", pb->data); stack_push(&stk, pb->rchild);//访问右孩子 } } } /* 后序遍历非递归算法 */ void PostOrderTraverse(BiTree* pBiTree) { Stack stk; BiTree* pb = NULL; BiTree* pre = NULL; stack_init(&stk); while(pBiTree || !stack_is_empty(&stk)){ while(pBiTree){ stack_push(&stk, pBiTree); pBiTree = pBiTree->lchild; } pBiTree = stack_get_top(&stk); if(!pBiTree->rchild || pBiTree->rchild == pre){ printf("%d ", pBiTree->data); stack_pop(&stk); pre = pBiTree; pBiTree = NULL; }else{ pBiTree = pBiTree->rchild; } } } /* 后序遍历递归算法 */ void PostOrderTraverse2(BiTree* pBiTree) { if(pBiTree){ PostOrderTraverse(pBiTree->lchild); PostOrderTraverse(pBiTree->rchild); printf("%d ", pBiTree->data); } } int main(void) { BiTree* pbt = NULL; bitree_create(&pbt); printf("\n"); printf("先序遍历非递归算法:\t"); PreOrderTraverse(pbt); printf("\n"); printf("先序遍历递归算法:\t"); PreOrderTraverse2(pbt); printf("\n"); printf("中序遍历非递归算法:\t"); InOrderTraverse(pbt); printf("\n"); printf("中序遍历递归算法:\t"); InOrderTraverse2(pbt); printf("\n"); //printf("中序遍历递归算法2:\t"); //InOrderTraverse3(pbt); //printf("\n"); printf("后序遍历非递归算法:\t"); PostOrderTraverse(pbt); printf("\n"); printf("后序遍历递归算法:\t"); PostOrderTraverse2(pbt); printf("\n"); printf("\n"); bitree_free(pbt); system("pause"); return 0; }