樹與二叉樹的應用

樹與二叉樹的應用

1.二叉排序樹的應用

1.1、定義

二叉排序樹(也稱二叉查找樹)或者是一顆空樹,或者是一顆具有下列特性的非空二叉樹:

1. 若左子樹非空,則左子樹上所有節點關鍵字值均小於根節點的關鍵字值。 2. 若右子樹非空,則右子樹上所有節點關鍵字值均大於根節點的關鍵字值。 3. 左、右子樹本身也分別是一顆二叉排序樹。

(ps:二叉排序樹是一個遞歸的數據結構,且左子樹節點值<根節點值<右子樹節點值。由中序遍歷可以得到一個遞增的有序序列。)

  • 特點:二叉排序樹是一種動態集合,樹的結構通常不是一次生成的,而是在查找過程中,當樹中不存在關鍵字值等於給定值得結點時再進行插入的。

1.2、基本操作

  • 1.2.2插入

若原二叉樹排序樹爲空,則直接插入結點;

若關鍵字k小於根結點關鍵字,則插入左子樹;

若關鍵字k大於根結點關鍵字,則插入右子樹;

此爲遞歸定義
int  BST_Insert(BiTree &T, KeyType k){
// 在二叉排序樹T中插入一個關鍵字爲k的結點
	if(T==NULL){
		T = (BiTree)malloc(sizeof(BSTNode));
		T->key = k;
		T->lchild=T->rchild=NULL;
		return 1;			// 返回1,表示成功
	}else if(k==T->key)		// 樹中存在相同關鍵字的結點
		return 0;
	else if(k<T->key)		// 插入T的左子樹
		return BST_Insert(T->lchild, k);
	else					// 插入T的右子樹
		return BST_Insert(T->rchild, k);
}
  • 1.2.2構造

每讀入一個元素,就建立一個新結點,若二叉排序樹非空,則將新結點的值與根結點的值比較,若小於根結點的值,則插入左子樹,否則插入右子樹;若二叉排序樹爲空,則將新結點作爲二叉排序樹的根結點。

void Creat_BST(BiTree &T, KeyType str[], int n){
// 用關鍵字數組str[]建立二叉排序樹
	T = NULL; 			// 初始化bt爲空樹
	int i = 0;
	while(i < n){		// 依次將每個元素插入
		BST_Insert(T, str[i]);
		i++;
	}
}
  • 1.2.4查找

查找是從根結點開始,沿某個分支逐層向下進行比較的過程。

若二叉排序樹非空,則將關鍵字與根結點的關鍵字比較,若相等,則查找成功;

若不等,則當根結點的關鍵字值大於給定關鍵字值時,在根結點的左子樹中查找,否則在根結點的右子樹中查找。

// 非遞歸查找
BSTNode *BST_Search(BiTree T, ElemType key, BSTNode *&p){
// 查找函數返回指向關鍵字值爲key的結點指針,若不存在,返回NULL;
	p = NULL;		// p指向被查找結點的雙親,用於插入和刪除操作中
	while(T!=NULL&&key!=T->data){
		p = T;
		if(key<T->data)		T=T->lchild;
		else	T = T->rchild;
	}
	return T;
}
  • 1.2.3刪除

刪除操作的實現過程按3種情況來處理:

1.若被刪除結點z是葉結點,則直接刪除,不會破壞二叉排序樹的性質。

2.若結點z只有左子樹或右子樹,則讓z子樹成爲z父結點的子樹,代替z的位置。

3.若結點z有左、右兩顆子樹,則令z直接後繼(後直接前驅)替代z,然後從二叉排序樹中刪除這個直接後繼(或直接前驅),這樣就轉換成爲了第一或第二種情況。

  • 1.2.5查找效率分析

二叉排序樹查找算法的平均查找長度,主要取決於樹的高度。

2.平衡二叉樹

2.1、定義

在插入和刪除二叉樹結點時,要保證任意結點的左、右子樹高度差的絕對值不超過1,這樣的二叉樹稱爲平衡二叉樹(Balanced Binary Tree),簡稱平衡樹(AVL)。

目的:避免樹的高度增長過快,而導致降低了二叉排序樹的性能。

平衡因子:結點左子樹與右子樹的高度差。

2.2、基本操作1

  • 2.2.1 插入/刪除
    基本思想:每當在二叉排序樹中插入(或刪除)一個結點時,首先檢查其插入路徑上的結點是否因爲此次操作而導致了不平衡。若導致了不平衡,則先找到插入路徑上離插入結點最近的平衡因子的絕對值大於1的結點A,再對以A爲根的子樹,在保持二叉排序樹特性的前提下,調整各結點的位置關係,使之重心達到平衡。

失去平衡後進行調整的規律如下:

1)LL平衡旋轉(右單旋轉)

2)RR平衡旋轉(左單旋轉)

3)LR平衡旋轉(先左後右雙旋轉)

4)RL平衡旋轉(先右後左雙旋轉)

  • 2.2.2查找

3.哈夫曼樹和哈夫曼編碼

3.1、定義

樹中 結點常常被賦予一個表示某種意義的數值,稱爲該結點的權。從樹根結點到任意結點的路徑長度(邊數)與該結點上權值的乘積,稱爲該結點的帶權路徑長度。樹中所有葉結點的帶權路徑長度之和稱爲該樹的帶權路徑長度。

其中帶權路徑長度最小的二叉樹稱爲哈夫曼樹,也稱爲最優二叉樹。

3.2、哈夫曼樹的構造

  • 1、將n個結點分別作爲n棵僅含一個結點的二叉樹,構成森林F.
  • 2、構造一個新結點,從F中選取兩棵根結點權值最小的樹作爲新結點的左、右子樹,並且將新結點的權值置爲左右子樹上根結點的權值之和。
  • 3、從F中刪除剛纔選出的兩棵樹,同時將新得到的樹加入F中。
  • 4、重複步驟2、3,直到F中只剩下一顆樹爲止。

3.3、哈夫曼編碼

哈夫曼編碼是一種可變長度編碼,應用於數據壓縮編碼。

  • 首先,將每個出現的字符當做一個獨立的結點,權值爲它出現的頻度(或次數),構造出對應的哈夫曼樹。
  • 將字符的編碼解釋爲從根至該字符的路徑上邊標記的序列,其中邊標記爲0表示"轉向左孩子",標記爲1表示"轉向右孩子"。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章