1. 程式人生 > >二叉排序樹的基本操作(建立,中序遍歷,查詢,刪除,插入)

二叉排序樹的基本操作(建立,中序遍歷,查詢,刪除,插入)

分析:

二叉排序樹的操作的難點在於刪除操作,刪除操作時,只需要滿足二叉排序樹的性質即可,即需要找到要刪除結點p的左孩子的最右下方的數替代該結點的資料,然後刪除p->lchild的最右下方的結點即可。

對於p->lchild==NULL的,只需要讓雙親結點直接指向p->rchild即可(對於根節點,只需要改變頭指標)。

對於p->lchild沒有右子樹的,讓刪除結點左孩子的資料賦值到刪除結點上,然後讓刪除結點的左孩子等於p->lchild->lchild

程式碼如下:

#include <stdio.h>
#include <stdlib.h>
typedef struct tree{
	struct tree *lchild,*rchild;
	int data;
}*BiTree,BiNode;

void Insert(BiTree bt,int data)
{//關鍵字的插入 
	BiTree p,s,parent;
	p=bt;
	while(p)
	{
		if(data<p->data)
		{
			parent=p;
			p=p->lchild;
		}
		
		else if(data>p->data)
		{
			parent=p;
			p=p->rchild;
		}
		else
			return ;
	}
	
	s=(BiTree)malloc(sizeof(BiNode));
	s->data=data;
	s->lchild=s->rchild=NULL;
	if(s->data<parent->data)
		parent->lchild=s;
	else
		parent->rchild=s;
}

void InitTree(BiTree &bt,int n)
{//建立二叉排序樹 
	int data,i;
	scanf("%d",&data);
	bt=(BiTree)malloc(sizeof(BiNode));
	bt->data=data;
	bt->lchild=bt->rchild=NULL;
	for(i=1;i<n;i++)
	{
		scanf("%d",&data);
		Insert(bt,data);
	}
}

void InOrder(BiTree bt)
{//樹的中序遍歷 
	if(!bt)
		return ;

	InOrder(bt->lchild);
	printf("%d ",bt->data);
	InOrder(bt->rchild);
}

int Search(BiTree bt,int key)
{
	BiTree p;
	p=bt;
	while(p)
	{
		if(key<p->data)
			p=p->lchild;
		else if(key>p->data)
			p=p->rchild;
		else
		{
			printf("數字%d查詢成功。\n",key);
			return 1;
		}
	}
	printf("未找到資料%d。\n",key); 
	return 0;
}

void Delete_BiTree(BiTree &bt,int key)
{
	BiTree p,cur,par;
	p=bt;
	while(p){
		if(key==p->data)
			break;
		else if(key<p->data){
			par=p;
			p=p->lchild;
		}
		else{
			par=p;
			p=p->rchild;
		}	
	}
	
	if(!p){
		printf("該資料不存在.\n");
		return ;
	}
	
	if(!p->lchild)		//沒有左子樹 
	{
		if(p==bt)
			bt=p->rchild; 
		else if(par->lchild==p)
			par->lchild=p->rchild;
		else
			par->rchild=p->rchild;
		free(p);
	}
	

	else
	{
		cur=p->lchild;
		par=cur;
		while(cur->rchild)
		{
			par=cur;
			cur=cur->rchild;
		}
		
		if(par==p->lchild)			//p的左孩子沒有右子樹 
		{
			p->data=par->data;
			p->lchild=par->lchild;
			free(par);
		}
		else						//p的左孩子有右子樹 
		{
			p->data=cur->data;
			par->rchild=cur->lchild;
			free(cur);
		}
	}
	printf("刪除成功.\n");
}


int main()
{
	BiTree bt;
	int n,key,selet;	
	while(1)
	{
		printf("		------------------\n");
		printf("		1、建立二叉排序樹\n");
		printf("		2、輸出中序遍歷結果\n");
		printf("		3、搜尋資料\n");
		printf("		4、刪除資料\n");
		printf("		5、插入資料\n");
		printf("		6、退出\n"); 
		printf("		------------------\n");
		
		scanf("%d",&selet);
		switch(selet)
		{
			case 1:
				printf("輸入數字的個數:");
				scanf("%d",&n);
				printf("請輸入每個數字:");
				InitTree(bt,n);
				break;
			case 2:	
				printf("中序遍歷結果為:");
				InOrder(bt);
				putchar('\n');
				break;
			case 3:
				printf("請輸入查詢的關鍵字:");
				scanf("%d",&key);
				Search(bt,key);
				break;
			case 4:
				printf("請輸入刪除的關鍵字:");
				scanf("%d",&key);
				Delete_BiTree(bt,key);
				break;
			case 5:
				printf("請輸入要插入的資料:");
				scanf("%d",&key); 
				Insert(bt,key);
				printf("插入成功.\n");
				break;
			default:
				return 0;
		}
	}
}