數據結構與算法之平衡二叉樹的實現

關於平衡二叉樹

前面的博客筆者提到過關於二叉搜索樹的實現與分析,詳見跳轉 :深入瞭解搜索樹之二叉搜索樹的原理分析以及實現雖然二叉搜索樹很大程度滿足了在O(lgN)的情況下搜索元素的需求。但是,**當元素按照升序或者降序插入時,一種極端的問題就無法避免,即平均搜索時間由O(lgN)升至O(N),**雖然O(N)在一些情況下也是一種理想的時間,但是我們任然希望在二叉搜索樹中檢索的時間複雜度爲O(lgN),這時就引入了平衡二叉樹樹的概念,通過對插入節點位置的修改以及調整可以使得最壞情況下的檢索效率保持在O(lgN)
在這裏插入圖片描述

平衡二叉樹的概念

  • 二叉樹的根節點的左右子樹的高度差不能超過一
  • 二叉樹的根結點的左右子樹同時也滿足平衡二叉樹的性質
    在這裏插入圖片描述

二叉樹結構的設計

1.爲了檢驗是否平衡,需要引入了平衡因子的概念,樹的結點有以下幾個域 :1.數據域(包括Keys以及Vals)2.孩子指針域 :用於保存結點的左右孩子指針 3.父節點指針域 :用於保存結點的父節點,當結點爲根結點時,其父節點指向空 4.高度域 :包括左子樹高度域以及右子樹高度域
初始化時,指針域的指針均指向None,初始化高度域的值爲0

平衡二叉樹的調整

  • 節點的插入
    與二叉搜索的插入相同,通過比較節點的權值大小,而後將節點插入到合適的位置,之後動態調整樹的平衡即可
  • 節點的刪除
    與二叉搜索的刪除相同,找到刪除的節點之後,利用其性質刪除節點,之後動態調整樹的平衡即可
    在插入或者刪除的過程中,總會不經意的破壞樹的平衡,那麼該如何調整樹纔可使樹達到平衡?這裏引入四種不同情況調整樹的平衡的方法:
  • LL型
    LL型 :說明失衡結點的左子樹破環了平衡,且失衡結點左孩子的左子樹的高度大於失衡結點的右子樹的高度
    在這裏插入圖片描述
    調整規則僞代碼描述:
LL(a,b)  
{ 
	/*
	a : 失衡結點 
	b : 失衡結點的左孩子 
	*/
	a.lson = b.rson
	b.rson = a		
}
  • 實現代碼
    def _LL(self,s):
        #p : s的父節點
        #a : 替代s
        #b : s的左孩子
        p = s.partet
        a = s
        b = a.lsub
        #調整根指針
        if p is not None :   #結點非根結點
            if a is p.lsub : #失衡結點爲其父節點的左孩子
                p.lsub = b
            else :
                p.rsub = b  #失衡結點爲其父節點的右孩子
        else :  #結點爲根結點
            self.root = b
        #調整父節點位置
        if b.rsub is not None :   
            b.rsub.partet = a
            
        #調整位置
        a.lsub = b.rsub
        b.rsub = a

        a.partet = b
        b.partet = p
  • RR型
    RR型 :說明失衡結點的右子樹破壞了平衡,且失衡節點右孩子的右子樹的高度大於失衡結點的左子樹的高度
    在這裏插入圖片描述
RR(a,b)  
{ 
	/*
	a : 失衡結點 
	b : 失衡結點的右孩子 
	*/
	a.rson = b.lson
	b.lson = a		
}
    def _RR(self,s):
        p = s.partet
        a = s
        b = a.rsub
        #調整根指針
        if p is not None :
            if a is p.lsub :
                p.lsub = b
            else :
                p.rsub = b
        else :
            self.root = b
            # 調節父節點
        if b.lsub is not None:
            b.lsub.partet = a
        #調整位置
        a.rsub = b.lsub
        b.lsub = a
        a.partet = b
        b.partet = p
  • LR型
    LR型 : 說明失衡結點的左子樹破環了平衡,且失衡節點左孩子的右子樹的高度大於失衡結點的左子樹的高度

在這裏插入圖片描述

