1. 程式人生 > >C++實現平衡搜尋樹

C++實現平衡搜尋樹

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<stdlib.h>

using namespace std;
template<class K,class V>
struct AVLTreeNode
{
	K _key;
	V _value;
	AVLTreeNode<K, V> *_left;
	AVLTreeNode<K, V> *_right;
	AVLTreeNode<K, V> *_parent;
	int _bf;//平衡因子,只能是-1,0,1

	AVLTreeNode(const K&key, const V&value)
		:_key(key)
		, _value(value)
		, _left(NULL)
		, _right(NULL)
		, _parent(NULL)
		, _bf(0)
	{}
};
template<class K, class V>
class AVLTree
{
	typedef AVLTreeNode<K, V> Node;
public:
	AVLTree()
		:_root(NULL)
	{}
	~AVLTree()
	{
		_destroy(_root);
	}
public:
	bool Insert(const K&key, const V&value)//插入
	{
		if (_root == NULL)
		{
			_root = new Node(key, value);
		}
		Node*parent = NULL;
		Node*cur = _root;
		while (cur)
		{
			if (cur->_key > key)
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (cur->_key < key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
				return false;
		}
		cur = new Node(key, value);
		if (parent->_key>key)
		{
			parent->_left = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_right = cur;
			cur->_parent = parent;
		}

		bool IsRotate = false;

		while (parent)
		{
			if (parent->_left == cur)
			{
				parent->_bf--;
			}
			else
			{
				parent->_bf++;
			}

			if (parent->_bf == 0)
			{
				break;
			}
			else if (parent->_bf == 1 || parent->_bf == -1)
			{
				cur = parent;
				parent = cur->_parent;
			}
			else
			{
				IsRotate = true;
				if (parent->_bf == 2)
				{
					if (cur->_bf == 1)
					{
						//left  
						_RotateL(parent);
					}
					else
					{
						//right left  
						_RotateRL(parent);
					}
				}
				else if (parent->_bf == -2)
				{
					if (cur->_bf == -1)
					{
						//right  
						_RotateR(parent);
					}
					else
					{
						//left right  
						_RotateLR(parent);
					}
				}
				break;
			}
		}
		if (IsRotate)
		{
			Node *ppNode = parent->_parent;
			if (ppNode == NULL)
			{
				_root = parent;
			}
			else
			{
				if (ppNode->_key < parent->_key)
				{
					ppNode->_right = parent;
				}
				else
				{
					ppNode->_left = parent;
				}
			}
		}
		return true;
	}
	bool IsBalanceTree()//判斷是否是平衡二叉樹
	{
		return _IsBalance(_root);
	}
	void InOrder()//前序遍歷
	{
		_InOrder(_root);
		cout << endl;
	}
protected:
	bool _IsBalance(Node *root)
	{
		return true;
	}
	int _Height(Node *root)//求高
	{
		if (root == NULL)
			return 0;
		int leftlen = _Height(root->_left);
		int rightlen = _Height(root->_right);
		return leftlen > rightlen ? leftlen + 1 : rightlen + 1;
	}
	void _RotateL(Node*& parent)//左單旋
	{
		Node *subR = parent->_right;
		Node *subRL = subR->_left;
		parent->_right = subRL;
		if (subRL != NULL)
		{
			subRL->_parent = parent;
		}
		subR->_left = parent;
		subR->_parent = parent->_parent;
		parent->_parent = subR;
		parent->_bf = 0;
		subR->_bf = 0;
		parent = subR;
	}
	void _RotateR(Node*& parent)//右單旋
	{
		Node*subL = parent->_left;
		Node*subLR = subL->_right;
		parent->_left = subLR;
		if (subLR != NULL)
		{
			subLR->_parent = parent;
		}
		subL->_right = parent;
		subL->_parent = parent->_parent;
		parent->_parent = subL;
		subL->_bf = 0;
		parent->_bf = 0;
		parent = subL;
	}
	void _RotateLR_R(Node*& parent)//左右旋轉(遞迴)
	{
		_RotateL(parent->_right);
		_RotateR(parent);
	}
	void _RotateRL_R(Node*& parent)//右左旋轉(遞迴)
	{
		_RotateR(parent->_left);
		_RotateL(parent);
	}
	void _RotateLR(Node*& parent)	//左右旋轉(非遞迴)
	{
		Node *subL = parent->_left;
		Node *subLR = subL->_right;
		subL->_right = subLR->_left;
		if (subLR->_left != NULL)
		{
			subLR->_left->_parent = subL;
		}
		subLR->_left = subL;
		subL->_parent = subLR;
		//調整平衡因子,右樹減去左樹
		if (subLR->_bf == 0 || subLR->_bf == 1)
		{
			subL->_bf = 0;
		}
		else
		{
			subL->_bf = 1;
		}
		parent->_left = subLR->_right;
		if (subLR->_right != NULL)
		{
			subLR->_right->_parent = parent;
		}
		subLR->_right = parent;
		subLR->_parent = parent->_parent;
		parent->_parent = subLR;
		//調整平衡因子,右樹減去左樹
		if (subLR->_bf == 0 || subLR->_bf == 1)
		{
			parent->_bf = 0;
		}
		else
		{
			parent->_bf = 1;
		}
		parent = subLR;
		subLR->_bf = 0;
	}
	void _RotateRL(Node*& parent)//右左旋轉(非遞迴)
	{
		Node *subR = parent->_right;
		Node *subRL = subR->_left;
		subR->_left = subRL->_right;

		if (subRL->_right != NULL)
		{
			subRL->_right->_parent = subR;
		}
		subRL->_right = subR;
		subR->_parent = subRL;

		if (subRL->_bf == 0 || subRL->_bf == 1)
		{
			subR->_bf = 0;
		}
		else
		{
			subR->_bf = 1;
		}

		parent->_right = subRL->_left;

		if (subRL->_left != NULL)
		{
			subRL->_left->_parent = parent;
		}
		subRL->_left = parent;
		subRL->_parent = parent->_parent;
		parent->_parent = subRL;
		if (subRL->_bf == 0 || subRL->_bf == -1)
		{
			parent->_bf = 0;
		}
		else
		{
			parent->_bf = -1;
		}
		parent = subRL;
		subRL->_bf = 0;
	}
	void _InOrder(Node *root)
	{
		if (root == NULL)
		{
			return;
		}
		_InOrder(root->_left);
		cout << root->_key << " ";
		_InOrder(root->_right);
	}
	void _destroy(Node *root)
	{
		if (root)
		{
			_destroy(root->_left);
			_destroy(root->_right);
			delete root;
			root = NULL;
		}
	}
private:
	Node *_root;
};
void test()
{
	AVLTree<int, int> AVLtree;
	int a[] = { 16, 3, 7, 11, 9, 26, 18, 14, 15 };
	for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		AVLtree.Insert(a[i], a[i]);
	}
	AVLtree.InOrder();
	AVLtree.IsBalanceTree();
}
int main()
{
	test();
	system("pause");
	return 0;
}


