1. 程式人生 > >資料結構(七)二叉樹節點、空指標、刪除葉節點、最大節點數

資料結構(七)二叉樹節點、空指標、刪除葉節點、最大節點數

1、二叉樹節點

程式碼:

//二叉樹節點 
#include<stdio.h>
#include <malloc.h>
#include <conio.h>
#include<iostream>
//
typedef int DataType; 
typedef struct Node
{
 DataType data;
 struct Node *LChild;
 struct Node *RChild;
}BinaryNode,*BinaryTree;
//用擴充套件先序遍歷序列建立二叉樹,如果是#當前樹根置為空,否則申請一個新節點
void CreateBinaryTree(BinaryTree *bt)
{
 char ch;
 ch=getchar();
 if(ch=='.')*bt=NULL;
 else
 {
  *bt=(BinaryTree)malloc(sizeof(BinaryNode));
  (*bt)->data=ch;
  CreateBinaryTree(&((*bt)->LChild));
  CreateBinaryTree(&((*bt)->RChild));
 }
}
//訪問根節點
void Visit(char ch)
{
 printf("%c  ",ch);
}
//先序遍歷二叉樹, root為指向二叉樹(或某一子樹)根結點的指標
void  PreOrder(BinaryTree root) 
{
 if (root!=NULL)
 {
  Visit(root ->data);  //訪問根結點
  PreOrder(root ->LChild);  //先序遍歷左子樹
  PreOrder(root ->RChild);  //先序遍歷右子樹
 }
}
void  InOrder(BinaryTree root)  
//中序遍歷二叉樹, root為指向二叉樹(或某一子樹)根結點的指標
{
 if (root!=NULL)
 {
  InOrder(root ->LChild);   //中序遍歷左子樹
  Visit(root ->data);        //訪問根結點
  InOrder(root ->RChild);   //中序遍歷右子樹
 }
}
//後序遍歷二叉樹,root為指向二叉樹(或某一子樹)根結點的指標
void  PostOrder(BinaryTree root)  
{
 if(root!=NULL)
 {
  PostOrder(root ->LChild); //後序遍歷左子樹
  PostOrder(root ->RChild); //後序遍歷右子樹
  Visit(root ->data);       //訪問根結點
 }
}
//後序遍歷求二叉樹的高度遞迴演算法//
int PostTreeDepth(BinaryTree bt)   
{
 int hl,hr,max;
 if(bt!=NULL)
 {
  hl=PostTreeDepth(bt->LChild);  //求左子樹的深度 
  hr=PostTreeDepth(bt->RChild);  //求右子樹的深度 
  max=hl>hr?hl:hr;              //得到左、右子樹深度較大者
  return(max+1);               //返回樹的深度
 }
 else return(0);              //如果是空樹,則返回0
}
//按豎向樹狀列印的二叉樹 
void PrintTree(BinaryTree Boot,int nLayer)  
{
    int i;
 if(Boot==NULL) return;
 PrintTree(Boot->RChild,nLayer+1);
 for(i=0;i<nLayer;i++)
  printf("  ");
 printf("%c\n",Boot->data);
 PrintTree(Boot->LChild,nLayer+1);
}
//節點 
int nodeCount(Node* T)
{	int nodecount=0;
	while(T!=NULL)
	{
	return 	1+nodeCount(T->LChild)+nodeCount(T->RChild);
	}
	return nodecount;
}
//葉節點 
int leaf(Node* T)
{
	int LeafCount=0;
	if(T==NULL)
	LeafCount=0;
	else
		if(T->LChild==NULL&&T->RChild==NULL)
			LeafCount+=1;
		else
			LeafCount=leaf(T->LChild)+leaf(T->RChild);
	return LeafCount;
}

//滿節點
 int fullleaf(Node* &T) 
{if (NULL == T)
		return 0;
	return (T -> LChild != NULL && T -> RChild != NULL) + fullleaf (T -> LChild) + fullleaf (T -> RChild)  ;
}

