树集锦

/* 
1、二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
2、AVL树
3、二叉查找树


 */
//
//二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现
//tree.h
/********************************************************************
    created:    2005/12/30
    created:    30:12:2005   10:39
    filename:     bintree.h
    author:        Liu Qi
    
    purpose:    二叉树的3种遍历方式(包括非递归实现),前序,后序和中序,先访问根节点就是
    前序(部分书籍称为先根遍历,个人觉得该说法更好^_^),类似的,最后访问根节点就是后序
*********************************************************************/


#ifndef TREE_H
#define TREE_H

#include <stdio.h>
#include <malloc.h>
#include <stack>
#include <queue>
#include <assert.h>

using namespace std;

typedef int ElemType;

typedef struct treeT
{
    ElemType key;
    struct treeT* left;
    struct treeT* right;
}treeT, *pTreeT;


/*===========================================================================
* Function name:    visit
* Parameter:        root:树根节点指针
* Precondition:        
* Description:        
* Return value:        
* Author:            Liu Qi, //-
===========================================================================*/
static void visit(pTreeT root)
{
    if (NULL != root)
    {
        printf(" %d\n", root->key);
    }
}



/*===========================================================================
* Function name:  BT_MakeNode    
* Parameter:      target:元素值    
* Precondition:      None    
* Postcondition:  NULL != pTreeT 
* Description:      构造一个tree节点,置左右指针为空,并且返回指向新节点的指针    
* Return value:      指向新节点的指针    
* Author:            Liu Qi,  [12/30/2005]
===========================================================================*/
static pTreeT BT_MakeNode(ElemType target)
{
    pTreeT pNode = (pTreeT) malloc(sizeof(treeT));

    assert( NULL != pNode ); 

    pNode->key   = target;
    pNode->left  = NULL;
    pNode->right = NULL;
    
    return pNode;
}


/*===========================================================================
* Function name:    BT_Insert
* Parameter:        target:要插入的元素值, pNode:指向某一个节点的指针
* Precondition:         NULL != ppTree 
* Description:        插入target到pNode的后面
* Return value:        指向新节点的指针
* Author:            Liu Qi,  [12/29/2005]
===========================================================================*/
pTreeT BT_Insert(ElemType target, pTreeT* ppTree)
{
    pTreeT Node;

    assert( NULL != ppTree ); 

    Node = *ppTree;
    if (NULL == Node)
    {
        return *ppTree = BT_MakeNode(target);
    }

    if (Node->key == target)    //不允许出现相同的元素
    {
        return NULL;
    }
    else if (Node->key > target)    //向左
    {
        return BT_Insert(target, &Node->left);
    }
    else
    {
        return BT_Insert(target, &Node->right);
    }
}




/*===========================================================================
* Function name:    BT_PreOrder
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        前序遍历
* Return value:        void
* Author:            Liu Qi,  [12/29/2005]
===========================================================================*/
void BT_PreOrder(pTreeT root)
{
    if (NULL != root)
    {
        visit(root);
        BT_PreOrder(root->left);
        BT_PreOrder(root->right);
    }    
}


/*===========================================================================
* Function name:    BT_PreOrderNoRec
* Parameter:        root:树根节点指针
* Precondition:        Node
* Description:        前序(先根)遍历非递归算法
* Return value:        void
* Author:            Liu Qi,  [1/1/2006]
===========================================================================*/
void BT_PreOrderNoRec(pTreeT root)
{
    stack<treeT *> s;

    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            visit(root);
            s.push(root);
            root = root->left;
        }
        else
        {
            root = s.top();
            s.pop();
            root = root->right;
        }
    }
}



/*===========================================================================
* Function name:    BT_InOrder
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        中序遍历
* Return value:        void
* Author:            Liu Qi,  [12/30/2005]
===========================================================================*/
void BT_InOrder(pTreeT root)
{
    if (NULL != root)
    {
        BT_InOrder(root->left);
        visit(root);
        BT_InOrder(root->right);
    }
}