相關推薦

C++實現平衡搜尋

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<stdlib.h> using namespace std; template<class K,class V> struct AVLTreeNod

C#實現平衡多路查詢(B)

寫在前面:搞了SQL Server時間也不短了,對B樹的概念也算是比較瞭解。去網上搜也搜不到用C#或java實現的B樹,乾脆自己寫一個。實現B樹的過程中也對很多細節有了更深的瞭解。 簡介     B樹是一種為輔助儲存設計的一種資料結構,在1970年由R.Bayer和E.mccreight提出。在檔案系統和資

【資料結構】平衡搜尋之---B的演算法實現

#include<iostream> using namespace std; #ifndef __BTREE_H__ #define __BTREE_H__ template<class K,int M=3>//設為三階B樹(每個陣列三個關鍵字

C/C++實現平衡二叉的插入、刪除、查詢和各種遍歷

1 平衡二叉樹的插入      關於平衡二叉樹的定義什麼的,就不再多說。直接說說各種功能的c語言實現。 首先插入的時候需要進行旋轉以保證樹始終保持平衡。而旋轉的型別有四種:L-L型旋轉,L-R型旋轉,R-L型旋轉,R-R型旋轉。其中L-L型和R-R型只需要進行一次基本旋轉操作

C#實現二叉的遍歷

c# 遍歷 二叉樹 遞歸 循環 C#實現二叉樹的前序、中序、後序遍歷。public class BinaryTreeNode { int value; BinaryTreeNode left; BinaryTreeNode r

c++實現二叉層序、前序創建二叉,遞歸非遞歸實現二叉遍歷

log ios cst ack ret 出棧 隊列 結點 非遞歸實現 #include <iostream> #include <cstdio> #include <stdio.h> #include <string> #i

資料結構實驗6:C++實現二叉

實驗6 學號:     姓名:      專業:   6.1 實驗目的 掌握二叉樹的動態連結串列儲存結構及表示。 掌握二叉樹的三種遍歷演算法(遞迴和非遞迴兩類)。 運用二叉樹三種遍歷的方法求解有關問題。 6

