數據結構二叉樹的建立(先序)和讀取(後序)

一、二叉樹的性質

  • 二叉樹的第i層上最多有2i-1個結點(i≥1)。
  • 深度爲k的二叉樹最多有2k-1個結點(k≥1 )
  • 一棵非空二叉樹,若葉子結點數爲n0,度數爲2的結點數爲n2,則n0=n2+1。

1.1 完全二叉樹特有性質

  • 具有n個結點的完全二叉樹的深度必爲log2n+1
  • 對於具有n個結點的完全二叉樹,如果按照從上到下和從左到右的順序對二叉樹中的所有結點從1開始順序編號,則對於任意的序號爲i的結點有如下性質:
  • 對於具有n個結點的完全二叉樹,如果按照從上到下和從左到右的順序對二叉樹中的所有結點從1開始順序編號,則對於任意的序號爲i的結點有如下性質:
       (1)如i=1,則序號爲i的結點是根結點,無雙親結點;如i>1,則序號爲i的結點的雙親結點序號爲i/2
      (2)如2i>n,則序號爲i的結點無左孩子;如2i≤n,則序號爲i的結點的左孩子結點的序號爲2i
      (3)如2i+1>n,則序號爲i的結點無右孩子;如2i+1≤n,則序號爲i的結點的右孩子結點的序號爲2i+1

完全二叉樹性質1

1.2滿二叉樹特殊性質

  • 深度爲k時,結點數n=2k-1
  • 不存在度爲1的結點
  • 每個結點都有兩棵高度相同的子樹
  • 深度爲k的完全二叉樹,前k-1層構成一棵深度爲k-1的滿二叉樹

二、二叉樹的存儲

2.1順序存儲

不常用,侷限性比較大,不寫了。

2.2鏈式存儲

鏈表中每個結點由 三個區域組成:

名稱 意義
data 數據:存放節點的數據信息
lchild 存放指向左孩子的指針
rchild 存放指向右孩子的指針

結點數據類型定義:

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

說明: 在n個結點的二叉鏈表中,有n+1個空指針域。 1

2.3二叉樹的遍歷

2.3.1 遍歷的方法

先序:
若二叉樹爲空,則遍歷結束,否則依次執行如下3個操作:
1.訪問根結點
2.先序遍歷根結點的左子樹
3.先序遍歷根結點的右子樹

void  PreOrder(BiTreebt) 
/*先序遍歷二叉樹,  bt爲指向二叉樹(或某一子樹)根結點的指針*/
{ 
	 if (bt==NULL)   
		 return ;
	 Visit(bt->data);         /*訪問根結點*/
     PreOrder(bt->lchild);    /*先序遍歷左子樹*/
     PreOrder(bt->rchild);    /*先序遍歷右子樹*/
} 

中序:
若二叉樹爲空,則遍歷結束,否則依次執行如下3個操作:
1.中序遍歷根結點的左子樹
2.訪問根結點
3.中序遍歷根結點的右子樹

void  InOrder(BiTreebt) 
/*中序遍歷二叉樹,  bt爲指向二叉樹(或某一子樹)根結點的指針*/
{ 
	if (bt=NULL)   
	 return ;
	 InOrder(bt->lchild);    /*中序遍歷左子樹*/ 
	 Visit(bt->data);       /*訪問根結點*/
	 InOrder(bt->rchild);   /*中序遍歷右子樹*/
 } 

後序:
若二叉樹爲空,則遍歷結束,否則依次執行如下3個操作:
1.後序遍歷根結點左子樹
2.後序遍歷根結點右子樹
3.訪問根結點

void  PostOrder(BiTreebt)
 /*後序遍歷二叉樹,  bt爲指向二叉樹(或某一子樹)根結點的指針*/
 {
	 if (bt=NULL)  
	  return ;
	  Post Order (bt->lchild);      /*後序遍歷左子樹*/ 
	  PostOrder(bt->rchild);        /*後序遍歷右子樹*/
	  Visit(bt->data);              /*訪問根結點*/
   } 

小結

已知一棵二叉樹的先序序列和中序序列,構造該二叉樹的過程如下:

  1. 根據先序序列的第一個元素建立根結點;
  2. 在中序序列中找到該元素,確定根結點的左右子樹的中序序列;.
  3. 在先序序列中確定左右子樹的先序序列;
  4. 由左子樹的先序序列和中序序列建立左子樹;
  5. 由右子樹的先序序列和中序序列建立右子樹。

上機實驗報告代碼:
   先序建立二叉樹,後序打印;

#include "stdio.h"    //設數據域類型爲字符型

typedef struct node{
	char data;
	struct node *lchild,*rchild;
}BiTNode, *BiTree;      //指向二叉樹結點的指針類型

void CreateBiTree(BiTree *t);   //構造二叉鏈表
void PostOrder(BiTree p);    //後序遍歷
void main( )   //主函數
{
	BiTree T;
	char ch1,ch2;
	printf("\n請選擇:\n");
	ch1='y';
	while(ch1=='y'||ch1=='Y')
	{
		printf("\n1------------------二叉樹建立-------------");
		printf("\n2------------------後序遍歷---------------");
		printf("\n3------------------退出-------------------\n");
		scanf("\n%c",&ch2);
		switch(ch2) 
		{
			case '1':printf("請按先序輸入建立二叉樹存儲的結點序列:\n");
					 CreateBiTree(&T);
					 break;
			case '2':printf("該二叉樹的後序遍歷序列爲:\n");  //調用後序遍歷函數
					 PostOrder(T);
					 break;
			case '3':printf("Thank you.\n");
					 ch1 = 'n';
					 break;
			default: printf("輸入有誤,請重新選擇");
		}
	}
}
void CreateBiTree( BiTree *t)  //構造二叉鏈表
{
	char ch;
	scanf("\n%c",&ch);
	if(ch=='0') *t=NULL;  //讀入0時,將相應結點置空
	else 
	{
		*t=new BiTNode;   //生成結點空間
		(*t)->data=ch;
		CreateBiTree(&(*t)->lchild);  //構造二叉樹的左子樹
		CreateBiTree(&(*t)->rchild);  //構造二叉樹的右子樹
	}
}

void PostOrder(BiTree p) //後序遍歷
{
	if(p != NULL) 
	{
		PostOrder(p->lchild);  
		PostOrder(p->rchild);  
		printf(" %c",p->data);
	}
}

效果圖


  1. 全部的結點爲2n,其中被佔用n-1,所以2n-(n-1)=n+1; ↩︎

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