LR(a,b)  
{ 
	/*
	a : 失衡結點 
	b : 失衡結點的左孩子 
	*/
	c = b.rson
	b.rson = c.lson
	a.lson = c.rson
	c.lson = b
	c.rson = a
		
}
    def _LR(self,s):
        p = s.partet
        a = s
        b = a.lsub
        c = b.rsub
        #調整根指針
        if p is not None :   #非根結點
            if a is p.lsub :
                p.lsub = c
            else :
                p.rsub = c
        else :              #根結點
            self.root = c
        # 調整父節點指針
        if c.lsub is not None:
            c.lsub.partet = b
        else :
            b.rdepth = 0
        if c.rsub is not None:
            c.rsub.partet = a
        else :
            a.ldepth = 0
        #調整位置
        b.rsub = c.lsub
        a.lsub = c.rsub
        c.lsub = b
        c.rsub = a

        a.partet = c
        b.partet = c
        c.partet = p
        #重新統計深度
  • RL型
  • RL型: 說明失衡結點的右子樹破環了平衡,且失衡結點右孩子的左子樹的高度大於失衡結點的右子樹的高度
    在這裏插入圖片描述
RL(a,b)  
{ 
	/*
	a : 失衡結點 
	b : 失衡結點的右孩子 
	*/
	c = b.lson
	a.rson = c.lson
	b.lson = c.rson
	c.lson = a
	c.rson = b	
} 
    def _RL(self,s) :
        p = s.partet
        a = s
        b = a.rsub
        c = b.lsub
        #調整根指針
        if p is not None :
            if a is p.lsub :
                p.lsub = c
            else :
                p.rsub = c
        else :
            self.root = c
            # 調整父節點指針
        if c.lsub is not None:
            c.lsub.partet = a
        else :
            a.rdepth = 0
        if c.rsub is not None:
            c.rsub.partet = b
        else :
            b.ldepth = 0
        #調整位置指針
        a.rsub = c.lsub
        b.lsub = c.rsub
        c.lsub = a
        c.rsub = b
        #調整父節點
        a.partet = c
        b.partet = c
        c.partet = p

算法的設計

1.平衡二叉樹的插入以及刪除操作與二叉搜索樹相似,與二叉搜索樹有些許差異,即爲了保持平衡,在插入以及刪除的過程中,需要動態維持其父節點的高度差。
2.維持結點平衡因子,如果指定的節點的左子樹爲空並且右子樹同時爲空,那麼指定的節點的左右高度域均賦值爲0即可,如果左子樹爲空,右子樹非空,則需要維持其右孩子的高度即其右孩子的左右最大的高度因子加以即可,反之則需要維持其左子樹的高度,如果左子樹非空且右子樹非空,需要同時維持其左右的高度因子
3.關於失衡之後的調度,前面提到過幾種失衡類型的狀態,可以依次判斷其父節點是否平衡,如果失衡則調整平衡之後需要重新更新其所有父節點的左右高度因子
4.其他操作
由於平衡二叉樹與平衡搜索樹有着共同的性質,所有查找最大值以及最小值的操作與二叉搜索樹相同

完整代碼


class Association :   #輔助類,保存節點的權值以及值
    def __init__(self,keys,vals):
        self.keys = keys
        self.vals = vals
class OrdersMaps :   #節點類的父類,保存節點的信息
    class Node :
        def __init__(self,elem,lsub ,rsub,partet):
            self.elem = elem
            self.lsub = lsub    #節點的左孩子
            self.rsub = rsub    #節點的右孩子
            self.partet = partet#節點的父節點