int main()
{
 BinaryTree T;
 int h;
 int layer;
 int treeleaf;
 layer=0;
 
 printf("請輸入二叉樹中的元素(以擴充套件先序遍歷序列輸入,其中.代表空子樹):\n");
    CreateBinaryTree(&T);
 printf("先序遍歷序列為:");
 PreOrder(T);
 printf("\n中序遍歷序列為:");
 InOrder(T);
 printf("\n後序遍歷序列為:");
 PostOrder(T);
 h=PostTreeDepth(T);
    printf("\nThe depth of this tree is:%d\n",h);
 PrintTree(T,layer);
 
 int ch;
 ch=nodeCount(T);
 printf("\n該二叉樹的節點數目為:%d\n",ch);
 ch=leaf(T);
 printf("\n該二叉樹的葉節點數目為:%d\n",ch);
 ch=fullleaf(T);
 printf("\n該二叉樹的滿節點數目為:%d\n",ch);


return 0;
}

執行:

2、空指標

程式碼:

//空指標 
/*設二叉樹有n個節點,度為0的n0個,度為1的n1個,度為2的n2個,空鏈域只有度為1和度為0的有,一共有2n0+n1個空鏈域。
1.n=n0+n1+n2;
2.n=n1+2n2+1;
1式x2-2式即的結果*/
//二叉樹節點 
#include<stdio.h>
#include <malloc.h>
#include <conio.h>
#include<iostream>
typedef int DataType; 
typedef struct BTNode
{
 DataType data;
 struct BTNode *lchild;
 struct BTNode *rchild;
}BTNode,*BinaryTree;
//用擴充套件先序遍歷序列建立二叉樹,如果是#當前樹根置為空,否則申請一個新節點
void CreateBinaryTree(BinaryTree *bt)
{
 char ch;
 ch=getchar();
 if(ch=='.')*bt=NULL;
 else
 {
  *bt=(BinaryTree)malloc(sizeof(BTNode));
  (*bt)->data=ch;
  CreateBinaryTree(&((*bt)->lchild));
  CreateBinaryTree(&((*bt)->rchild));
 }
}
//求二叉樹中度為0的節點個數 
int NumberOfZeroDegree(BTNode *T)
{
    int i=0;
    if(NULL != T)
    {
            if(NULL==T->lchild  && NULL==T->rchild)
            {
                         i=1;       
            }
            else
            {
                i= NumberOfZeroDegree(T->lchild)+NumberOfZeroDegree(T->rchild);
            }
             
    }
    return i;
}

//求二叉樹中度為1的節點個數 
int NumberOfOneDegree(BTNode *T)
{
    int i=0;
    if(NULL != T)
    {
           
           if((NULL!=T->lchild  && NULL==T->rchild) ||(NULL!=T->rchild && NULL ==T->lchild))
            {
                 i=1+NumberOfOneDegree(T->lchild)+NumberOfOneDegree(T->rchild);
            }
            else
            {
                 i=NumberOfOneDegree(T->lchild)+NumberOfOneDegree(T->rchild);
            }
            
    }
    return i;
    
}

//求二叉樹中度為2的節點個數 
int NumberOfTwoDegree(BTNode *T)

{
    int i=0;
    
    if(NULL != T)
    {
            if((NULL!=T->lchild)&&(NULL!=T->rchild))
              i=1+NumberOfTwoDegree(T->lchild)+NumberOfTwoDegree(T->rchild); 
            else
              i=NumberOfTwoDegree(T->lchild)+NumberOfTwoDegree(T->rchild); 
    }
    return i;
}
//1.n=n0+n1+n2;
int NumberAllNodes1(BTNode *T)
{
    return NumberOfZeroDegree(T)+NumberOfOneDegree(T)+NumberOfTwoDegree(T);
}
//2.n=n1+2n2+1;
int NumberAllNodes2(BTNode *T)
{
    return 2*NumberOfOneDegree(T)+NumberOfTwoDegree(T)+1;
}  

//求 nullptr的值 
int Numberofnullptr(BTNode *T)
{
	return  NumberAllNodes1(T)-1;
}

