1. 程式人生 > >C語言二叉樹

C語言二叉樹

null ret || 進行 第一個 exchange right creat truct

本二叉樹的功能為:創建二叉樹,遞歸先根,中根,後根遍歷,二叉樹節點總數目,二叉樹深度,二叉樹葉子節點數,復制二叉樹,尋找某節點是否存在並輸出,交換左右子樹,插入某節點。

下面介紹每種算法的主要思路:

1.創建二叉樹:首先引入申請空間的指針節點。設葉子節點的左右子樹均為零,每當遇到輸入的數字為零時,將指針賦值為NULL,否則依次創建左右子樹。

2.遞歸遍歷:如根節點不為空,則依次訪問其左右子樹。

3.二叉樹節點總數:根節點為空返回零,否則返回1+左右子樹節點總數。

4.二叉樹深度:根節點為空返回零,否則返回1+左右子樹中深的那棵樹的深度。

5.二叉樹葉子節點總數:遞歸有兩個出口,若根節點為空,返回零;若根節點的左右子樹均為空,返回1。否則返回左右子樹之和。

6.復制二叉樹:類似創建二叉樹。

7.尋找節點是否存在:重點!

Node*Find(Node*root,int item){

Node*p=NULL; //需要引入一個空指針

if(root==NULL) return NULL;

if(root->data==item) {

return root;

}

p=Find(root->Left,item); //用指針p來儲存左子樹的尋找結果

if(p!=NULL) return p; //若p不為空,說明在左子樹中找到該節點,返回該節點

return Find(root->Right,item); //否則返回右子樹的尋找結果(無論是該節點指針或者NULL,最終將會有一個被返回)

}

(1)錯誤示範:警示!

Node*Find(Node*root,int item){

if(root==NULL) return NULL;

if(root->data==item) {

return root;

}

return Find(root->Left,item);

return Find(root->Right,item);

}

錯誤原因:該算法最終由於第一個return的存在,最終只能返回左子樹左面的那部分。

(2)錯誤示範:警示!

Node*Find(Node*root,int item){

if(root==NULL) return NULL;

if(root->data==item) {

return root;

}

Find(root->Left,item);

Find(root->Right,item);

}

錯誤原因:因為沒有return導致遞歸不能正常進行。

8.交換左右子樹:左右子樹只要有一個不為空就交換其左右子樹,若左子樹不為空,交換左子樹;若右子樹不為空,交換右子樹。

9.插入節點:利用Find函數找到相應節點並返回其指針,進行插入。

Node*Addition(Node*root,int item){ //截取插入函數的一部分

Node*r=root;

Node*p=NULL;

Node*q=NULL;

q = (Node*)malloc(sizeof(Node));

q->data=item;

q->Left=p->Left;

p->Left=q; //重點!p->Left=q而不是q=p->Left

q->Right=NULL;

}

以下是完整代碼:

#include<iostream>

#include<stdlib.h>

using namespace std;

typedef struct BinaryTreeNode

{

int data;

struct BinaryTreeNode *Left;

struct BinaryTreeNode *Right;

}Node;

//創建二叉樹,順序依次為中間節點->左子樹->右子樹

Node* createBinaryTree()

{

Node *p;

int ch;

cin>>ch;

if(ch == 0) //如果到了葉子節點,接下來的左、右子樹分別賦值為0

{

p = NULL;

}

else

{

p = (Node*)malloc(sizeof(Node));

p->data = ch;

p->Left = createBinaryTree(); //遞歸創建左子樹

p->Right = createBinaryTree(); //遞歸創建右子樹

}

return p;

}

//先序遍歷

void preOrderTraverse(Node* root)

{

if( root )

{

cout<<root->data<<‘ ‘;

preOrderTraverse(root->Left);

preOrderTraverse(root->Right);

}

}

//中序遍歷

void inOrderTraverse(Node* root)

{

if( root )

{

inOrderTraverse(root->Left);

cout<<root->data<<‘ ‘;

inOrderTraverse(root->Right);

}

}

//後序遍歷

void lastOrderTraverse(Node* root)

{

if( root )

{

lastOrderTraverse(root->Left);

lastOrderTraverse(root->Right);

cout<<root->data<<‘ ‘;

}

}

//二叉樹節點總數目

int Nodenum(Node* root)

{

if(root == NULL)

{

return 0;

}

else

{

return 1+Nodenum(root->Left)+Nodenum(root->Right);

}

}