class AvlTrees :
    class Node(OrdersMaps.Node):
        def __init__(self,elem,lsub = None,rsub = None,partet = None):
            super().__init__(elem,lsub,rsub,partet)
            self.ldepth = 0  #左子樹的高度   
            self.rdepth = 0  #右子樹的高度
    def __init__(self,root = None):
        self.root = root
    #-------------------------輔助操作-------------------------------
    def _calAlldepth(self,p):
        #重新統計所有父節點的高度
        while p is not None :
            self._calNewdepth(p)
            p = p.partet
    def _calNewdepth(self,p):  #更新結點的ldepth值以及rdepth值
        if p.lsub is None and p.rsub is None :
            p.ldepth = 0
            p.rdepth = 0
        elif p.lsub is None and p.rsub is not None :
            p.rdepth = 1 + max(p.rsub.ldepth,p.rsub.rdepth)
        elif p.rsub is None and p.lsub is not None :
            p.ldepth = 1 + max(p.lsub.ldepth,p.lsub.rdepth)
        else :
            p.ldepth = 1 + max(p.lsub.ldepth, p.lsub.rdepth)
            p.rdepth = 1 + max(p.rsub.ldepth, p.rsub.rdepth)

    def _isbalance(self,p):  #判斷結點是否平衡
        return abs(p.ldepth - p.rdepth) <= 1
    def _rebalance(self,p):  #使樹平衡

        while p is not None :
            if self._isbalance(p) :
                s = p
                while s is not None :
                    self._calAlldepth(s)
                    s = s.partet
                p = p.partet
            else :
                if p.ldepth > p.rdepth and p.lsub.ldepth > p.lsub.rdepth :
                    self._LL(p)
                elif p.ldepth > p.rdepth and p.lsub.ldepth < p.lsub.rdepth :
                    self._LR(p)
                elif p.ldepth < p.rdepth and p.rsub.ldepth < p.rsub.rdepth :
                    self._RR(p)
                else :
                    self._RL(p)
                s = p
                while s is not None:
                    self._calAlldepth(s)
                    s = s.partet
                p = p.partet

    #------------------------------樹平衡調節----------------------------
    def _LL(self,s):
        #p : s的父節點
        #a : 替代s
        #b : s的左孩子
        p = s.partet
        a = s
        b = a.lsub
        #調整根指針
        if p is not None :
            if a is p.lsub :
                p.lsub = b
            else :
                p.rsub = b
        else :  #結點爲根結點
            self.root = b
        #調整父節點位置
        if b.rsub is not None :
            b.rsub.partet = a

        #調整位置
        a.lsub = b.rsub
        b.rsub = a

        a.partet = b
        b.partet = p
    def _RR(self,s):
        p = s.partet
        a = s
        b = a.rsub
        #調整根指針
        if p is not None :
            if a is p.lsub :
                p.lsub = b
            else :
                p.rsub = b
        else :
            self.root = b
            # 調節父節點
        if b.lsub is not None:
            b.lsub.partet = a
        #調整位置
        a.rsub = b.lsub
        b.lsub = a
        a.partet = b
        b.partet = p
        #調整所有結點的深度
        #self._calAlldepth(p)
    def _RL(self,s) :
        p = s.partet
        a = s
        b = a.rsub
        c = b.lsub
        #調整根指針
        if p is not None :
            if a is p.lsub :
                p.lsub = c
            else :
                p.rsub = c
        else :
            self.root = c
            # 調整父節點指針
        if c.lsub is not None:
            c.lsub.partet = a
        else :  #當結點爲None,需要維持其父節點的高度
            a.rdepth = 0
        if c.rsub is not None:
            c.rsub.partet = b
        else :
            b.ldepth = 0
        #調整位置指針
        a.rsub = c.lsub
        b.lsub = c.rsub
        c.lsub = a
        c.rsub = b
        #調整父節點
        a.partet = c
        b.partet = c
        c.partet = p
    def _LR(self,s):
        p = s.partet
        a = s
        b = a.lsub
        c = b.rsub
        #調整根指針
        if p is not None :   #非根結點
            if a is p.lsub :
                p.lsub = c
            else :
                p.rsub = c
        else :              #根結點
            self.root = c
        # 調整父節點指針
        if c.lsub is not None:
            c.lsub.partet = b
        else :
            b.rdepth = 0
        if c.rsub is not None:
            c.rsub.partet = a
        else :
            a.ldepth = 0
        #調整位置
        b.rsub = c.lsub
        a.lsub = c.rsub
        c.lsub = b
        c.rsub = a
        #調整父節點
        a.partet = c
        b.partet = c
        c.partet = p
        #重新統計深度

    #------------------------------基本操作-----------------------------
    def _rebalance_mapinsert(self,p):   #封裝插入調節函數
        return self._rebalance(p)
    def _rebalance_mapdelete(self,p):
        self._calAlldepth(p)
        return self._rebalance(p)
