BinaryTree-遞歸遍歷&建樹--C語言

  • 定義BinaryTree結構
  • 測試用例
  • 遞歸前中後遍歷
  • 中前 中後建樹
  • 層序 葉子結點 雙親結點

代碼塊

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef char ELELTYPE; 

//定義結構體
typedef struct 
{
    ElemType data;
    BtNode *leftchild;
    BtNode *rightchild;
}BtNode,*BinaryTree;

//申請結點
BtNode * Buynode()
{
    BtNode *s = (BtNode*)malloc(sizeof(BtNode));
    if(s == NULL) exit(1);
    memset(s,0,sizeof(BtNode)); //memset 以字節爲單位初始化
    return s;
}

//釋放結點
void Freenode(BtNode *p)
{
    free(p);
}

//遞歸先序遍歷二叉樹
void PreOrder(BtNode *ptr)
{
    if(ptr!=NULL)
    {
        printf("%c",ptr->data);
        PreOrder(ptr->leftchild);
        PreOrder(ptr->rightchild);
    }
}

//遞歸中序遍歷二叉樹
void InOrder(BtNode *ptr)
{
    if(ptr!=NULL)
    {
        InOrder(ptr->leftchild);
        printf("%c",ptr->data);
        InOrder(ptr->rightchild);
    }
}

//遞歸後序遍歷二叉樹
void PastOrder(BtNode *ptr)
{
    if(ptr!=NULL)
    {
        PastOrder(ptr->leftchild);
        PastOrder(ptr->rightchild);
        printf("%c",ptr->data);
    }
}

//創建二叉樹方式一:屏幕讀入 ABC##DE##F##G#H##  (#代表null)
BtNode * CreateTree1()
{
    BtNode *s = NULL;
    ElemType item;
    scanf("%c",&item);
    if(item != '#')
    {
        s = Buynode();
        s->data = item;
        s->leftchild = CreateTree1();
        s->rightchild = CreateTree1();
    }
    return s;
}

//創建二叉樹方式二:二級指針 字符串
BtNode * CreateTree3(char ** const pstr)
{
    BtNode *s = NULL;
    // 二級指針       一級指針      值
    if(pstr!=NULL && *pstr!=NULL && **pstr!='#')
    {
        s=Buynode();
        s->data= **pstr;
        s->leftchild = CreateTree3(&++*pstr);
        s->rightchild = CreateTree3(&++*pstr);
    }
    return s;
}

//方式三:中序 前序 創建二叉樹
int Find(char *is,int n,char ch)
{
    for(int i = 0;i<n;++i)  //在中序找到pos
    {
        if(is[i]==ch)
        {
        return i;
        }
    }
        return -1;
}

BtNode * Create(char *ps,char *is,int n)
{
    BtNode *s = NULL ;
    if(n>0)
    {
        s=Buynode();
        s->data = ps[0];
        int pos = Find(is,n,ps[0]);
        if(pos==-1){exit(1);}
        //創建左子樹(search,searchLine,len)
        s->leftchild = Create(ps+1,is,pos);  
        //創建右子樹 (search,searchLine,len)
        s->rightchild = Create(ps+pos+1,is+pos+1,n-pos-1);
    }
    return s;
}

BtNode * CreatePI(char *ps,char *is)
{
    if(ps==NULL || is == NULL)
    {
        return NULL;
    }
    else
    {
        int n = strlen(ps);
        Create(ps,is,n);
    }
}

// 方式四:中序 後序 創建二叉樹
BtNode * CreateTree(char *ls,char *is,int n)
{
    BtNode *s =NULL;
    if(n>0)
    {
        int pos = Find(is,n,ls[n-1]);
        if(pos==-1){exit(1);}
        s=Buynode();
        s->data = ls[n-1];

        s->leftchild=CreateTree(ls,is,pos);
        s->rightchild = CreateTree(ls+pos,is+pos+1,n-pos-1);
    }
    return s;

}
BtNode * CreateIL(char *is,char *ls)
{
    if(is==NULL || ls== NULL)
    {
        return NULL;
    }else
    {
        int m = strlen(ls); //is
        CreateTree(ls,is,m);
    }
}
BtNode *FindValue(BtNode *ptr,ElemType x)
{
    if(ptr==NULL || ptr->data==x)
    {
        return ptr;
    }
    else{
        BtNode *p=FindValue(ptr->leftchild,x);
        if(p==NULL){
            FindValue(ptr->rightchild,x);
        }
        return p;
    }
}

//層序遍歷二叉樹
int front = 0,rear =1;
void LevelOrder(BtNode *ptr)
{
    BtNode *q[100];
    q[0]=ptr;
    while(front<rear)
    {
        if(q[front]){
            printf("%c",q[front]->data);
            q[rear++]=q[front]->leftchild;
            q[rear++]=q[front]->rightchild;
            front++;
        }
        else
        {
            front++;
        }
    }
}