/*===========================================================================
* Function name:    BT_InOrderNoRec
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        中序遍历,非递归算法
* Return value:        void
* Author:            Liu Qi,  [1/1/2006]
===========================================================================*/
void BT_InOrderNoRec(pTreeT root)
{
    stack<treeT *> s;
    while ((NULL != root) || !s.empty())
    {
        if (NULL != root)
        {
            s.push(root);
            root = root->left;
        }
        else
        {
            root = s.top();
            visit(root);
            s.pop();
            root = root->right;
        }
    }
}



/*===========================================================================
* Function name:    BT_PostOrder
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        后序遍历
* Return value:        void
* Author:            Liu Qi,  [12/30/2005]
===========================================================================*/
void BT_PostOrder(pTreeT root)
{
    if (NULL != root)
    {
        BT_PostOrder(root->left);
        BT_PostOrder(root->right);
        visit(root);    
    }
}


/*===========================================================================
* Function name:    BT_PostOrderNoRec
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        后序遍历,非递归算法
* Return value:        void
* Author:            Liu Qi, //  [1/1/2006]
===========================================================================*/
void BT_PostOrderNoRec(pTreeT root)
{
//学习中,尚未明白
}


/*===========================================================================
* Function name:    BT_LevelOrder
* Parameter:        root:树根节点指针
* Precondition:        NULL != root
* Description:        层序遍历
* Return value:        void
* Author:            Liu Qi,  [1/1/2006]
===========================================================================*/
void BT_LevelOrder(pTreeT root)
{
    queue<treeT *> q;
    treeT *treePtr;

    assert( NULL != root ); 

    q.push(root);

    while (!q.empty())
    {
        treePtr = q.front();
        q.pop();
        visit(treePtr);

        if (NULL != treePtr->left)
        {
            q.push(treePtr->left);    
        }
        if (NULL != treePtr->right)
        {
            q.push(treePtr->right);
        }    
            
    }
}

#endif

//
//main.cpp
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "tree.h"

#define MAX_CNT 5
#define BASE  100

int main(int argc, char *argv[])
{
    int i;
    pTreeT root = NULL;
    
    srand( (unsigned)time( NULL ) ); 
    
    for (i=0; i<MAX_CNT; i++)
    {
        BT_Insert(rand() % BASE, &root);
    }

    //前序
    printf("PreOrder:\n");
    BT_PreOrder(root);
    printf("\n");

    printf("PreOrder no recursion:\n");
    BT_PreOrderNoRec(root);
    printf("\n");
    
    //中序
    printf("InOrder:\n");
    BT_InOrder(root);
    printf("\n");

    printf("InOrder no recursion:\n");
    BT_InOrderNoRec(root);
    printf("\n");

    //后序
    printf("PostOrder:\n");
    BT_PostOrder(root);
    printf("\n");

    //层序
    printf("LevelOrder:\n");
    BT_LevelOrder(root);
    printf("\n");
    
    return 0;
}

///

//AVL树
//AvlTree.h
#ifndef AVLTREE_H
#define AVLTREE_H
typedef int Element;
typedef struct Node{
	Element data;
	struct Node *left,*right;
	int Height;		//节点的高度
}AvlNode,*AvlTree,*Position;
void MakeEmpty(AvlTree &T); //清空平衡二叉搜索树
bool IsEmpty(AvlTree T); //判断树是否为空
bool Find(Element x,AvlTree T); //查找元素
Position FindMin(AvlTree T); //查找最小元素
Position FindMax(AvlTree T); //查找最大元素
AvlTree Insert(Element x,AvlTree &T); //插入元素
Position SingleRotateWithLeft(AvlTree k2); //向左单旋转
Position SingleRotateWithRight(AvlTree k2); //向右单旋转
Position DoubleRotateWithLeft(AvlTree k3); //双旋转
Position DoubleRotateWithRight(AvlTree k3); //双旋转
int MAX(int a,int b); 
int Height(Position p); //返回节点的高度
void InOrderTraverse(AvlTree T); //前序遍历树
#endif //AVLTREE_H

