數據結構:二叉樹和二叉搜索樹

二叉樹創建(層序)

與層序有關的要用到隊列,因此創建一個隊列

Bintree creat()//二叉樹層序創建(想用C++STL庫的,到時候改成new)
{
	int data;
	BinTree BT,T;
	
	scanf("%d",&data);
	if(data!=0)
	{
		BT=(BinTree)malloc(sizeof(struct TNode));
		BT->data=data;
		BT->left=NULL;
		BT->right=NULL;
		q.push(data);
	}
	else return NULL;

	while(!q.empty())
	{
		T=q.front();
		scanf("%d",&data);
		if(data==0) T->left=NULL;
		else{
			T->left=(BinTree)malloc(sizeof(struct TNode));
			T->left->data=data;
			q.push(T->left)
		} 
		scanf("%d",&data);
		if(data==0) T->right=NULL;
		else{
			T->right=(BinTree)malloc(sizeof(struct TNode));
			T->right->data=data;
			q.push(T->right)
		} 
		
	}
	
	return BT;
}

輸出二叉樹中所有葉結點

分析:用到的知識是二叉樹的遍歷,在遍歷的時候加條件(左子樹和右子樹都爲空即可)

void Preorderprintleaves(BinTree BT)
{
	if(BT)
	{
		if(!BT->left&&!BT->right)
		{
			printf("%d",BT->data);
		}	
		Preorderprintleaves(BT->left);
		Preorderprintleaves(BT->right);
	}
 } 

遞歸求二叉樹高度

分析:求二叉樹高度=求左子樹高度和求右子樹高度中最大的那個=…=…(遞推下去吧)

int getHeight(BinTree BT)
 {
 	int HL,HR,MAXH;
 	
 	if(BT)
 	{
 		HL=getHeight(BT->left);
 		HR=getHeight(BT->right);
 		MAXH=HL>HR?HL:HR;
 		return(MAXH+1);
	 }
	 else return 0;/*空樹高度爲0*/
 }

二叉搜索樹(BST)的查找

注意返回的還是指針,指向二叉樹的結點
如果發現BST爲空了(查完了還沒找到) 返回查找失敗

typedef struct node *Bintree;
struct node{
int data;
Bintree left,right;
};

Bintree find(Bintree BST,int x)
{
   if(!BST) return NULL;
   else
   {
   	if(BST->data==x) return BST;//返回當前結點的地址
   	else if(BST->data>x) return find(BST->left,x);
   	else if(BST->data<x) return find(BST->right,x); 
   }
}

查找BST的最大最小值

方法一:遞歸
方法二:迭代

利用BST的性質,最小元素一定在樹的最左分支的端結點上

Bintree FindMax(Bintree BST)
{
	if(!BST) return NULL;
	else if(BST->right==NULL) return BST;
	else return FindMax(BST->right);

}

Bintree findmin(Bintree BST)
{
	if(BST)
	{
	
	while(BST->left)
	{
		BST=BST->left;
	}
	return BST;
	}
}

BST的插入

操作類似於查找,必須記得分情況
原樹爲空,那麼建一個只有一個結點的樹
原樹不爲空,遞歸尋找插入的位置

最後返回的也是指針,指向插入元素的位置
(遞歸真是個好東西啊)

Bintree insert(Bintree BST,int x)
{
	if(!BST)
	{
		BST=(Bintree)malloc(sizeof(struct node));
		BST->data=x;
		BST->left=BST->right=NULL;
	}
	else
	{
		if(BST->data>x)
		{
			insert(BST->left,x);
		}
		else if (BST->data<x)
		{
			insert(BST->right,x);
		}
	}
	return BST;
}

二叉搜索樹的插入其實還是很方便的,因爲數據的插入後一定接在樹下方,不影響其他結點,但是刪除就相對複雜了,一個結點的刪除會影響其他結點的位置

二叉搜索樹的刪除

三種情況
1.刪除的是葉結點
2.刪除的結點只有一個孩子結點
3.刪除的結點有左右兩顆子樹,那麼要轉換爲第二種情況:選取左子樹中的最大元素或者右子樹的最小元素(利用上面講的findmax和findmin函數鴨)

Bintree delete(Bintree BST,int x)
{
	//先找到要被刪除的元素
	Bintree tmp;
	if(!BST) return printf("未找到")else
	{
		if(x<BST->data) delete(BST->left,x);
		else if(x>BST->data) delete(BST->right,x);
		else if(x==BST->data)
		{
			if(BST->left&&BST->right)
			/*有兩個子節點*/
			{
				tmp=findmin(BST->right);
				BST->data=tmp->data;
				/*重要過程?遞歸(why?如何理解?)*/
				BST->right=delete(BST->right,BST->data); 
			}
			else
			{
				tmp=BST;
				if(!BST->left)//只有右孩子
				BST=BST->right;
				else
				{
					BST=BST->left;
				} 
				free(tmp);//原來數據被刪除,指針改變方向 
			}
			
		}
		
	return BST;
	} 
}
//最後返回值還是指針,指向的是刪除後的結點,原來的數據不復存在 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章