/*
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;
}
///////////////////////////////////////////////////////////////////////////////////////////////
树集锦
最新推荐文章于 2020-04-16 16:53:04 发布