#include <stdio.h>
#include <stdlib.h>
typedef struct btree bt;
struct btree {
    int _val;
    int _count;
    bt *_lc;
    bt *_rc;
};
 * 挂载节点
 * @param head 二叉树的根节点的指针
 * @param val 待插叙节点的值
 */
void insert(bt *const head, int const val) {
    bt *node = malloc(sizeof(bt));
    node->_val = val;
    node->_count = 1;
    node->_lc = NULL;
    node->_rc = NULL;
    bt *tmp = head;
    while (1) {
        if (tmp->_val == val) {
            tmp->_count++;
            return;
        } else if (tmp->_val > val) {
            if (tmp->_lc == NULL)
                break;
            else
                tmp = tmp->_lc;
        } else {
            if (tmp->_rc == NULL)
                break;
            else
                tmp = tmp->_rc;
        }
    }
    if (tmp->_val > val)
        tmp->_lc = node;
    else
        tmp->_rc = node;
}
 * 构建二叉树
 * @param arr 构建二叉树的输入-数组
 * @param len 数组的长度
 * @return 二叉树根节点的指针
 */
bt *buildTree(int const * const arr, size_t const len) {
    bt *head = malloc(sizeof(bt));
    head->_val = *arr;
    head->_count = 1;
    head->_lc = NULL;
    head->_rc = NULL;
    int i;
    for (i = 1; i < len; ++i) {
        insert(head, *(arr + i));
    }
    return head;
}
 * 中序遍历(采用的递归算法)
 * @param node 当前的"根"节点指针
 */
void travelMidSeq(bt const * const node) {
    if (node->_lc != NULL)
        travelMidSeq(node->_lc);
    int i;
    int len = node->_count;
    for (i = 0; i < len; ++i)
        printf("%d ", node->_val);
    if (node->_rc != NULL)
        travelMidSeq(node->_rc);
}
 * 释放资源(递归算法)---实质就是后续遍历的算法
 * @param node 当前需要处理的节点指针
 */
void releaseTree(bt *node) {
    if (node->_lc != NULL)
        releaseTree(node->_lc);
    if (node->_rc != NULL)
        releaseTree(node->_rc);
    free(node);
}
typedef struct linkNode ln;
struct linkNode {
    bt *_node;
    ln *_next;
};
typedef struct linkList mQueue;
struct linkList {
    ln *_head;
    ln *_tail;
    
    ln *(*removeFirstAndAddItsChilds)(mQueue const * const queue);
};
 * 按传入的二叉树节点指针构造一个新的链表节点
 * @param bt_node 二叉树节点指针
 * @return 构造的新链表节点指针
 */
ln *makeNode(bt const * const bt_node) {
    ln *node = (ln *) malloc(sizeof(ln));
    node->_node = bt_node;
    return node;
}
 * 移除队列(链表实现)首元素并添加该首元素在二叉树中的两个子节点入队列的函数指针
 * @param queue 队列的指针
 * @return 移除的队列元素的指针
 */
ln *removeFirstAndAddItsChilds(mQueue const *queue) {
    ln *first = queue->_head->_next;
    
    ln *nl = NULL;
    ln *nr = NULL;
    if (first->_node->_lc)
        nl = makeNode(first->_node->_lc);
    if (first->_node->_rc)
        nr = makeNode(first->_node->_rc);
    ln *curTail = queue->_tail->_next;
    if (queue->_tail->_next) {
        if (queue->_head->_next == queue->_tail->_next) {
            
            if (nl) {
                queue->_head->_next = nl;
                if (nr)
                    queue->_tail->_next = queue->_head->_next->_next = nr;
                else
                    queue->_tail->_next = nl;
            } else if (nr)
                queue->_tail->_next = queue->_head->_next = nr;
            else 
                queue->_head->_next = queue->_tail->_next = NULL;
        } else {
            queue->_head->_next = first->_next;
            if (nl) {
                queue->_tail->_next->_next = nl;
                if (nr)
                    queue->_tail->_next = queue->_tail->_next->_next->_next = nr;
                else
                    queue->_tail->_next = nl;
            } else if (nr)
                queue->_tail->_next = queue->_tail->_next->_next = nr;
        }
    }
    return first;
}
 * 二叉树的按层遍历
 * @param root 二叉树根节点的指针
 * @param head 队列的头指针
 * @param tail 队列的位置针
 */
void layerTravel(bt const * const root, ln *const head, ln *const tail) {
    mQueue queue = {head, tail, removeFirstAndAddItsChilds};
    ln *n = makeNode(root);
    n->_node = root;
    n->_next = NULL;
    head->_next = n;
    tail->_next = n;
    while (queue._head->_next) {
        ln *result = queue.removeFirstAndAddItsChilds(&queue);
        int i;
        int len = result->_node->_count;
        for (i = 0; i < len; ++i)
            printf("%d ", result->_node->_val);
        free(result);
    }
}
int main(void) {
    int arr[] = {8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15};
    int len = sizeof(arr) / sizeof(int);
    bt *tree = buildTree(arr, len);
    printf("middle sequence travel result :\n");
    travelMidSeq(tree);
    printf("\nlayer sequence travel result:\n");
    ln head = {NULL, NULL};
    ln tail = {NULL, NULL};
    layerTravel(tree, &head, &tail);
    releaseTree(tree);
    return 0;
}