#----------------------------基本操作--------------------------
    def mapinsert(self,keys,vals):
        tmpNode = self.root
        newNode = self.Node(Association(keys, vals))
        if tmpNode is None:
            self.root = newNode
        else:
            while tmpNode is not None:
                if keys < tmpNode.elem.keys:
                    if tmpNode.lsub is None:
                        tmpNode.lsub = newNode
                        newNode.partet = tmpNode
                        #更新所有父節點的高度
                        cNode = newNode
                        self._calAlldepth(cNode)
                        return self._rebalance_mapinsert(newNode)
                    tmpNode = tmpNode.lsub
                elif keys > tmpNode.elem.keys:
                    if tmpNode.rsub is None:
                        tmpNode.rsub = newNode
                        newNode.partet = tmpNode
                        cNode = newNode
                        self._calAlldepth(cNode)
                        return self._rebalance_mapinsert(newNode)
                    tmpNode = tmpNode.rsub
                else:   return
    def mapdelete(self,keys):
        # 查找到k的節點
        if self.search(keys) == -1:
            raise ValueError('Avl Tree uninclude keys ! ! !')
        cNode = self.root
        while cNode.elem.keys != keys:
            if keys < cNode.elem.keys:
                cNode = cNode.lsub
            elif keys > cNode.elem.keys:
                cNode = cNode.rsub
        pNode = cNode.partet

        if cNode.lsub is None and cNode.rsub is None:
            if pNode is not None:
                if pNode.lsub is cNode:
                    pNode.lsub = None
                else:
                    pNode.rsub = None
            else:
                self.root = None
                return self._rebalance_mapdelete(cNode)
        elif cNode.lsub is None and cNode.rsub is not None:  # 刪除的節點左孩子非空,右孩子爲空
            if pNode is not None:  # 刪除節點爲根節點
                if pNode.lsub is cNode:
                    pNode.lsub = cNode.rsub
                else:
                    pNode.rsub = cNode.rsub
            else:  # 刪除節點非根節點
                self.root = cNode.rsub
                return self._rebalance_mapdelete(cNode)
        elif cNode.lsub is not None and cNode.rsub is None:
            if pNode is not None:
                if pNode.lsub is cNode:
                    pNode.lsub = cNode.lsub
                else:
                    pNode.rsub = cNode.lsub
            else:
                self.root = cNode.lsub
            return self._rebalance_mapdelete(cNode)
        else :
            sNode = cNode.lsub
            while sNode.rsub is not None :
                sNode = sNode.rsub  #拿到左子樹的最大值
            tmpe1 = sNode.elem.keys
            tmpe2 = sNode.elem.vals
            self.mapdelete(sNode.elem.keys)
            cNode.elem.keys = tmpe1
            cNode.elem.vals = tmpe2
    def getTrees(self,root):
        if root is None :
            return
        self.getTrees(root.lsub)
        print(root.elem.vals,end=' ')
        self.getTrees(root.rsub)
    def search(self,keys):
        p = self.root
        while p is not None :
            if p.elem.keys == keys :
                return 0
            elif p.elem.keys > keys :
                p = p.lsub
            else :
                p = p.rsub
        return -1
    def getMin(self,p):
        while p.lsub is not None :
            p = p.lsub
        return p
    def getMax(self,p):
        while p.rsub is not None :
            p = p.rsub
        return p
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <math.h>
# define Max(a,b) (a) >(b)?(a):(b)

//============創建結點類=================
//--------------創建結點----------------- 
//  assitNode ;輔助結點,用於保存數據域的權值以及結點值 
//  Node :樹結點 
//  Tree : 初始化樹根結點 
//
//

typedef int KeysType;
typedef char ValsType;
typedef struct assitNode{
	KeysType keys;    
	ValsType vals;
}assitNode;

typedef struct Node{
	struct assitNode *elem;
	struct Node *lsub ;   //結點左右孩子 
	struct Node *rsub ;
	struct Node *partet;
	 //結點對應的左右子樹深度
	int ldepth;    
	int rdepth;
}Node;
//--------------初始化樹------------------

typedef struct{
	Node *root;
}Tree;
 
//================計算深度================

void calNewdepth(Node *);
void calPartetdepth(Node*);
void rebalance(Tree*,Node*);