AVL平衡搜尋

AVL樹又稱高度平衡的二叉搜尋樹。 性質:      1. 左子樹和右子樹的高度之差的絕對值不超過1      2. 樹中的

平衡搜尋之B-

B-樹:     一種適合外查詢的平衡多叉樹(有些地方寫的是B-樹,注意不要誤讀 成"B減樹") 。 M階的B樹滿足如下性質:     1、根節點至少有兩個孩子; &nbs

C++實現二叉建立、前序、中序、後序、層序遍歷

看完資料結構二叉樹部分後,通過學習書上的虛擬碼以及其他人的程式碼自己動手實現了一下,採用前序方式建立一顆二叉樹,實現了前中後層四種遍歷方式。 在層序遍歷部分與前三種遍歷不同,層序遍歷採用從根節點開始從上到下逐層遍歷,所以藉助佇列來實現,開始遍歷後,將根節點先壓入佇列,然後將

【Algorithms公開課學習筆記9】 符號表part2——平衡搜尋

Balanced Search Tree 平衡搜尋樹 0. 前言 上一篇文章,我們分析了二叉搜尋樹(BST傳送門)。在二叉搜尋樹中,查詢、插入、刪除、ceiling和floor等操作的平均時間效能取決於樹高。在極端情況下(如插入有序序列後),如果樹高h過大,其時

【Algorithms公開課學習筆記10】 符號表part3——平衡搜尋的應用

Geometric Application of BSTs 平衡搜尋樹的幾何應用 0. 前言 在前面的文章中,我們分析了符號表的許多基本操作,包括:查詢、插入、刪除等。現在我們新增兩個操作:範圍查詢(range search) 和 範圍統計(range coun

二叉搜尋與二叉平衡搜尋

二叉平衡搜尋樹是一種特殊的二叉搜尋樹,其保持一定的平衡關係,要求每一個節點的左右子樹的高度不會相差超過1 1.下面是一到二叉平衡搜尋樹的題,leetcode108 題目描述: 將一個按照升序排列的有序陣列,轉換為一棵高度平衡二叉搜尋樹。 本題中,一個高度平衡二叉樹是指一個二叉樹每個節

c++實現紅黑

現在只是簡單的實現了紅黑樹的調整功能,其餘功能還沒有實現好,等後面的學習中再來新增 #ifndef _RB_TREE_H_ #define _RB_TREE_H_ typedef bool _color_type; const _color_type _color_red

資料結構與演算法C++之二分搜尋的刪除節點,刪除任意節點

上篇部落格介紹了怎樣刪除二分搜尋樹的最大值和最小值節點,下面介紹怎樣刪除樹的任意一個節點 上篇刪除最大值節點的操作,其實刪除的節點要麼沒有左右子節點,要麼只可能有左節點, 同樣,刪除最小值節點的操作,其實刪除的節點要麼沒有左右子節點,要麼只可能有右節點 (1)刪

資料結構與演算法C++之二分搜尋的順序性

二分搜尋樹可以查詢最小值 minimum 和最大值 maximum 可以找到一個元素的前驅(successor),後繼(predecessor),floor,和 ceil 當該元素在樹中時,前驅後繼和f

C++實現記憶搜尋演算法

1、記憶搜尋演算法:        給n*n地圖,老鼠初始位置在(0,0),它每次行走要麼橫著走要麼豎著走,每次最多可以走出k個單位長度,且落腳點的權值必須比上一個落腳點的權值大,求最終可以獲得的最大權值  2、思路      每次最多m步,記錄四個方向的下一次走法可以

c++實現二叉的插入、刪除、查詢、遍歷和樹形列印

binary_tree.h 宣告 #ifndef BINARY_TREE #define BINARY_TREE #include "util.h" template<typename T> class tree_node { public: tree_

C++實現二叉的插入、刪除、查詢、遍歷

1.二叉樹的概念        樹是一些節點的集合,節點之間用邊連結,節點之間不能有環路。上層的節點稱為父節點,下層節點稱為子節點。最上層的節點稱為根節點。       二叉樹是特殊的樹。對於每個節點

資料結構之高度平衡搜尋AVL(含經典面試題----判斷一棵是否是AVL

什麼是AVL樹 AVL樹簡介 AVL樹又稱為高度平衡的二叉搜尋樹,目的在於儘量降低二叉樹的高度,減少平均搜尋長度。 滿足二叉搜尋樹的性質 類比二叉搜尋樹,先將樹的結構確定下來,下面處理滿足AVL樹獨有的性質即可。 滿足AVL樹的性質 左