二叉樹的鏈表實現


二叉樹的鏈表實現

在構建二叉樹時使用完全二叉樹的特性,所以構建的是一顆完全二叉樹

打印二叉樹

打印完全二叉樹要使用隊列結構保存序列。將根節點存入隊列,然后在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<<n)
    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); }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM