數據結構“樹”的常用代碼總結(C語言)

“樹”的常用代碼總結(數據結構)

首先本文采用的主要是採用二叉樹的二叉鏈表存儲

//二叉樹的二叉鏈表存儲表示

BiTNode 其實就是 Binary(二)Tree(樹) Node(結點)
包括 數據域左右孩子結點的指針域

typedef struct BiTNode
{
	char data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

//樹的二叉鏈表(孩子 - 兄弟)存儲表示

typedef struct CSNode
{
	int data;
	struct CSNode *firstchild, *nextsibling;
}CSNode, *CSTree;

//創建二叉樹(先序輸入&遞歸建立)

按先序遍歷順序輸入二叉樹的各個結點值,#表示空節點,建立二叉樹。

void CreatBiTree(BiTree &T)
{
	char ch;
	scanf("%c",&ch);
	if(ch == '#')
	{
        T = NULL;
	}
	else
	{
        T = (BiTree)malloc(sizeof(BiTNode));
        T->data = ch;
        CreatBiTree(T->lchild);
        CreatBiTree(T->rchild);
	}
}

//二叉樹遍歷(遞歸)

這裏展示的是二叉樹的中序遍歷和先序遍歷,只要稍微變一下printf("%c",T->data);的位置。printf("%c",T->data);相當於遍歷時每個雙親。它在什麼位置,就是什麼遍歷。

二叉樹先序遍歷(遞歸)
void  PreOrderTraverse(BiTree T)
{
	if(T)
	{
        printf("%c",T->data);  //先序遍歷此條語句在前面
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
	}
}
二叉樹中序遍歷(遞歸)
void  InOrderTraverse(BiTree T)
{
	if(T)
	{
        InOrderTraverse(T->lchild);
        printf("%c",T->data);  //中序遍歷此條語句在中間
        InOrderTraverse(T->rchild);
	}
}
二叉樹後序遍歷(遞歸)
//後序遍歷二叉樹
void PostOrderBiTree(BiTree T)
{
    if (T)
    {
        PostOrderBiTree(T->lChild);
        PostOrderBiTree(T->rChlid);
        printf("%d ", T->data);  //後序遍歷此條語句在最後
    }
}

//求二叉樹的深度(高度)

int TreeDeep(BiTree T)
{
    int deep = 0;
    if(T)
    {
        int leftdeep = TreeDeep(T->lchild);
        int rightdeep = TreeDeep(T->rchild);
        deep = leftdeep>=rightdeep?leftdeep+1:rightdeep+1;
    }
    return deep;
}

//由二元組建立孩子兄弟二叉樹

以雙親孩子二元組(F,C)的形式自上而下、自左而右依次輸入樹的各邊,建立樹的孩子-兄弟鏈表

void CreateCSTree(CSTree &T) 
{
    int input[2],n,i;
    CSTree queue[MAXSIZE];
    int front,rear;
    CSTree p, q;

    scanf("%d",&n);

    //對隊列初始化
    front = rear = 0;

    for (i=0; i<n; i++) 
    {
        scanf("%d",&input[0]);
        scanf("%d",&input[1]);
        //創建當前孩子結點
        p = (CSTree)malloc(sizeof(CSNode)); 
        p->data = input[1];
        //孩子結點和兄弟結點賦值爲空 
        p->firstchild = p->nextsibling = NULL;

        //將剛剛創建好的當前孩子結點放入隊尾 
        queue[rear] = p;
        rear = (rear+1)%MAXSIZE;

        /*********找雙親*********/

        //如果是根結點,則不需找雙親
        if (input[0] == -1) 
        {
            T = p; //將剛剛創建的結點賦值爲根結點 
        }

        //如果不是根結點,則找雙親 
        else
        {
            //從頭到尾遍歷當前所有兄弟找雙親,得到雙親的指針 
            for (q=queue[front]; q->data!=input[0];)
        {
             //如果隊頭元素和當前雙親結點不同,則出隊
            //最終獲得的指針即其雙親的指針 
            front=(front+1)%MAXSIZE;
            q=queue[front]; 
        }
        /*找到雙親後找哥哥*/ 
        //如果找到的雙親還不存在孩子結點 
        if (!q->firstchild) 
        {
            q->firstchild=p; 
        }
        //如果已有孩子結點。則要找到最近的哥哥
        else
        {
            for(q=q->firstchild; q->nextsibling; q=q->nextsibling);
            q->nextsibling = p;//和哥哥連接 
        }
    }
}
return 0;
}

//求孩子兄弟鏈表表示的樹 T的深度

int depthCSTree(CSTree T)
{ 
	int maxd, d;	
    CSTree p;	
	if(!T) return 0; //空樹	
	else 
	{		
        for(maxd=0,p=T->firstchild; p; p=p->nextsibling)
        if((d=depthCSTree(p)) > maxd) maxd = d; //子樹的最大深度
        return maxd + 1;  
	}
}

//輸出孩子兄弟鏈表表示的樹 T所有葉子結點值

void  InOrderTraverse_leaf(CSTree T)
{
	if(T)
	{
        if(!T->firstchild)
        {
            printf("%d ",T->data);
        }
        InOrderTraverse_leaf(T->firstchild);
        InOrderTraverse_leaf(T->nextsibling);
	}
}

//二元組建樹並求其葉子結點和深度

此代碼用到的所有函數在上面已經全部展示過了
其中 system(“color F0\n”); 語句可以將控制檯變爲白底黑字

int main()
{
	system("color F0\n"); 
    CSTree T;
	int deep;
	CreateCSTree(T);
	InOrderTraverse_leaf(T);
	printf("\n");
    deep = depthCSTree(T);
	printf("%d\n",deep);
}

//求每個結點的深度

此時在二叉樹的存儲結構中添加一個深度元素,像這樣:
typedef struct BiTNode
{
 char data;
 int deep;
 struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

void node_deep(BiTree &T)
{
	if(T)
	{
        if(T->lchild)
            T->lchild->deep = T->deep + 1;
        if(T->rchild)
            T->rchild->deep = T->deep + 1;
        node_deep(T->lchild);
        node_deep(T->rchild);
	}
}

如果還有什麼想要的關於樹的函數可以在評論區留言!看到就會盡快更新

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