/
//method.cpp
#include "stdafx.h"
#include "AvlTree.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void MakeEmpty(AvlTree &T) //清空树
{
	if(T == NULL)
		return;
	MakeEmpty(T->left);
	MakeEmpty(T->right);
	free(T);
	T = NULL;
}
bool IsEmpty(AvlTree T) 
{
	return T == NULL ? true : false;
}
bool Find(Element x,AvlTree T)
{
	if(T == NULL)
		return false;
	else if(x < T->data)  //如果元素小于当前节点往左继续查找
		return Find(x,T->left);
	else if(x > T->data) //如果元素大于当前节点往右继续查找
		return Find(x,T->right);
	return true;
}
Position FindMin(AvlTree T) //查找最小值
{
	if(T == NULL)
		return NULL;
	else if(T->left == NULL) //节点的左子树为NULL,此节点就是最小元素的节点
		return T;
	else
		FindMin(T->left);
}
Position FindMax(AvlTree T)
{
	if(T == NULL)
		return NULL;
	else if(T->right == NULL) //节点的右子树为NULL,此节点就是最大元素的节点
		return T;
	else
		FindMax(T->right);
}
AvlTree Insert(Element x,AvlTree &T)
{
	if(T == NULL) //创建节点
	{
		T = (AvlTree)malloc(sizeof(AvlNode));
		if(T == NULL)
		{
			printf("内存分配失败,程序即将退出\n");
			exit(1);
		}
		T->data = x;
		T->Height = 0;
		T->left = T->right = NULL;
	}
	else if(x < T->data) //元素小于当前节点的元素,往左继续
	{
		T->left = Insert(x,T->left);
		if(Height(T->left) - Height(T->right) == 2) //如果左边节点的高度比右边节点的高度大2
			if(x < T->left->data)					//且元素x小于左边的元素,也就是x插入的方向是左边
				T = SingleRotateWithLeft(T);        //执行单旋转
			else
				T = DoubleRotateWithLeft(T);        //执行双旋转
	}
	else if(x > T->data)
	{
		T->right = Insert(x,T->right);
		if(Height(T->right) - Height(T->left) == 2)
			if(x > T->right->data)
				T = SingleRotateWithRight(T);
			else
				T = DoubleRotateWithRight(T);
	}
	T->Height = MAX(Height(T->left),Height(T->right)) + 1; //计算在节点插入后的各节点的高度
	return T;
}
Position SingleRotateWithLeft(AvlTree k2) //单旋转
{
	Position k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;
	k2->Height = MAX(Height(k2->left),Height(k2->right)) + 1;
	k1->Height = MAX(Height(k1->left),k2->Height) + 1;
	return k1;
}
Position SingleRotateWithRight(AvlTree k2)
{
	Position k1 = k2->right;
	k2->right = k1->left;
	k1->left = k2;
	k2->Height = MAX(Height(k2->left),Height(k2->right)) + 1;
	k1->Height = MAX(Height(k1->right),k2->Height);
	return k1;
}
Position DoubleRotateWithLeft(AvlTree k3) //双旋转
{
	k3->left = SingleRotateWithRight(k3->left);
	return SingleRotateWithLeft(k3);
}
Position DoubleRotateWithRight(AvlTree k3)
{
	k3->right = SingleRotateWithLeft(k3->right);
	return SingleRotateWithRight(k3);
}
int Height(Position p)
{
	return p == NULL ? -1 : p->Height;
}
int MAX(int a,int b)
{
	return a > b ? a : b;
}
void InOrderTraverse(AvlTree T) //前序遍历
{
	if(T)
	{
		printf("%d ",T->data);
		InOrderTraverse(T->left);
		InOrderTraverse(T->right);
	}
}

///

//main.cpp
#include "stdafx.h"
#include "LinkList.h"
#include <stdio.h>
int main()
{
	AvlTree T = NULL;
	int it;
	printf("请输入平衡二叉搜索树的数据\n");
	while(scanf("%d",&it) != EOF)
		Insert(it,T);
	printf("平衡二叉搜索树的数据为:\n");
	InOrderTraverse(T);
	printf("\n");
	printf("平衡二叉搜索树的最小元素为:%d\n",FindMin(T)->data);
	printf("平衡二叉搜索树的最大元素为:%d\n",FindMax(T)->data);
	printf("请输入要查找的内容\n");
	scanf("%d",&it);
	if(Find(it,T))
		printf("在平衡二叉搜索树中找到元素%d\n",it);
	else
		printf("在平衡二叉搜索树中未找到元素%d\n",it);
	MakeEmpty(T);
	if(IsEmpty(T))
		printf("平衡二叉搜索树为空\n");
	return 0;
}



