Chapter 4 Tree

二叉树

#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct BTNode
{
	ElemType Data;		//数据元素
	struct BTNode *Lchild;	//指向左孩子结点
	struct BTNode *Rchild;	//指向右孩子结点
}*BTree,*Position ;
void CreateBTree(BTree &T, char *str)  
{
	BTree St[MaxSize];
	Position P = NULL;
	int Top = -1, k, j = 0;
	char ch = str[j];
	T = NULL;		//建立的二叉树初始时为空
	while (ch != '\0')  	//str未扫描完时循环
	{
		switch (ch)
		{
		case '(':Top++; St[Top] = P; k = 1; break;		//为左孩子结点
		case ')':Top--; break;
		case ',':k = 2; break;                      		//为孩子结点右结点
		default:P = (BTNode*)malloc(sizeof(BTNode));
			P->Data = ch; P->Lchild = P->Rchild = NULL;
			if (T == NULL)                    	 	//P为二叉树的根结点
				T = P;
			else  						//已建立二叉树根结点
			{
				switch (k)
				{
				case 1:St[Top]->Lchild = P; break;
				case 2:St[Top]->Rchild = P; break;
				}
			}
		}
		ch = str[++j];
	}
}

Position FindNode(BTree T, ElemType X) //查找某一节点
{
	Position P;
	if (T == NULL)
		return NULL;
	else if (T->Data == X)   //找到了
		return T;
	else
	{
		P = FindNode(T->Lchild, X);           //递归查找左子树
		if (P != NULL)
			return P;                     //如果找到,返回节点位置
		else
			return FindNode(T->Rchild, X); //递归查找右子树
	}
}

Position LchildNode(Position P) //返回左孩子
{
	return P->Lchild;
}

Position RchildNode(Position P) //返回右孩子
{
	return P->Rchild;
}

int BTreeHeight(BTree T)
{
	int LHeight, RHeight;
	if (T == NULL) 
		return 0; 				//空树的高度为0
	else
	{
		LHeight = BTreeHeight(T->Lchild);	//求左子树的高度为LHeight
		RHeight = BTreeHeight(T->Rchild);	//求右子树的高度为RHeight
		return (LHeight > RHeight) ? (LHeight + 1) : (RHeight + 1);
	}
}

void DispBTree(BTree T)
{
	if (T != NULL)
	{
		printf("%c", T->Data);
		if (T->Lchild != NULL || T->Rchild != NULL)
		{
			printf("(");				//有孩子结点时才输出(
			DispBTree(T->Lchild);			//递归处理左子树
			if (T->Rchild != NULL) printf(",");	//有右孩子结点时才输出,
			DispBTree(T->Rchild);			//递归处理右子树
			printf(")");				//有孩子结点时才输出)
		}
	}
}

int NodeNum(BTree T) //计算树的节点个数
{
	if (T)
		return NodeNum(T->Lchild) + NodeNum(T->Rchild) + 1;
	else
		return 0;
}

void PreOrder(BTree T) //前序遍历
{
	if (T == NULL)
		return;
	printf("%c ", T->Data);
	PreOrder(LchildNode(T));
	PreOrder(RchildNode(T));
}

void InOrder(BTree T) //中序遍历
{
	if (T == NULL)
		return;
	InOrder(LchildNode(T));
	printf("%c ", T->Data);
	InOrder(RchildNode(T));
}

void PostOrder(BTree T)  //后序遍历
{
	if (T == NULL)
		return;
	PostOrder(LchildNode(T));
	PostOrder(RchildNode(T));
	printf("%c ", T->Data);
}

void PrintNodeAtLevel(BTree T, int Level) //打印当前层的节点
{
	// 空树或层级不合理
	if (T == NULL || Level < 1)
		return;
	if (Level == 1)
	{
		printf("%c ", T->Data);
		return;
	}
	// 左子树的 level - 1 级
	PrintNodeAtLevel(T->Lchild, Level - 1);
	// 右子树的 level - 1 级
	PrintNodeAtLevel(T->Rchild, Level - 1);
}

void TravLevel(BTree T)  //逐层遍历二叉树
{
	if (T == NULL)
		return;
	int Height = BTreeHeight(T);
	int i;
	for (i = 1; i <= Height; i++)
	{
		PrintNodeAtLevel(T, i);
		printf("\n");
	}
}