//雙分支結點的個數
int SizeBinary(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return -1;
    }
    else
    {
        if(ptr->leftchild != NULL && ptr->rightchild != NULL)
        {
            ++count;
            SizeBinary(ptr->leftchild);
            SizeBinary(ptr->rightchild);
        }else
        {
            if(ptr->leftchild == NULL)
            {
                SizeBinary(ptr->rightchild);
            }else
            {
                SizeBinary(ptr->rightchild);
            }
        }
    }
}

//尋找孩子結點的雙親結點
BtNode * Paret(BtNode *ptr,BtNode *child){
    if(ptr == NULL || ptr->leftchild ==child || ptr->rightchild == child)
    {
    return ptr;
    }
    else{
        BtNode *p = Paret(ptr->leftchild,child);
        if(NULL == p)
        {
            Paret(ptr->rightchild,child);
        }
    }
}

BtNode * FindParet(BtNode *ptr,BtNode *child)
{
    if(ptr == NULL || child ==NULL || ptr==child)
    {
        return NULL;
    }
    else
    {
        return Paret(ptr,child);
    }
}


// 葉子結點個數
int SizeLeaf(BtNode *ptr)
{
    if(ptr == NULL)
    {
        return 0;
    }else if(ptr->leftchild==NULL && ptr->rightchild ==NULL)
    {
     return 1;  
    }
    else
    {
        return SizeLeaf(ptr->leftchild)+SizeLeaf(ptr->rightchild);
    }
}
//結點總個數
int Size(BtNode *ptr){
    if(ptr==NULL)
    {return 0;}
    return 1+Size(ptr->leftchild)+Size(ptr->rightchild);
}
// 樹的深度
int Depth(BtNode *ptr)
{
    if(ptr==NULL)
    {
        return 0;
    }
    int dl=Depth(ptr->leftchild);
    int dr=Depth(ptr->rightchild);
    return(dl>dr?dl:dr)+1;
}


void main()
{
    char *ps = "ABCDEFGH";//前
    char *is = "CBEDFAGH";//中
    char *ls = "CEFDBHGA";//後

    //輸入序列建樹 
    printf("請輸入先序序列1:\n");
    BinaryTree root = NULL;
    root = CreateTree1();

    //層序遍歷二叉樹
    LevelOrder(root);

    //查找
    //FindValue(root,'B');

    //equal比較兩樹結構相似 數據相等
    char *str = "ABC##DE##F##G#H##";
    char *ptr = "ABC##DE##F##H#G##";
    BinaryTree root1 = NULL;
    BinaryTree root2 = NULL;
    root1 = CreateTree3(&str);
    root2 = CreateTree3(&ptr);
    printf("%d\n",Equal(root1,root2));

    int n =Depth(root);

    //int &a = 100; // 常量 無地址 不能編譯通過
    //const int &a =100; //常引用開闢空間 
    //int a = 10;
    //int *ip = &a;
    //int *&is = ip;// 指針的 引用
    //int &*is; //不允許使用【指針】==》引用

    // 測試 後序 中序 建立二叉樹
    BinaryTree root4= NULL;
    root4 = CreateIL(is,ls);
    PreOrder(root);
    printf("\n");
    InOrder(root);
    printf("\n");
    PastOrder(root);
    printf("\n");

    //測試 前序 中序 創建二叉樹
    BinaryTree root5= NULL;
    root5= CreatePL(ps,is);
    PreOrder(root);
    printf("\n");
    InOrder(root);
    printf("\n");
    PastOrder(root);
    printf("\n");   
}

作業:
// obj1:大數的加減乘除取模判斷素數開方次方 文件加密的分佈式算法
設計文檔+功能函數+模塊設計
// obj2:哈夫曼編碼 基於哈夫曼編碼的文本文件解壓縮
// obj3:日曆系統 年月日 小時分 對日期進行操作 日程安排表


下次函數:
int SizeOne();
int SizeOneLeft();
int SizeOneRight();

Is_Full_BinaryTree(root); //滿二叉樹
bool Is_Comp_BinaryTree(BtNode *ptr); //完全二叉樹
bool Is_Balance_BinaryTree(BtNode *ptr); //平衡二叉樹

//非遞歸建樹 (is ls ps)
void NicePerOrder(BtNode *ptr);
void NiceInOrder(BtNode *ptr);
void NicePastOrder(BtNode *ptr);

// 找兩個結點的最近公共雙親結點
BtNode * FindNearParet(BtNode *ptr ,BtNode *child1,BtNode *child2);
// 找這個樹的最遠兩個結點的距離 返回兩個結點的地址 …可以用結構體存放 地址 + int
int maxPath(BtNode *ptr);
struct RetNode
{
BtNode *child1;
BtNode *child2;
int path;
};
RetNode RetPath(BtNode *ptr);
int RetTwoMaxPath(BtNode ptr,BtNode &child1,BtNode *&child2);

問題:
//引用和指針的區別 引用的特點:邏輯 物理上 分類
// 寫一個 棧 隊列 k隊列 無鎖隊列 棧滿擴容 堆區無空間??
//如何解決內存不足 單進程無問題 多進程的線程安全 效率 多線程共享
// ++ 葉子結點個數 左分支結點 右分支 雙分支??

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章