二叉树的链表实现

二叉树的链表实现

在构建二叉树时使用完全二叉树的特性,所以构建的是一颗完全二叉树

打印二叉树

打印完全二叉树要使用队列结构保存序列。将根节点存入队列,然后在while循环中将队列的第一个元素出队并将其右孩子和左孩子依次入队(如果不为null),这样的入队的顺序就按层按从左到右的顺序,出队亦是。所以可以通过调整入队顺序改变遍历顺序.以此循环遍历root及其子树,循环的条件是队列不为null.

//print tree
void printTree(treeLink *root){
    int height = getHeight(root);//树的高度,层数

    int count = 0,length = 1;//换行计数

    int k;//元素间距

    treeLink *node;//遍历树的指针

    treeList *head = newTreeList();//空顺序表

    addTree(head,root);//将root(根)入队

    //k 的值用于控制tree node 间距,当从root节点向下打印时, k是递减的,k的递减规律是: n = (n+1) - 2^n ;(n 是当前层数,n-1表示上一层,root的层数n = 数的高度,n从叶子(最末端)向根节点计数.  (2^n == 1<
    k = (1 << (height+1)) - 1;
    k = k - (1 << height);

    if(root == NULL){
        return;//如果是空树直接返回
    }

    while((node = getTree(head)) != NULL){

        printCH2(k);//打印空格方法
        printf("%d",node->data);//打印元素,每个元素前后要打印空格.
        printCH2(k);

        count++;

        //判断是否打印空格,调整层数
        if(count == length){
            printf("\n\n");

            count = 0;
            length *=2;

            height--;
            k = k - (1 << height);

        }

        //将当前节点的左右孩子入队
        //if(node->Lchild)
        addTree(head,node->Lchild);
        addTree(head,node->Rchild);

        //将当前节点出队
        popTree(head);
    }
    printf("\n");
}
//打印结果
/*
               1

       2              3

   4      5      6       7

 8  9  10  11

*/

树的结构定义

//treeLink node
typedef struct treeLink{
    int data;
    struct treeLink *Lchild, *parent, *Rchild;
}treeLink;

完整实现代码

注:不含在打印树时用到顺序表结构及函数

//创建treeLink节点
treeLink *newTreeNode(int data){
    treeLink *node = (treeLink *)malloc(sizeof(treeLink));

    node->data = data;
    node->parent = NULL;
    node->Lchild = NULL;
    node->Rchild = NULL;
    return node;
}


void add(treeLink *node){
    if(node->data > 5)return;

    node->Lchild = newTreeNode(node->data*2);
    node->Rchild = newTreeNode(node->data*2+1);
    add(node->Lchild);
    add(node->Rchild);
}

//建树
void create(treeLink **root){
    *root = newTreeNode(1);
    add(*root);
}

//求深度
int getHeight(treeLink *root){
    int count = 0;
    while(root != NULL){
        count++;
        root = root->Lchild;
    }
    return count;
}

//先序遍历
void perorder(treeLink *node){
    if(node != NULL){
        printf("%d  ",node->data);
        perorder(node->Lchild);
        perorder(node->Rchild);
    }
}

//中序遍历
void inorder(treeLink *node){
    if(node != NULL){

        inorder(node->Lchild);
        printf("%d  ",node->data);
        inorder (node->Rchild);
    }
}

//后序遍历
void postorder (treeLink *node){
    if(node != NULL){

        postorder (node->Lchild);
        postorder (node->Rchild);
        printf("%d  ",node->data);
    }
}

//遍历的非递归实现:要借助栈结构,按遍历顺序逆向压栈,顺序出栈
void perorder3(treeLink *root){
    int top = 0, len = 50;
    treeLink *node;
    treeLink *arr[50];
    arr[top] = root;
    while (top > -1 && top < len-1){
        node = arr[top--];
        printf("%d  ",node->data);

        if(node->Lchild != NULL)
        arr[++top] = node->Rchild;

        if(node->Rchild != NULL)
        arr[++top] = node->Lchild;
    }
}

//打印空格
void printCH2(int k){
    char ch = ' ';

        while(k){
            printf("%c",ch);
            k--;
        }
}


void TreeLinkTest(){
    treeLink *root = NULL;
    create(&root);

    printTree(root);
    printf("\n先序\n");
    perorder(root);
    printf("\n先序\n");
    perorder3(root);
    printf("\n中序\n");
    inorder(root);
    printf("\n后序\n");
    postorder(root);
}

你可能感兴趣的:(数据结构,二叉树,打印二叉树,完全二叉树)