int main()
{
	BTree T;
	T = (BTNode*)malloc(sizeof(BTNode));
	CreateBTree(T, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
	printf("输出二叉树:");
	DispBTree(T);
	printf("\n");
	Position N = FindNode(T, 'H');
	Position P = LchildNode(N);
	printf("H的左孩子是:%c ,", P->Data);
	P = RchildNode(N);
	printf("右孩子是: %c .\n", P->Data);
	printf("二叉树b的深度: %d.\n", BTreeHeight(T));
	printf("二叉树b的结点个数: %d.\n", NodeNum(T));
	printf(" 先序遍历序列:\n");
	printf("     递归算法:"); PreOrder(T); printf("\n");
	printf(" 中序遍历序列:\n");
	printf("     递归算法:"); InOrder(T); printf("\n");
	printf(" 后序遍历序列:\n");
	printf("     递归算法:"); PostOrder(T); printf("\n");
	printf(" 层次遍历序列:"); printf("\n");
	TravLevel(T); printf("\n");

	return 0;
}

二叉搜索树

#include <stdio.h>
#include <malloc.h>
typedef int KeyType;
typedef char InfoType[10];
typedef struct TreeNode           		//记录类型
{
	KeyType Key;              		//关键字项
	InfoType Data;             		//其他数据域
	struct TreeNode *Lchild, *Rchild;	//左右孩子指针
} *BSTree,*Position;
int InsertBST(BSTree &T, KeyType K)
{
	if (T == NULL)				//原树为空, 新插入的记录为根结点
	{
		T = (TreeNode*)malloc(sizeof(TreeNode));
		T->Key = K;
		T->Lchild = T->Rchild = NULL;
		return 0;
	}
    if (K == T->Key) 				//树中存在相同关键字的结点,返回-1
		return -1;
	else if (K < T->Key)
		return InsertBST(T->Lchild, K);	//插入到T的左子树中
	else if(K > T->Key)
		return InsertBST(T->Rchild, K);  //插入到T的右子树中
}

void DispBST(BSTree T)		                 //输出一棵排序二叉树
{
	if (T != NULL)
	{
		printf("%d", T->Key);
		if (T->Lchild != NULL || T->Rchild != NULL)
		{
			printf("(");					//有孩子结点时才输出(
			DispBST(T->Lchild);				//递归处理左子树
			if (T->Rchild != NULL)
				printf(",");	//有右孩子结点时才输出,
			DispBST(T->Rchild);				//递归处理右子树
			printf(")");					//有孩子结点时才输出)
		}
	}
}
Position CreateBST(KeyType a[], int n)	//返回BST树根结点
{
	BSTree T = NULL;         			//初始时T为空树
	int i = 0;
	while (i < n)
	{
		printf("   第%d步,插入%d元素:", i + 1, a[i]);
		InsertBST(T, a[i++]);  			//将关键字a[i]插入二叉排序树T中
		DispBST(T); printf("\n");
	}
	return T;               			//返回建立的二叉排序树的根
}
Position SearchBST(BSTree T, KeyType K)
{
	if (T == NULL)      	
		return T;
	if (K < T->Key)
		return SearchBST(T->Lchild, K);  //在左子树中递归查找
	else if (K > T->Key)
		return SearchBST(T->Rchild, K);  //在右子树中递归查找
	else
		return T;
}
Position SearchBST1(BSTree T, KeyType K, BSTree f1, BSTree &f)
/*在T中查找关键字为k的结点,若查找成功,该函数返回该结点的指针,
  f返回其双亲结点;否则,该函数返回NULL。其调用方法如下:
  SearchBST(bt,x,NULL,f);
  这里的第3个参数f1仅作中间参数,用于求f,初始设为NULL*/
{
	if (T == NULL)
	{
		f = NULL;
		return NULL;
	}
	else if (K == T->Key)
	{
		f = f1;
		return T;
	}
	else if (K < T->Key)
		return SearchBST1(T->Lchild, K, T, f);  //在左子树中递归查找
	else 
		return SearchBST1(T->Rchild, K, T, f);  //在右子树中递归查找
}

Position FindMin(BSTree T)    //递归实现
{
	if (T == NULL)
		return NULL;
	if (T->Lchild == NULL)
		return T;
	else
		return FindMin(T->Lchild);
}

Position FindMax(BSTree T)   //非递归实现
{
	if (T != NULL)
		while (T->Rchild != NULL)
			T = T->Rchild;
	return T;
}

Position DeleteBST(BSTree T, KeyType K)
{
	Position TmpCell;
	if (T == NULL) //树T为空
		return T;
	if (K < T->Key)
		T->Lchild = DeleteBST(T->Lchild, K);   //递归查找左子树
	else if (K > T->Key)
		T->Rchild = DeleteBST(T->Rchild, K);   //递归查找右子树
	else  //找到节点
	{
		if (T->Lchild && T->Rchild)            //有两个孩子
		{
			TmpCell = FindMin(T->Rchild);  //查找右子树中最小的节点
			T->Key = TmpCell->Key;
			T->Rchild = DeleteBST(T->Rchild, T->Key);
		}
		else                                   //只有一个孩子或没有孩子
		{
			TmpCell = T;
			if (T->Lchild == NULL)         //没有左孩子
				T = T->Rchild;
			else if (T->Rchild == NULL)    //没有右孩子
				T = T->Rchild;
			free(TmpCell);
		}
	}
	return T;
}

Position Search1(BSTree T, KeyType K) //递归查找某一节点
{
	if (T == NULL)
		return NULL;
	printf("%d ",T->Key);
	if (K < T->Key)
		return Search1(T->Lchild, K);
	else if (K > T->Key)
		return Search1(T->Rchild, K);
	else
		return T;
}

Position Search2(BSTree T, KeyType K) //非递归查找某一节点
{
	if (T == NULL)
		return NULL;
	while (T) {
		printf("%d ", T->Key);
		if (K < T->Key)
			T = T->Lchild;
		else if (K > T->Key)
			T = T->Rchild;
		else
			return T;
	}
}

int IsBST(BSTree T)    //判断该树是否为二叉排序树 
{
	                       //静态变量,只执行一次!!!
	static int  flag = 1;  //标记节点是否符合二叉排序树的要求
	static int LastKey = 0;//记录上一节点的关键值
	                       //类似中序遍历!!!
	if (T->Lchild && flag)
		IsBST(T->Lchild);
	if (T->Key < LastKey)
		flag = 0;
	LastKey = T->Key;
	if (T->Rchild && flag)
		IsBST(T->Rchild);
	return  flag;
}

int Compare(BSTree T, BSTree P)  //比较两棵二叉树是否相同
{
	if (T == NULL && P == NULL)
		return 1;
	else if (T != NULL && P != NULL)
	{
		if (T->Key == P->Key)
			return Compare(T->Lchild, P->Lchild) && Compare(T->Rchild, P->Rchild);
		else
			return 0;
	}
	else
		return 0;
}
void main()
{
	BSTree T;
	int x = 46, i;
	KeyType a[] = { 4,9,0,1,8,6,3,5,2,7 };
	int n = 10;
	printf(" 创建一棵BST树:\n");
	T = CreateBST(a, n);
	printf("   BST:"); DispBST(T); printf("\n");
	(IsBST(T) == 1) ? printf("bt是一棵BST树 \n") : printf("bt不是一棵BST树\n");
	printf("查找关键字(递归):");
	Search1(T, 6);
	printf("\n");
	printf("查找关键字(非递归):");
	Search2(T, 6);
	printf("\n");
	printf("删除操作:\n");
	printf("原BFS:");
	DispBST(T); printf("\n");
	printf("删除节点4:");
	DeleteBST(T, 4);
	DispBST(T); printf("\n");
	printf("删除节点5:");
	DeleteBST(T, 5);
	DispBST(T); printf("\n");
}

平衡二叉树

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct AvlNode
{
	ElementType Element;
	struct AvlNode *Left;
	struct AvlNode *Right;
	int Height;
}*AvlTree,*Position;

int Height(Position P)
{
	if (P == NULL)
		return -1;
	else
		return P->Height;
}

int Max(int a, int b)
{
	if (a > b)
		return a;
	else
		return b;
}

Position SingleRotateWithLeft(Position K2)
{
	Position K1;

	K1 = K2->Left;
	K2->Left = K1->Right;
	K1->Right = K2;

	K1->Height = Max(Height(K1->Right), Height(K1->Left)) + 1;
	K2->Height = Max(Height(K2->Right), Height(K2->Left)) + 1;

	return K1;
}

Position SingleRotateWithRight(Position K2)
{
	Position K1;

	K1 = K2->Right;
	K2->Right = K1->Left;
	K1->Left = K2;

	K1->Height = Max(Height(K1->Left), Height(K1->Right)) + 1;
	K2->Height = Max(Height(K2->Left), Height(K2->Right)) + 1;

	return K1;
}

Position DoubleRotateWithLeft(Position K3)
{
	K3->Left = SingleRotateWithRight(K3->Left);

	return SingleRotateWithLeft(K3);
}

Position DoubleRotateWithRight(Position K3)
{
	K3->Right = SingleRotateWithLeft(K3->Right);

	return SingleRotateWithRight(K3);
}

AvlTree Insert(AvlTree T, ElementType X)
{
	if (T == NULL)
	{
		T = (AvlNode*)malloc(sizeof(AvlNode));
		T->Element = X;
		T->Height = 0;
		T->Left = T->Right = NULL;
	}
	else
	{
		if (X < T->Element)
		{
			T->Left = Insert(T->Left, X);
			if (Height(T->Left) - Height(T->Right) == 2)
			{
				if (X < T->Left->Element)
					T = SingleRotateWithLeft(T);
				else
					T = DoubleRotateWithLeft(T);
			}
		}
		else if (X > T->Element)
		{
			T->Right = Insert(T->Right, X);
			if (Height(T->Right) - Height(T->Left) == 2)
			{
				if (X > T->Right->Element)
					T = SingleRotateWithRight(T);
				else
					T = DoubleRotateWithRight(T);
			}
		}
	}
	T->Height = Max(Height(T->Left), Height(T->Right)) + 1;

	return T;
}

Position FindMin(AvlTree T)  
{
	if (T == NULL)
		return NULL;
	if (T->Left == NULL)
		return T;
	else
		return FindMin(T->Right);
}

Position Delete(AvlTree T,ElementType X)
{
	Position Temp;
	if (T == NULL)
		return NULL;
	else if (X < T->Element)
	{
		T->Left = Delete(T->Left, X);
		if (Height(T->Right) - Height(T->Left) == 2)
			//由于在左子树的删除导致在T处平衡被破坏  
			if (Height(T->Right->Left) > Height(T->Right->Right))
				//如果T->Right的左子树比右子树高,执行双旋转  
				T = DoubleRotateWithRight(T);
			else
				//否则执行单旋转  
				T = SingleRotateWithRight(T);
	}
	else if (X > T->Element)
	{
		T->Right = Delete(T->Right, X);
		if (Height(T->Left) - Height(T->Right) == 2)
			//由于在右子树的删除导致在T处平衡被破坏  
			if (Height(T->Left->Right) > Height(T->Left->Left))
				//如果T->Left的左子树比右子树要高,执行单旋转  
				T = SingleRotateWithLeft(T);
			else
				//否则执行双旋转  
				T = DoubleRotateWithLeft(T);
	}
	else 
	{//正常的删除策略  
		if (T->Left && T->Right)
		{
			Temp = FindMin(T->Right);
			T->Element = Temp->Element;
			T->Right = Delete(T->Right, T->Element);
		}
		else
		{
			Temp = T;
			if (T->Left == NULL)
				T = T->Right;
			else if (T->Right == NULL)
				T = T->Left;
			free(Temp);
		}
	}	
	if (T)
		//最后更新高度,此处可能T已经被设置成了NULL,所以需要检测下  
	    T->Height = Max(Height(T->Left), Height(T->Right)) + 1;

	return T;
}

int main()
{
	AvlTree T = (AvlNode*)malloc(sizeof(AvlNode));
	T = NULL;
	int A[] = { 0,1,2,3,4,5,6,7,8,9 };
	for (int i = 0; i < 10; i++)
		T = Insert(T, A[i]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章