void calNewdepth(Node *tmpNode) //更新單個結點深度 
{
	//計算結點左右子樹的深度值
	//初始值均爲零
	//如果某個子樹非空,則其左子樹的深度爲1 + 孩子結點左右子樹的最大值
	//        A(2)
   	//      /    \ 
	//    B(1)  C(1)     ---> B右子樹爲空,則其左子樹的高度爲孩子結點的左右子樹最大值+1 
	//   /    /   \
	//  D(0) E(0) F(0)   --->左右子樹均爲空,則取左右子樹高度爲0 
	 
	if(tmpNode->lsub==NULL && tmpNode->rsub==NULL)
	{
		tmpNode->ldepth = 0;
		tmpNode->rdepth = 0;	
	}
	else if(tmpNode->lsub != NULL && tmpNode->rsub==NULL) /*左非空右空*/
	{
		 tmpNode->rdepth = 0;
		 tmpNode->ldepth = 1 + Max(tmpNode->lsub->ldepth,tmpNode->lsub->rdepth);
	}
	else if(tmpNode->rsub != NULL && tmpNode->lsub==NULL)
	{
		tmpNode->ldepth = 0;
		tmpNode->rdepth = 1 + Max(tmpNode->rsub->ldepth,tmpNode->rsub->rdepth);	
	}
	else
	{
		tmpNode->ldepth = 1 + Max(tmpNode->lsub->ldepth,tmpNode->lsub->rdepth);
		tmpNode->rdepth = 1 + Max(tmpNode->rsub->ldepth,tmpNode->rsub->rdepth);
	}
	
}

void calPartetdepth(Node *tmpNode)  //更新所有的父節點深度 
{
	while(NULL !=tmpNode)
	{
		calNewdepth(tmpNode);
		tmpNode = tmpNode->partet;	
	}
}

//=======================輔助操作===============================

int isbalance(Node *tmpNode)  
{
	//如果結點未失衡返回0否則返回-1
	//判斷結點是否失衡的依據是該節點的左子樹高度減去右子樹高度 
	return (abs((tmpNode->ldepth)-(tmpNode->rdepth)) <= 1) ? 0 : -1;
}
 
void rebalance_mapinsert(Tree *tree,Node *tmpNode)
{
	rebalance(tree,tmpNode);	
}
void rebalance_mapdelete(Tree *tree,Node *tmpNode)
{
	calPartetdepth(tmpNode);
	rebalance(tree,tmpNode);
}

//==========================調整平衡策略==========================

void _left_left(Tree *tree,Node *tmpNode)
{
	
	//      partet --> A                 partet --> B
	//               /  \                         /  \
	//				B   @   ---------->          C   A
	//             / \                              / \
	//            C   @                            @   @
	
	Node *pNode = tmpNode->partet;
	Node *lsubNode = tmpNode->lsub; /*失衡結點左孩子*/
	//調整根結點
	if(pNode != NULL)
	{
		if(pNode->lsub == tmpNode)
		{
			pNode->lsub = lsubNode;
		}
		else
		{
			pNode->rsub = lsubNode;
		}
	}
	else
	{
		tree->root = lsubNode;
	}
	//調整父節點位置
	if(lsubNode->rsub != NULL)
	{
		lsubNode->rsub->partet = tmpNode;	
	} 
	
	tmpNode->lsub = lsubNode->rsub;
	lsubNode->rsub = tmpNode;
	tmpNode->partet = lsubNode;
	lsubNode->partet = pNode;
}

void _left_right(Tree *tree,Node *tmpNode)
{
	//       partet--> A                 partet -->  C
	//                /                            /  \
	//               B                            B   A
	//                \                           \  /
	//                 C                          @ &
	//                / \
	//               @  &
	Node *pNode = tmpNode->partet;
	Node *aNode = tmpNode;
	Node *bNode = aNode->lsub;
	Node *cNode = bNode->rsub;
	/*調整根結點指針*/
	if(pNode != NULL)
	{
		if(pNode->lsub = aNode)
		{
			pNode->lsub = cNode;
		}
		else
		{
			pNode->rsub = cNode;
		}	
	}
	else
	{
		tree->root = cNode;
		
	}
	
	//調整位置
	if(cNode->lsub != NULL)
	{
		cNode->lsub->partet = bNode;
	}
	else
	{
		bNode->rdepth = 0;
	}
	if(cNode->rsub != NULL)
	{
		cNode->rsub->partet = aNode;
	}
	else
	{
		aNode->ldepth = 0;
		
	} 
	
	bNode->rsub = cNode->lsub;
	aNode->lsub = cNode->rsub;
	cNode->lsub = bNode;
	cNode->rsub = aNode;
	aNode->partet = cNode;
	bNode->partet =	cNode;
	cNode->partet = pNode;
	
}



