所用编译器;Devc++(有些编译器编译不了,建议使用Devc++)
所用语言:C语言
逻辑结构:非线性结构
存储结构:链式存储结构
写在前面:学习二叉树之前也有找过一些学习资料,数据结构的书,博客文章,但是都大概讲述的是方法,并没有给出完整的且比较适合初学者的,今天刚刚学习了二叉树,趁着这股热劲,把代码敲了,个人认为这些基本操作 ,熟悉了链表是如何操作,建立的,还是比较容易掌握的。下面是代码,罗列了一些基本操作以及在main方法中用switch-case菜单的模式来展现:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <windows.h>
int flag = 0;
typedef struct bitnode{
int data;
struct bitnode *lchild,*rchild;
}BiTNode,*BiTree;
//建立一个空的带头结点的二叉树
BiTree Initiate()
{
BiTNode *bt;//制造一个空结点
bt = (BiTNode*)malloc(sizeof(BiTNode));
if(bt==NULL) return NULL;
bt->lchild = NULL;
bt->rchild = NULL;
return bt;//返回
}
//生成一棵以x为根节点的数据域值以lbt和rbt为左右子树的二叉树
BiTree Create(int x,BiTree lbt,BiTree rbt)
{
BiTree p;//创造一个数据结点
if((p=(BiTNode*)malloc(sizeof(BiTNode)))==NULL)
return NULL;
p->data = x;
p->lchild = lbt;
p->rchild = rbt;
return p;
}
//将数据域信息为x的结点插入到二叉树bt中作为结点parent的右孩子结点。
//如果结点parent原来有左孩子结点,则将结点parent原来的左孩子结点作为结点x的左孩子结点
BiTree InsertL(BiTree bt,int x,BiTree parent)
{
BiTree p;
if(parent==NULL)
{
printf("为空树,无法进行插入工作");
return NULL;
}
if((p=(BiTNode*)malloc(sizeof(BiTNode)))==NULL) return NULL;
p->data = x;
p->lchild = NULL;
p->rchild = NULL;
if(parent->lchild==NULL)
parent->lchild = p;
else
{
p->lchild = parent->lchild;
parent->lchild = p;
}
return bt;
}
//将数据域信息为x的结点插入到二叉树bt中作为结点parent的右孩子结点。
//如果结点parent原来有右孩子结点,则将结点parent原来的右孩子结点作为结点x的右孩子结点
BiTree InsertR(BiTree bt,int x,BiTree parent)
{
BiTree p;
if(parent==NULL)
{
printf("为空树,无法进行插入工作");
return NULL;
}
if((p=(BiTNode*)malloc(sizeof(BiTNode)))==NULL) return NULL;
p->data=x;
p->lchild=NULL;
p->rchild=NULL;
if(parent->rchild==NULL)
parent->rchild = p;
else
{
p->rchild = parent->rchild;
parent->rchild = p;
}
return bt;
}
//在二叉树中删除左子树,当parent或者parent的左子树为空时删除失败。
//删除成功返回根结点指针,删除失败返回空指针。
BiTree DelectL(BiTree bt,BiTree parent)
{
BiTree p;
if(parent==NULL||parent->lchild==NULL)
{
printf("parent为空或者左子树为空!无法删除!");
return NULL;
}
p = parent->lchild;
parent->lchild = NULL;
free(p);
printf("删除成功!\n");
return bt;
}
//在二叉树中删除右子树,当parent或者parent的右子树为空时删除失败。
//删除成功返回根结点指针,删除失败返回空指针。
BiTree DelectR(BiTree bt,BiTree parent)
{
BiTree p;
if(parent==NULL||parent->rchild==NULL)
{
printf("parent为空或者右子树为空!无法删除!");
return NULL;
}
p = parent->rchild;
parent->rchild = NULL;
free(p);
printf("删除成功!\n");
return bt;
}
//先序遍历
void PreOrder(BiTree bt)
{
if(bt==NULL) return;
printf("%d ",bt->data);
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
//中序遍历
void InOrder(BiTree bt)
{
if(bt==NULL) return;
InOrder(bt->lchild);
printf("%d ",bt->data);
InOrder(bt->rchild);
}
//后序遍历
void PostOrder(BiTree bt)
{
if(bt==NULL) return;
PostOrder(bt->lchild);
PostOrder(bt->rchild);
printf("%d ",bt->data);
};
void list()
{
printf("1.初始化\t\t");
printf("2.创建一棵二叉树\n");
printf("3.左子树插入\t\t");
printf("4.右子树插入\n");
printf("5.删除左子树\t\t");
printf("6.删除右子树\n");
printf("7.先序遍历\t\t");
printf("8.中序遍历\n");
printf("9.后序遍历\t\t");
printf("10.退出\n\n");
}
int main()
{
int c;
int x;
while(true)
{
list();
printf("请选择功能:");
scanf("%d",&c);
if(c>=10) break;
switch(c)
{
case 1:
BiTree bt,p;
bt=Initiate();
if(bt==NULL)
printf("初始化失败!\n");
else
printf("初始化成功(带头结点)!\n");
break;
case 2:
printf("请输入根结点的数据:");
scanf("%d",&x);
p=Create(x,NULL,NULL);
if(p!=NULL)
{
bt->lchild = p;
printf("创建成功!\n",p->data);
printf("提示:3秒后即将进行清屏操作");
Sleep(3000);
system("cls");
}else{
printf("创建失败!\n");
}
break;
case 3:
printf("请输入要插入的数据:");
scanf("%d",&x);
p=InsertL(bt,x,bt->lchild);
if(p!=NULL){
printf("插入成功!\n");
printf("提示:3秒后即将进行清屏操作");
Sleep(3000);
system("cls");
}
else
printf("插入失败!\n");
break;
case 4:
printf("请输入要插入的数据:");
scanf("%d",&x);
p=InsertR(bt,x,bt->lchild);
if(p!=NULL){
printf("插入成功!\n");
printf("提示:3秒后即将进行清屏操作");
Sleep(3000);
system("cls");
}
else
printf("插入失败!\n");
break;
case 5:
DelectL(bt,bt->lchild);
break;
case 6:
DelectR(bt,bt->lchild);
break;
case 7:
PreOrder(bt->lchild);
break;
case 8:
InOrder(bt->lchild);
break;
case 9:
PostOrder(bt->lchild);
break;
default:
//结束程序
break;
}
printf("\n\n");
}
}