实践二:
操作系统:中文WindowsXp
开发工具:VC7
语言:C
编写时间:20051011
完成时间:20051018
功能:对二叉树建立、添加、删除、遍历及销毁。
操作系统:中文WindowsXp
开发工具:VC7
语言:C
编写时间:20051011
完成时间:20051018
功能:对二叉树建立、添加、删除、遍历及销毁。
- 二叉树实现原码下载地址
源码如下:
main.c#include < stdio.h >
#include < stdlib.h >
#include " BianaryTree.h "
#include " OperJm.h "
void main ( void )
... {
BiTree T = NULL; //二叉树根结点。
if ( BiTreeEmpty (T) )
...{
T = InitBiTree (T);
if (T != NULL)
...{
do
...{
system ("cls");
}while ( OperJm (&T) );
}
}
}
OperJm.h/**/ /*
文件名称:OperJm.h
文件内容:二叉树操作相关的人机界面函数声明。
创建日期:20051012
创建人:高玉涵
创建地点:郑州
*/
#define NUM_MAX 50 //数据最大数。
Status OperJm (BiTree *T); //操作结果:显示一个操作菜单。返回用户输入的值。
Status AddData (BiTree T); //操作结果:添加数据。成功返回添加的结点数。
void PrintData (BiTree T); //操作结果:打印结点数据域中的值。
void InputCheck (TElemType *check); //
/**/ /*
文件名称:OperJm.c
文件内容:二叉树操作相关的人机界面函数定义。
创建日期:20051012
创建人:高玉涵
创建地点:郑州
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sjjg.h"
#include "BianaryTree.h"
#include "OperJm.h"
int g_nCount = 0; //全局变量,存放递归的执行次数。
Status OperJm (BiTree * T)
... {
/**//*
操作结果:显示一个操作菜单。返回用户输入的值。
*/
int value; /**//* 选项值 */
int pos; //结点位置信息。
TElemType check; //查找值。
BiTree BTreturn = NULL; //返回结点的值。
BiTree bt = NULL;
printf (" -------二叉树二叉链表结构实现----- ");
printf (" | 1.添加数据。 | ");
printf (" | 3.删除一项记录。 | ");
printf (" | 4.先序遍历结点。 | ");
printf (" | 5.中序遍历结点。 | ");
printf (" | 6.后序遍历结点。 | ");
printf (" | 7.查找数据。 | ");
printf (" | 0.退出。 | ");
printf (" --------------------------------- ");
printf (" 请选择:");
fflush(stdin); /**//* 清除键盘缓冲区。(在ANIS C中此函数对输入流操作,
其结果是未定义的,一般是起到清空缓冲区的作用。
这根据所使用的编辑器有关,所以特别声明。
*/
scanf ("%d", &value); /**//* 获取输入的值 */
switch( value )
...{
case 1:
printf ( "成功的添加了%d个数据。", AddData (*T) );
system ("pause");
break;
case 3:
InputCheck (&check); //校验用户输入的值。
if ( check != ' ' || check != EOF || check != '
/**/ /*
文件名称:sjjg.h
文件内容:自己定义的一些新的数据类型(参考<<数据结构>>严尉敏)。
创建日期:20051011
创建人:高玉涵
*/
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1 //不可实行的。
#define OVERFLOW -2 //溢值。
typedef int Status; //是函数的类型,其值是函数结果状态代码。
/**/ /*
说明:
i 为循环计数器。
iCout 累加计数器(多用于返回函数的执行结果值)。
*/
/**/ /*
文件名称:BianaryTree.h
文件内容:二叉树操作相关的函数声明。
创建日期:20051011
创建人:高玉涵
创建地点:郑州
*/
#include " sjjg.h "
typedef char TElemType; // 树中数据域的类型。
typedef struct BiTNode // 二叉树的二叉链表存储表示。
... {
TElemType data;
struct BiTNode *lchild; //左子树。
struct BiTNode *rchild; //右子树。
} BiTNode;
typedef BiTNode * BiTree;
// 下面是对二叉树操作相关的函数。
BiTree InitBiTree (BiTree T); // 操作结果:构造空二叉树T。成功返回地址,否则返回NULL。
Status BiTreeEmpty ( const BiTree T); // 操作结果:若T为空二叉树,则返回TRUE,否则FALSE。
Status CreateBiTree (BiTree T, char definition); // 操作结果:按definition构造二叉树。成功返回TRUE,否则FALSE。
void EmpressPreface ( const BiTree T, void ( * opter) (BiTree T)); // 操作结果:后序遍历二叉树T。对每个结点调用函数opter。
void DestroyBiTree (BiTree T); // 操作结果:销毁二叉树。
void FirstPreface ( const BiTree T, void ( * opter) (BiTree T)); // 操作结果:先序遍历T,对每个结点调用函数opter。
void MediumPreface ( const BiTree T, void ( * opter) (BiTree T)); // 操作结果:中序遍历T,对每个结点调用函数opter。
BiTree SearchBiTree ( const BiTree T, TElemType e, int * position); // 操作结果:二叉树二分查找e指定的值。成功返回地址及所属结点位置信息,否则NULL。
Status DeleteNode (BiTree T, BiTree * parent, TElemType e, int * position, BiTree ( * opter) ( const BiTree T, TElemType e, int * position) );
BiTree Parent ( const BiTree T, TElemType e); // 操作结果:若e是T的非根结点,则返回它的双亲,否则返回NULL。
/**/ /*
文件名称:BianaryTree.c
文件内容:二叉树操作相关的函数定义。
创建日期:20051011
完成日期:20051018
创建人:高玉涵
创建地点:郑州
*/
#include < stdio.h >
#include < stdlib.h >
#include " BianaryTree.h "
BiTree InitBiTree (BiTree T)
... {
/**//*
操作结果:构造空二叉树T。成功返回地址,否则返回NULL。
*/
if (T == NULL) //二叉树为空树时。
...{
T = (BiTree) malloc (sizeof(BiTNode));
if (T == NULL) return NULL; //存储空间分配失败。
T->data = NULL;
T->lchild = NULL;
T->rchild = NULL;
return T;
}
return NULL;
}
Status BiTreeEmpty ( const BiTree T)
... {
/**//*
初始条件:二叉树T存在。
操作结果:若T为空二叉树,则返回TRUE,否则FALSE。
*/
if (T == NULL) return TRUE; //二叉树为空。
return ERROR;
}
Status CreateBiTree (BiTree T, TElemType definition)
... {
/**//*
初始条件:definition给出二叉树T的定义。
操作结果:按definition构造二叉树。成功返回TRUE,否则FALSE。
*/
BiTree NewNode; //新结点指针。
BiTree CurrentNode; //当前结点指针。
BiTree ParentNode; //父结点指针。
if ( (T->data == NULL) )//当二叉树只有一个根结点且数据域未赋值。
...{
T->data = definition;
return TRUE;
}
//创建新结点。
NewNode = (BiTree) malloc (sizeof(BiTNode));
if (NewNode == NULL) return ERROR; //存储空间分配失败。
NewNode->data = definition; //将definition中的数据复制到新结点中。
NewNode->lchild = NULL;
NewNode->rchild = NULL;
CurrentNode = T;
while (CurrentNode != NULL)
...{
ParentNode = CurrentNode; //存储父结点指针。
if (CurrentNode->data > NewNode->data)
...{
CurrentNode = CurrentNode->lchild;
}
else
...{
CurrentNode = CurrentNode->rchild;
}
}
if (ParentNode->data > NewNode->data )
...{
ParentNode->lchild = NewNode;
}
else
...{
ParentNode->rchild = NewNode;
}
return TRUE;
}
void DestroyBiTree (BiTree T)
... {
/**//*
初始条件:二叉树T存在。
操作结果:销毁二叉树。
*/
free (T); //释放占用的资源。
T = NULL; //赋NULL值。
}
void EmpressPreface ( const BiTree T, void ( * opter) (BiTree T))
... {
/**//*
初始条件:二叉树T存在。
操作结果:后序遍历二叉树T。对每个结点调用函数opter。
*/
extern int g_nCount; //访问外部变量。
if (T != NULL)
...{
g_nCount++; //计数。
EmpressPreface (T->lchild, opter); //处理左子树。
EmpressPreface (T->rchild, opter); //处理右子树。
opter (T);
}
}
void FirstPreface ( const BiTree T, void ( * opter) (BiTree T))
... {
/**//*
初始条件:二叉树T存在。
操作结果:先序遍历T,对每个结点调用函数opter。
*/
extern int g_nCount; //访问外部变量。
if (T != NULL)
...{
g_nCount++; //计数。
opter (T);
FirstPreface (T->lchild, opter);
FirstPreface (T->rchild, opter);
}
}
void MediumPreface ( const BiTree T, void ( * opter) (BiTree T))
... {
/**//*
初始条件:二叉树T存在。
操作结果:中序遍历T,对每个结点调用函数opter。
*/
extern int g_nCount; //访问外部变量。
if (T != NULL)
...{
g_nCount++; //计数。
MediumPreface (T->lchild, opter);
opter (T);
MediumPreface (T->rchild, opter);
}
}
BiTree SearchBiTree ( const BiTree T, TElemType e, int * position)
... {
/**//*
初始条件:二叉树T存在。
操作结果:二叉树二分查找e指定的值。成功返回地址及所属结点位置信息,否则NULL。
*/
BiTree point; //当前结点。
point = T;
*position = 0; //初始位置信息。0=根,-1=左子树,1=右子树。
while (point != NULL)
...{
if (point->data == e)
...{
return point;
}
else
...{
if (point->data > e)
...{
point = point->lchild;
*position = -1; //左子树。
}
else
...{
point = point->rchild;
*position = 1; //右子树。
}
}
}
return NULL;
}
Status DeleteNode (BiTree T, BiTree * RootNode, TElemType e, int * position,
BiTree ( * opter) ( const BiTree T, TElemType e, int * position) )
... {
/**//*
初始条件:二叉树T存在,e指向中T中某个结点,pos为-1,0,1。
操作结果:根据pos为-1,0,1,删除T中p所指结点。成功返回TRUE,否则FALSE。
*/
BiTree parent = NULL; //父结点。
BiTree point = NULL; //欲删除结点。
BiTree child = NULL; //子结点指针。
point = opter (T, e, position); //寻找欲删除结点的指针。
parent = Parent (T, e); //寻找欲删除结点的父结点(双亲)。
if (point == NULL ) //该结点不在二叉树中。
...{
return FALSE;
}
else
...{
//没有左子树也没有右子树。
if (point->lchild == NULL && point->rchild == NULL)
...{
switch ( *position ) //判断删除位置。
...{
case -1:
(*RootNode)->lchild = NULL; //将父结点的左指针指向NULL。
free (point);point = NULL;break; //释放资源。
case 1:
(*RootNode)->rchild = NULL;//将父结点的右指针指向NULL。
free (point);point = NULL;break; //释放资源。
case 0:
*RootNode = NULL; //将父结点指向NULL。
free (point);point = NULL;break; //释放资源。
}
return TRUE;
}
//没有左子树。
if (point->lchild == NULL && point->rchild != NULL)
...{
if (parent == NULL) parent = point;//说明parent与point都指的是root结点。
if (parent != point)
...{
parent->rchild = point->rchild; //将父结点右指针->结点右指针。
free (point);point = NULL; //释放资源。
}
else
...{
*RootNode = parent->rchild; //将右指针地址赋给父结点。
//parent = parent->rchild;
free (point);point = NULL; //释放资源。
}
return TRUE;
}
//没有右子树。
else if (point->rchild == NULL && point->lchild != NULL)
...{
if (parent == NULL) parent = point;//说明parent与point都指的是root结点。
if (parent != point)
...{
parent->lchild = point->lchild; //将父结点右指针->结点右指针。
free (point);point = NULL; //释放资源。
}
else
...{
*RootNode = parent->lchild; //将右指针地址赋给父结点。
//parent = parent->lchild; //将右指针地址赋给父结点。
free (point);point = NULL; //释放资源。
}
return TRUE;
}
//有左子树也有右子树。
else if (point->lchild != NULL && point->rchild != NULL)
...{
parent = point; //将父结点指向目前结点。
child = point->lchild; //向左走设置子结点。
while (child->rchild != NULL)//找左子树最右边的叶子节点。
...{
parent = child; //保留父结点指针。
child = child->rchild; //往右子树前进。
}
point->data = child->data; //将原结点设置成叶结点数据值。
if (parent->lchild == child)
...{
parent->lchild = child->lchild;
}
else
...{
parent->rchild = child->rchild;
}
free (child);child = NULL; //释放资源。
}
return FALSE;
}
}
BiTree Parent ( const BiTree T, TElemType e)
... {
/**//*
初始条件:二叉树T存在,e是T中某个结点。
操作结果:若e是T的非根结点,则返回它的双亲,否则返回NULL。
*/
BiTree point; //当前结点。
BiTree parent; //父结点(双亲结点)。
parent = T;
point = T;
while (point != NULL)
...{
if (point->data == e)
...{
return (T == point? NULL: parent);
}
else
...{
if (point->data > e)
...{
parent = point; //保留父结点。
point = point->lchild;
}
else
...{
parent = point;
point = point->rchild;
}
}
}
return NULL;
}
未完待续......