void _right_right(Tree *tree,Node *tmpNode)
{
	
	//         partet-->   A                        partet--> B
	//                    / \                               / \
	//                   @   B                             A   C
	//                      / \                           / \
	//                     @  C                          @  @     
	Node *pNode = tmpNode->partet;
	Node *rsubNode = tmpNode->rsub;
	//調整根指針
	if(pNode != NULL)
	{
		if(pNode->lsub==tmpNode)
		{
			pNode->lsub = rsubNode;
		}
		else
		{
			pNode->rsub = rsubNode;
		}
	}
	else
	{
		tree->root = rsubNode;
	} 
	//調整父節點位置
	if(rsubNode->lsub != NULL)
	{
		rsubNode->lsub->partet = tmpNode;		
	} 
	
	//調整位置
	tmpNode->rsub = rsubNode->lsub;
	rsubNode->lsub = tmpNode; 
	tmpNode->partet = rsubNode;
	rsubNode->partet = pNode;
	
}

void _right_left(Tree *tree,Node *tmpNode)
{ 
	//      partet --> A                partet -->   C
	//                  \                          /  \
	//                   B                        A    B
	//                  /                          \  /
	//                 C                           @ &
	//                / \
	//               @   &
	Node *pNode = tmpNode->partet;
	Node *aNode = tmpNode;
	Node *bNode = aNode->rsub;
	Node *cNode = bNode->lsub;
	/*調整根指針*/
	if(pNode != NULL)
	{
		if(pNode->lsub == tmpNode)
		{
			pNode->lsub = cNode;
		}
		else
		{
			pNode->rsub = cNode;
		}
	}
	else
	{
		tree->root = cNode;
	}
	/*調整cNode的孩子*/
	if(cNode->lsub != NULL)
	{
		cNode->lsub->partet = aNode;
	}
	else
	{
		aNode->ldepth = 0;
	}
	if(cNode->rsub != NULL)
	{
		cNode->rsub->partet = bNode;
	}
	else
	{
		bNode->rdepth = 0;
	}
	aNode->rsub = cNode->lsub;
	bNode->lsub = cNode->rsub;
	cNode->lsub = aNode;
	cNode->rsub = bNode;
	aNode->partet = cNode;
	bNode->partet = cNode;
	cNode->partet = pNode;

} 

//==========================調整平衡操作===========================
void rebalance(Tree *tree,Node *tmpNode)
{
	while(tmpNode != NULL)
	{
		if(isbalance(tmpNode)== 0)
		{
			calPartetdepth(tmpNode);	
			tmpNode = tmpNode->partet;
		}
		else if(isbalance(tmpNode)== -1)
		{
			if((tmpNode->ldepth > tmpNode->rdepth)&&(tmpNode->lsub->ldepth > tmpNode->lsub->rdepth))
			{
				_left_left(tree,tmpNode);
			}
			else if((tmpNode->ldepth > tmpNode->rdepth)&&(tmpNode->lsub->ldepth < tmpNode->lsub->rdepth))
			{
				_left_right(tree,tmpNode);
			}
			else if((tmpNode->rdepth > tmpNode->ldepth)&&(tmpNode->rsub->ldepth < tmpNode->rsub->rdepth))
			{
				_right_right(tree,tmpNode); 
			}
			else
			{
				_right_left(tree,tmpNode);
			}
			calPartetdepth(tmpNode);
			tmpNode = tmpNode->partet;
		}
	}
} 
Node *createNewNode()
{	
	Node *newNode = (Node*)malloc(sizeof(Node));
	newNode->elem->keys = keys;
	strcpy(newNode->elem->vals,vals);
	newNode->partet = NULL;
	newNode->ldepth = 0;
	newNode->rdepth = 0;
	return newNode;
}