//二叉樹的深度

int DepthOfTree(Node* root)

{

if(root)

{

return DepthOfTree(root->Left)>DepthOfTree(root->Right)?DepthOfTree(root->Left)+1:DepthOfTree(root->Right)+1;

}

if( root == NULL )

{

return 0;

}

}

//二叉樹葉子節點數

int Leafnum(Node* root)

{

if(!root)

{

return 0;

}

else if( (root->Left == NULL) && (root->Right == NULL) )

{

return 1;

}

else

{

return (Leafnum(root->Left) + Leafnum(root->Right)) ;

}

}

//復制二叉樹

Node*Copy(Node*copy){

Node*p;

if(copy==NULL) p=NULL;

else{

p=(Node*)malloc(sizeof(Node));

p->data=copy->data;

p->Left=Copy(copy->Left);

p->Right=Copy(copy->Right);

return p;

}

}

//尋找節點

Node*Find(Node*root,int item){

Node*p=NULL;

if(root==NULL) return NULL;

if(root->data==item) {

return root;

}

p=Find(root->Left,item);

if(p!=NULL) return p;

return Find(root->Right,item);

}

//輸出是否存在該節點

void Output(Node*root){

if(root!=NULL) cout<<"Find it";

else cout<<"No find";

}

//交換左右子樹

Node*Exchange(Node*root){

if(root->Left!=NULL||root->Right!=NULL){

Node*temp=root->Left;

root->Left=root->Right;

root->Right=temp;

}

if(root->Left) Exchange(root->Left);

if(root->Right) Exchange(root->Right);

return root;

}

//插入某節點

Node*Addition(Node*root,int item){

int location;

Node*r=root;

Node*p=NULL;

Node*q=NULL;

if(root==NULL) return NULL;

if(item==0){

cout<<"無法插入該節點";

return root;

}

cout<<"請輸入要插入節點的位置";

cin>>location;

p=Find(r,location);

if(p==NULL){

cout<<"不存在該節點要插入的位置";

cout<<endl;

return root;

}

q = (Node*)malloc(sizeof(Node));

q->data=item;

q->Left=p->Left;

p->Left=q;

q->Right=NULL;

return root;

}

//主函數

int main()

{

int number=2;

int number1=9;

Node *addition=NULL;

Node *output=NULL;

Node *exchange=NULL;

Node *root = NULL;

Node *example=NULL;

Node *example_addition=NULL;

Node *example_exchange=NULL;

root = createBinaryTree();

example=Copy(root);

example_addition=Copy(root);

example_exchange=Copy(root);

addition=Addition(example_addition,number1);

exchange=Exchange(example_exchange);

printf("二叉樹建立成功");

cout<<endl;

cout<<"二叉樹總節點數為:"<<Nodenum(root)<<endl;

cout<<"二叉樹深度為:"<<DepthOfTree(root)<<endl;

cout<<"二叉樹葉子節點數為:"<<Leafnum(root)<<endl;

cout<<"前序遍歷結果:"<<endl;

preOrderTraverse(root);

cout<<endl;

cout<<"中序遍歷結果:"<<endl;

inOrderTraverse(root);

cout<<endl;

cout<<"後序遍歷結果:"<<endl;

lastOrderTraverse(root);

cout<<endl;

cout<<"添加後前序遍歷結果:"<<endl;

preOrderTraverse(addition);

cout<<endl;

cout<<"添加後中序遍歷結果:"<<endl;

inOrderTraverse(addition);

cout<<endl;

cout<<"添加後後序遍歷結果:"<<endl;

lastOrderTraverse(addition);

cout<<endl;

cout<<"復制二叉樹前序遍歷結果:"<<endl;

preOrderTraverse(example);

cout<<endl;

cout<<"復制二叉樹中序遍歷結果:"<<endl;

inOrderTraverse(example);

cout<<endl;

cout<<"復制二叉樹後序遍歷結果:"<<endl;

lastOrderTraverse(example);

cout<<endl;

cout<<"交換後二叉樹前序遍歷結果:"<<endl;

preOrderTraverse(exchange);

cout<<endl;

cout<<"交換後二叉樹中序遍歷結果:"<<endl;

inOrderTraverse(exchange);

cout<<endl;

cout<<"交換後二叉樹後序遍歷結果:"<<endl;

lastOrderTraverse(exchange);

cout<<endl;

output=Find(root,number);

Output(output);

return 0;

}

C語言二叉樹