int main()
{
 BinaryTree T;
 
 printf("請輸入二叉樹中的元素(以擴充套件先序遍歷序列輸入,其中.代表空子樹):\n");
    CreateBinaryTree(&T);
  int ch;
 ch=NumberOfZeroDegree(T);
 printf("\n該二叉樹度為0的節點數目為:%d\n",ch);
 ch=NumberOfOneDegree(T);
 printf("\n該二叉樹度為1的葉節點數目為:%d\n",ch);
 ch=NumberOfTwoDegree(T);
 printf("\n該二叉樹度為2的滿節點數目為:%d\n",ch);
 ch=NumberAllNodes1(T);
 //ch=NumberAllNodes2(T);
 printf("\n該二叉樹的節點數目為:%d\n",ch);
 ch=Numberofnullptr(T);
 printf("\n該二叉樹的空指標數目為:%d\n",ch);
 
 
 return 0;
}

執行:

3、刪除葉節點

程式碼:

#include <iostream>
#include <string>
#include <cstdio>
using namespace std;
struct BiNode
{
    char data;
    BiNode *lchild, *rchild;
};
class BiTree
{
public:
    BiTree( );
    BiNode * Getroot();
    int Delete(BiNode *root);
    void LeverOrder(BiNode *root);
private:
    BiNode *root;
    BiNode *Creat( );
};
BiTree::BiTree( )
{
    this->root = Creat( );
}
BiNode *BiTree::Getroot( )
{
    return root;
}
int BiTree::Delete(BiNode *root)
{
    if(root==NULL)
        return (int)NULL;
    else
    {
        if(!root->lchild && !root->rchild)//判斷是否為葉子
            root->data ='#';//將節點值置空
        Delete(root->lchild);//並刪除當前節點的左右孩子
        Delete(root->rchild);
    }
    return 0;
}
void BiTree::LeverOrder(BiNode *root)//層序輸出
{
    const int MaxSize = 100;
    int front = 0;
    int rear = 0;
    BiNode* Q[MaxSize];
    BiNode* q;
    if (root == NULL) return;
    else
    {
        Q[rear++] = root;
        while (front != rear)
        {
            q = Q[front++];
            if(q->data!='#')
            cout<<q->data<<" ";
            if (q->lchild != NULL)    Q[rear++] = q->lchild;
            if (q->rchild != NULL)    Q[rear++] = q->rchild;
        }
    }
}
BiNode* BiTree ::Creat( )
{
    BiNode * root;
    char ch;
    cin>>ch;
    if (ch == '#')
        root = NULL;
    else
    {
        root = new BiNode;
        root->data=ch;
        root->lchild = Creat( );
        root->rchild = Creat( );
    }
    return root;
}
//判斷是否為葉子,然後刪除,最後層序輸出就行了
int main()
{
    BiTree bt;
    BiNode *root = bt.Getroot( );
    bt.Delete(root);
    bt.LeverOrder(root);
    return 0;
}

執行:

4、最大節點數

程式碼:

//最大節點數,則該二叉樹為滿二叉樹 
#include<stdio.h>
#include <conio.h>
#include<iostream>
using namespace std;
 
typedef int DataType; 
typedef struct Node
{
 DataType data;
 struct Node *lChild;
 struct Node *rChild;
}BinTreeNode,*BinaryTree;


//後序遍歷求二叉樹的高度遞迴演算法
int PostTreeDepth(BinaryTree bt)   
{
 int hl,hr,max;
 if(bt!=NULL)
 {
  hl=PostTreeDepth(bt->lChild);  //求左子樹的深度 
  hr=PostTreeDepth(bt->rChild);  //求右子樹的深度 
  max=hl>hr?hl:hr;              //得到左、右子樹深度較大者
  return(max+1);               //返回樹的深度
 }
 else return(0);              //如果是空樹,則返回0
}

template<class T>
int BinaryTree<T>::twoDegree(BinTreeNode<T>* bt)
{
    //子樹不空
    if(bt!=NULL)
    {
        //如果左右子樹都不空
        if(bt->lChild!=NULL 
            && bt->rChild!=NULL)
            //遞迴統計左右子樹,並返回兩者的和,並加1
            return 1+twoDegree(bt->lChild)
            +twoDegree(bt->rChild);
		 else
            return 0;
    }
	else
        return 0;
}

int main()
{
  BinaryTree T;
  int h;
  int n;
  
  h=PostTreeDepth(T);
    printf("\nThe depth of this tree is:%d\n",h);
    
  n=BinaryTree(T);
    printf("\nThe jiedian of this tree is:%d\n",n);
    
    return 0;
}