二叉树是数据结构中的重要内容之一,这里把自己做的一个练习题目写出来,方便回顾和交流。程序使用C语言实现,使用的IDE是Visual Studio 2010。
要求:
随机生成N个整数,N>20,建立二叉排序树;以树的形式输出建立好的二叉排序树删除第十个输入的数据,并以树的形式输出以后的二叉排序树
1、建立并生成二叉树
首先,定义一个二叉树的结构体:
typedef struct BiTNode
{
char data;
struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
BiTree T;
插入操作:
因为生成二叉树需要调用,插入函数就先写在这里。
void Insert(BiTree &BST,BiTNode *s)
{
BiTree t;
t = SearchBST(BST, s->data);
if (!t)
{
if (BST == NULL) BST = s;
else if (s->data<BST->data)
Insert(BST->lchild, s);
else
Insert(BST->rchild, s);
}
}
生成二叉排序树:
采用头插法,即从根部开始调用Insert()函数实现。
BiTree Create(
int n,
int *num)
{
int i;
BiTree s;
T = NULL;
for (i =
0; i<n; i++)
{
s = (BiTree)
malloc(
sizeof(BiTNode));
s->data = num[i];
s->lchild = NULL;
s->rchild = NULL;
Insert(T, s);
}
return T;
}
2、二叉树基本操作
查找操作:
BiTree SearchBST(BiTree BST,
int key)
{
BiTree s;
if (BST == NULL)
return NULL;
if (BST->data == key) s = BST;
else if (BST->data>key)
s = SearchBST(BST->lchild, key);
else
s = SearchBST(BST->rchild, key);
return s;
}
二叉树遍历:
void prorder(BiTree &BT)
{
if (BT != NULL)
{
printf(
"= ", BT->data);
prorder(BT->lchild);
prorder(BT->rchild);
}
}
删除二叉排序树中的节点:
int DeleteBT(BiTree *BT,
int key)
{
if(!*BT)
return 0;
else
{
if(key==(*BT)->data)
return Delete(BT);
else if(key<(*BT)->data)
return DeleteBT(&(*BT)->lchild,key);
else
return DeleteBT(&(*BT)->rchild,key);
}
}
int Delete(BiTree *p)
{
BiTree q,s;
if((*p)->rchild==NULL)
{
q=*p; *p=(*p)->lchild;
free(q);
}
else if((*p)->lchild==NULL)
{
q=*p; *p=(*p)->rchild;
free(q);
}
else
{
q=*p; s=(*p)->lchild;
while(s->rchild)
{
q=s; s=s->rchild;
}
(*p)->data=s->data;
if(q!=*p)
q->rchild=s->lchild;
else
q->lchild=s->lchild;
free(s);
}
return 1;
}
3、打印树形
void Paint(BiTree BT,
int x,
int y,
int g)
{
char c[
3];
int right =
0, left =
0;
if (BT)
{
setcolor(WHITE);
circle(x, y,
10);
Sleep(ms);
c[
0] = BT->data /
10 +
48;
c[
1] = BT->data %
10 +
48;
c[
2] =
'\0';
outtextxy(x-
7, y-
6, c);
Sleep(ms);
if (BT->lchild != NULL)
{
if (x>g) left = (x - g) /
2 + g;
if (x<g) left = (x - g) /
2 + x;
line(x -
3, y, left, y +
50);
Sleep(ms);
}
if (BT->rchild != NULL)
{
if(BT->lchild!=NULL)right=
2*x-left;
else
{
if(x<g) right =(x+g)/
2;
else right=x+
40;
}
line(x +
3, y, right, y +
50);
Sleep(ms);
}
Paint(BT->lchild, left, y +
50, x);
Paint(BT->rchild, right, y +
50, x);
}
}
void prorder(BiTree &BT)
{
if (BT!= NULL)
{
printf(
"= ", BT->data);
prorder(BT->lchild);
prorder(BT->rchild);
}
}
4、数组操作
为了存储和管理输入数据,增加两个与数组相关的函数
void Createnum(
int n,
int *num)
{
int vol, i, j, flag;
for (i =
0; i<n; i++)
{
vol = rand() %
100;
flag =
1;
for (j =
0; j < i; j++)
{
if (vol == num[j]){ flag =
0;
break; }
}
if (flag) num[i] = vol;
else --i;
}
}
void show_num(
int n,
int *num)
{
int i;
for (i =
0; i<n; i++)
{
printf(
"= ", num[i]);
if ((i +
1) %
5 ==
0)
printf(
"\n");
}
}
5、主函数
void main()
{
int x, y, g;
int i, a, b, c;
int num[
100];
int gdriver, gmode;
x =
320, y =
30, g =
0;
gdriver = DETECT;
while (
1)
{
printf(
"随机生成多少数? ");
scanf_s(
"%d", &b);
srand(time(NULL));
Createnum(b, num);
printf(
"所有随机数为:\n");
show_num(b, num);
printf(
"\n按任意键开始生成二叉排序树 ");
getchar();
T = Create(b, num);
if (T != NULL)
printf(
"生成成功!");
else
{
printf(
"生成失败!");
break;
}
printf(
"\n前序遍历结果:(ENTER)");
getchar();
prorder(T);
printf(
"\n按任意键开始打印树形");
getchar();
initgraph(
800,
550,
0);
setbkcolor(
0);
cleardevice();
Paint(T, x, y, g);
getchar();
closegraph();
printf(
"请输入要删除的数的序号: ");
scanf_s(
"%d", &a);
DeleteBT(&T, num[a -
1]);
initgraph(
800,
550,
0);
setbkcolor(
0);
cleardevice();
Paint(T, x, y, g);
getchar();
getchar();
closegraph();
printf(
"前序遍历结果:(ENTER)");
getchar();
prorder(T);
printf(
"是否继续?");
scanf_s(
"%d", &c);
if (!c)
break;
system(
"cls");
}
system(
"pause");
}
6、运行结果
生成二叉树并打印出树的形状:
删除节点,输入序号是10,也就是上面输出数组的第十个元素,注意,这里的标号是从1开始的,所以删除了值为64的节点。
输出新的前序遍历结果,可以观察到与刚开始结果的变化,最后键入1重新开始,键入0结束。
注意事项
由于画图操作中用到一些以前Dos界面上的函数,在VS2010等新版的环境中不支持(虽然我试了老版本的VC++等也不支持,但百度上是么说的)。这里需要安装一个EasyX的插件,这里附上下载链接:http://download.csdn.net/detail/qq_28292827/9686820
转载请注明原文地址: https://ju.6miu.com/read-679845.html