// 二叉查找树
/* 二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,
则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值 */
//SearchTree.h
#ifndef SEARCHTREE_H
#define SEARCHTREE_H
typedef int Element;
typedef struct Node{
	Element data;
	struct Node* Left;
	struct Node* Right;
}SearchNode,*SearchTree,*Position;
void MakeEmpty(SearchTree T);
bool IsEmpty(SearchTree T);
bool Find(Element x,SearchTree T);
Position FindMin(SearchTree T);
Position FindMax(SearchTree T);
Position Insert(Element x,SearchTree &T);
Position Delete(Element x,SearchTree T);
void InOrderTraverse(SearchTree T);
#endif //SEARCHTREE_H

///
//method.cpp
#include "stdafx.h"
#include "SearchTree.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void MakeEmpty(SearchTree T) //清空二叉树
{
	if(T)
	{
		MakeEmpty(T->Left);
		MakeEmpty(T->Right);
		free(T);
	}
}
bool IsEmpty(SearchTree T) //判断二叉树是否为空
{
	if(T == NULL)
		return true;
	else
		return false;
}
bool Find(Element x,SearchTree T)  //查找x是否在树中存在
{
	if(T == NULL)
		return false;
	else if(x < T->data)
		return Find(x,T->Left);
	else if(x > T->data)
		return Find(x,T->Right);
	return true;
}
Position FindMin(SearchTree T) //查找最小数
{
	if(T == NULL)
		return NULL;
	else if(T->Left == NULL)
		return T;
	else 
		return FindMin(T->Left);
}
Position FindMax(SearchTree T) //查找最大数
{
	if(T == NULL)
		return NULL;
	while(T->Right != NULL)
		T = T->Right;
	return T;
}
Position Insert(Element x,SearchTree &T) //向二叉树中插入数据
{
	if(T == NULL)
	{
		T = (SearchTree)malloc(sizeof(SearchNode));
		if(!T)
		{
			printf("内存分配失败\n");
			exit(1);
		}
		T->data = x;
		T->Left = T->Right = NULL;
	}
	else
	{
		if(x < T->data)
			T->Left = Insert(x,T->Left);
		else if( x > T->data)
			T->Right = Insert(x,T->Right);
	}
	return T;
}
Position Delete(Element x,SearchTree T) //删除元素为x的节点
{
	SearchTree temp = NULL;
	SearchTree tp = NULL;
	if(T == NULL)
		return NULL;
	else if(x < T->data)
		T->Left = Delete(x,T->Left);
	else if(x > T->data)
		T->Right = Delete(x,T->Right);
	else if(T->Left && T->Right)
	{
		temp = FindMin(T->Right);
		T->data = temp->data;
		T->Right = Delete(temp->data,T->Right);
	}
	else
	{
		tp = T;
		if(T->Left == NULL)
			T = T->Right;
		if(T->Right == NULL)
			T = T->Left;
		free(tp);
	}
	return T;
}
void InOrderTraverse(SearchTree T) //前序遍历
{
	if(T)
	{
		printf("%d ",T->data);
		InOrderTraverse(T->Left);
		InOrderTraverse(T->Right);
	}
}

//
//main.cpp
#include "stdafx.h"
#include "SearchTree.h"
#include <stdio.h>
int main()
{
	SearchTree T = NULL;
	printf("please enter the element\n");
	int ch;
	while(scanf_s("%d",&ch) != EOF)
		Insert(ch,T);
	printf("集合中的内容为:\n");
	InOrderTraverse(T);
	printf("\n");
	printf("请输入要查找的数据\n");
	scanf_s("%d",&ch);
	if(Find(ch,T))
		printf("在集合中找到元素:%d\n",ch);
	else
		printf("在集合中没有找到元素:%d\n",ch);
	printf("集合中的最小元素为:%d\n",FindMin(T)->data);
	printf("集合中的最大元素为:%d\n",FindMax(T)->data);
	printf("请输入要删除的元素\n");
	int word;
	scanf_s("%d",&word);
	Delete(word,T);
	printf("删除后集合的元素为:\n");
	InOrderTraverse(T);
	return 0;
}

///








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值