void mapinsert(Tree *tree,int keys,char *vals)
{
	Node *newNode = createNewNode();
	Node *tmpNode = tree->root;
	if(tmpNode == NULL)
	{
		tree->root = newNode;
	}
	else
	{
		while(NULL != tmpNode)
		{
			if(tmpNode->elem->keys > keys)
			{
				if(tmpNode->lsub ==NULL)
				{
					tmpNode->rsub = newNode;
					newNode->partet = tmpNode;
					cNode = newNode;
					calPartetdepth(cNode);
					return rebalance(tree,newNode)
				}
				tmpNode = tmpNode->lsub;
			}
			else if(tmpNode->elem->keys < keys)
			{
				if(tmpNode->rsub ==NULL)
				{
					tmpNode->lsub = newNode;
					newNode->partet = tmpNode;
					cNode = newNode;
					calPartetdepth(cNode);
					return rebalance(tree,newNode)
				}
				tmpNode = tmpNode->rsub;
			}
			else
			{
				return ;
			}
		}
	}		
}


void mapdelete(Tree *tree,int keys)
{
	/*查找指定元素*/
	Node *tmpNode = tree->root;
	
	while(tmpNode->elem->keys != keys)
	{
		if(tmpNode->elem->keys > keys)
		{
			tmpNode = tmpNode->lsub;
		}
		else
		{
			tmpNode = tmpNode->rsub;
		}
	}

	Node *pNode =tmpNode->partet;   /*刪除結點的父節點*/
		
	if((tmpNode->lsub == NULL)&&(tmpNode->rsub ==NULL)) //待刪除結點無左右孩子 
	{
		if(pNode == NULL)
		{
			tree->root = NULL;	
		}
		else
		{
			if(pNode->lsub == tmpNode)
			{
				pNode->lsub = NULL;
			}
			else
			{
				pNode->rsub = NULL;
			}
		}
		calPartetdepth(tmpNode);
		rebalance(tmpNode);
	}
	
	else if((tmpNode->lsub==NULL)&&(tmpNode->rsub != NULL)) //待刪除的結點只有右孩子 
	{
		if(pNode == NULL)
		{
			tree->root = tmpNode->rsub;
		}
		else
		{
			if(pNode->lsub == tmpNode)
			{
				pNode->lsub = tmpNode->rsub;
			}	
			else
			{
				pNode->rsub = tmpNode->rsub;	
			} 
		}
		calPartetdepth(tmpNode);
		rebalance(tmpNode);
	}

	else if((tmpNode->lsub != NULL)&&(tmpNode->rsub ==NULL))  //待刪除的結點只有左孩子 
	{
		if(pNode==NULL)
		{
			tree->root = tmpNode->lsub;
		}
		else
		{
			if(pNode->lsub = tmpNode)
			{
				pNode->lsub = tmpNode->lsub;
				
			}
			else
			{
				pNode->rsub = tmpNode->lsub; 
			}
		}
		calPartetdepth(tmpNode); 
		rebalance(tmpNode);
	}
	
	else  //待刪除的結點既有左孩子又有右孩子 
	{
		Node *sNode = tree->root->lsub;
		while( sNode->rsub != NULL)
		{
			sNode = sNode->rsub;
		}
		int tmpe1 = sNode->elem->keys;
		char tmpe2 = sNode->elem->vals;
		mapdelete(tree,sNode->elem->keys);
		tmpNode->elem->keys = tmpe1;
		strcpy(tmpNode->elem->vals,tmpe2);
	}	
}
//--------------------------其他操作--------------------- 

 int getMax(Tree *tree) /*獲取樹中結點的最大值*/ 
{
	Node *tmpNode = tree->root;
	while(tmpNode->rsub != NULL)
	{
		tmpNode =tmpNode->rsub;
	}
	return tmpNode->elem->vals; 
}
int getMin(Tree *tree)  /*獲取樹中結點的最小值*/ 
{
	Node *tmpNode = tree->root;
	while(tmpNode->lsub != NULL)
	{
		tmpNode = tmpNode->lsub;
	}
	return tmpNode->elem->vals;
}



void getTrees(Node *tmpNode){  /*中序遍歷得到樹種結點*/
	if(tmpNode != NULL)
	{
		return ;
	}
	else
	{
		getTrees(tmpNode->lsub);
		printf("%2s",tmpNode->elem->vals);
		getTrees(tmpNode->rsub);
	}
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章