資料結構(七)二叉樹節點、空指標、刪除葉節點、最大節點數
阿新 • • 發佈:2019-02-07
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;
}