算法与数据结构之二叉树

#include<stdio.h>
#include<windows.h>
#include<malloc.h>
#define maxsize 20
typedef int elemtype;
typedef struct node //定义
{
elemtype data;
struct node *lchild;
struct node *rchild;
}btnode;
void createbtnode(btnode *&b,char *str) //创建二叉树
{
btnode *st[maxsize],*p=NULL;
int top=-1,k,j=0;
char ch;
b=NULL;
ch=str[j];
while(ch!='\0')
{
switch(ch)
{
case '(':top++;st[top]=p;k=1;break;
case ')':top--;break;
case ',':k=2;break;
default:p=(btnode *)malloc(sizeof(btnode));
p->data=ch;p->lchild=p->rchild=NULL;
if(b==NULL)
b=p;
else
{
switch(k)
{
case 1:st[top]->lchild=p;break;
case 2:st[top]->rchild=p;break;
default:printf("错误!\n");
}
}
}
j++;
ch=str[j];
}
}
btnode *findnode(btnode *b,elemtype x) //查找节点
{
btnode *p;
if(b==NULL)
return NULL;
else if(b->data==x)
return b;
else
{
p=findnode(b->lchild,x);
if(p!=NULL)
return p;
else 
return findnode(b->rchild,x);
}
}
btnode *lchildnode(btnode *p) //找左孩子
{
return p->lchild;
}
btnode *rchildnode(btnode *p) //找右孩子
{
return p->rchild;
}
int btnodeheight(btnode *b) //求高度
{
int lchildh,rchildh;
if(b==NULL)
return 0;
else
{
lchildh=btnodeheight(b->lchild);
rchildh=btnodeheight(b->rchild);
return(lchildh>rchildh)?(lchildh+1):(rchildh+1);
}
}
void dispbtnode(btnode *b) //输出二叉树
{
if(b!=NULL)
{
printf("%c",b->data);
if(b->lchild!=NULL||b->rchild!=NULL)
{
printf("(");
dispbtnode(b->lchild);
if(b->rchild!=NULL)
printf(",");
dispbtnode(b->rchild);
printf(")");
}
}
}

int Nodes(btnode *b)//求二叉树b的节点个数
{
int num1,num2;
if (b==NULL) 
return 0;
else if (b->lchild==NULL && b->rchild==NULL) 
return 1;
else
{
num1=Nodes(b->lchild);
num2=Nodes(b->rchild);
return (num1+num2+1);
}
}
int LeafNodes(btnode *b)//求二叉树b的叶子节点个数
{
int num1,num2;
if (b==NULL) 
return 0;
else if (b->lchild==NULL && b->rchild==NULL) 
return 1;
else
{
num1=LeafNodes(b->lchild);
num2=LeafNodes(b->rchild);
return (num1+num2);
}
}
void TravLevel(btnode *b) //层次遍历
{
btnode *Qu[maxsize];//定义循环队列
int front,rear;//定义队首和队尾指针
front=rear=0;//置队列为空队列
if (b!=NULL) 
printf("%c ",b->data);
rear++;//节点指针进入队列
Qu[rear]=b;
while (rear!=front)//队列不为空
{
front=(front+1)%maxsize;
b=Qu[front];//队头出队列
if (b->lchild!=NULL)//输出左孩子,并入队列
{
printf("%c ",b->lchild->data);
rear=(rear+1)%maxsize;
Qu[rear]=b->lchild;
}
if (b->rchild!=NULL)//输出右孩子,并入队列
{
printf("%c ",b->rchild->data);
rear=(rear+1)%maxsize;
Qu[rear]=b->rchild;
}

printf("\n");
}
void PreOrder(btnode *b) //先序遍历的递归算法
{
if (b!=NULL) 
{
printf("%c ",b->data);//访问根节点
PreOrder(b->lchild);//递归访问左子树
PreOrder(b->rchild);//递归访问右子树
}
}
void PreOrder1(btnode *b) //先序遍历的非递归算法
{
btnode *St[maxsize],*p;
int top=-1;
if (b!=NULL) 
{
top++;//根节点入栈
St[top]=b;
while (top>-1)//栈不为空时循环
{
p=St[top];//退栈并访问该节点
top--;
printf("%c ",p->data);
if (p->rchild!=NULL)//右孩子入栈
{
top++;
St[top]=p->rchild;
}
if (p->lchild!=NULL)//左孩子入栈
{
top++;
St[top]=p->lchild;
}
}
printf("\n");
}
}
void InOrder(btnode *b) //中序遍历的递归算法
{
if (b!=NULL) 
{
InOrder(b->lchild);//递归访问左子树
printf("%c ",b->data);//访问根节点
InOrder(b->rchild);//递归访问右子树
}
}
void InOrder1(btnode *b) //中序遍历的非递归算法
{
btnode *St[maxsize],*p;
int top=-1;
if (b!=NULL)
{
p=b;
while (top>-1 || p!=NULL)
{
while (p!=NULL)
{
top++;
St[top]=p;
p=p->lchild;
}
if (top>-1)
{
p=St[top];
top--;
printf("%c ",p->data);
p=p->rchild;
}
}
printf("\n");
}
}
void PostOrder(btnode *b) //后序遍历的递归算法
{
if (b!=NULL) 
{
PostOrder(b->lchild);//递归访问左子树
PostOrder(b->rchild);//递归访问右子树
printf("%c ",b->data);//访问根节点
}
}
void PostOrder1(btnode *b) //后续遍历的非递归算法
{
btnode *St[maxsize];
btnode *p;
int flag,top=-1;//栈指针置初值
if (b!=NULL)
{
do
{
while (b!=NULL)//将t的所有左节点入栈
{
top++;
St[top]=b;
b=b->lchild;
}
p=NULL;//p指向当前节点的前一个已访问的节点
flag=1;
while (top!=-1 && flag)
{
b=St[top];//取出当前的栈顶元素
if (b->rchild==p)//右子树不存在或已被访问,访问之
{
printf("%c ",b->data);//访问*b节点
top--;
p=b;//p指向则被访问的节点

}

else
{
b=b->rchild;//t指向右子树
flag=0;
}
}
} while (top!=-1);
printf("\n");

}
void DestroyBTNode(btnode *&b) //销毁二叉树
{
if (b!=NULL)
{
DestroyBTNode(b->lchild);
DestroyBTNode(b->rchild);
free(b);
}

}

void main()
{
int hight,n;
char ch,str[100];
btnode *b,*p,*p1,*p2;
printf(" *****************欢迎使用二叉树基本运算系统*******************\n");
printf("请输入一个广义表\n(例如:A(B(D(,I),E(J,K(H))),C(F)))\n");
gets(str);
createbtnode(b,str);
while(1)
{
printf("请选择:\n");
printf(" 1 求树的高度\n");
printf(" 2 求节点的孩子\n");
printf(" 3 输出二叉树\n");
printf(" 4 求二叉树的节点数\n");
printf(" 5 求二叉树的叶子节点数\n");
printf(" 6 层次遍历序列\n");
printf(" 7 先序遍历序列\n");
printf(" 8 中序遍历序列\n");
printf(" 9 后续遍历序列\n");
printf(" 10 释放二叉树并退出\n");
printf(" 11 退出\n");
scanf("%d",&n);
switch(n)
{
case 1:printf("树的高度为:%d\n",btnodeheight(b));break;
case 2:getchar();printf("请输入需查找的节点:");
scanf("%c",&ch);
p=findnode(b,ch);
p1=lchildnode(p);
p2=rchildnode(p);
if(p1!=NULL)
printf("左孩子为:%c\n",p1->data);
else
printf("没有左孩子\n");
if(p2!=NULL)
printf("右孩子为:%c\n",p2->data);
else
printf("没有右孩子\n");
break;
case 3:dispbtnode(b);
printf("\n");
break;
case 4:printf("二叉树的节点个数为:%d个\n",Nodes(b));break;
case 5:printf("二叉树的叶子节点数为%d个\n",LeafNodes(b));break;
case 6:printf("层次遍历序列:");TravLevel(b);break;
case 7:printf("先序遍历序列:\n");
printf(" 递归算法:");PreOrder(b);printf("\n");
printf(" 非递归算法:");PreOrder1(b);break;
case 8:printf("中序遍历序列:\n");
printf(" 递归算法:");InOrder(b);printf("\n");
printf(" 非递归算法:");InOrder1(b);break;
case 9:printf("后序遍历序列:\n");
printf(" 递归算法:");PostOrder(b);printf("\n");
printf(" 非递归算法:");PostOrder1(b);break;
case 10:DestroyBTNode(b);printf("二叉树已销毁!\n");exit(0);break;
case 11:exit(0);
default:printf("输入错误\n");
}
}
}

时间: 2024-11-05 14:41:10

算法与数据结构之二叉树的相关文章

一步一步写算法(之排序二叉树线索化)

原文:一步一步写算法(之排序二叉树线索化) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们谈到了排序二叉树,还没有熟悉的同学可以看一下这个,二叉树基本操作.二叉树插入.二叉树删除1.删除2.删除3.但是排序二叉树也不是没有缺点,比如说,如果我们想在排序二叉树中删除一段数据的节点怎么办呢?按照现在的结构,我们只能一个一个数据查找验证,首先看看在不在排序二叉树中,如果在那么删除:如果没有这个数据,那么继续查找.那么有没有方法

021_《Delphi算法与数据结构》

<Delphi算法与数据结构> Delphi 教程 系列书籍 (021) <Delphi算法与数据结构> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Pdf 附书源码     原书名: The Tomes of Delphi Algorithms and Data Structures 原出版社: Wordware Publishing 作者: [美]Julian Bucknall 译者: 林琪 朱涛江 丛书名: Delphi技术系列 出版社:中国电力

一步一步写算法(之排序二叉树)

原文:一步一步写算法(之排序二叉树) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们讲过双向链表的数据结构.每一个循环节点有两个指针,一个指向前面一个节点,一个指向后继节点,这样所有的节点像一颗颗珍珠一样被一根线穿在了一起.然而今天我们讨论的数据结构却有一点不同,它有三个节点.它是这样定义的: typedef struct _TREE_NODE { int data; struct _TREE_NODE* parent;

一步一步写算法(之排序二叉树的保存和加载)

原文:一步一步写算法(之排序二叉树的保存和加载)[ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     排序二叉树是我们开发中经常使用到的一种数据结构,它具有较好的插入.删除.查找特性.但是由于二叉树的指针较多,所以相比较其他的数据结构而言,二叉树来得比较麻烦些.但是也不是没有办法,下面介绍一下我个人常用的方法.     我们知道,如果一个二叉树是一个满树的话,那么二叉树的节点应该是按照1.2.3.4依次排开的.但是现实情况是这样的,由于

纸上谈兵: 算法与数据结构

算法和数据结构是计算机科学的核心内容.作为程序员,编程是我们的实战项目.然而,写出程序还不够.一个程序在应对一些大型而复杂的情况时,会耗费大量的时间.我们可以很容易写出一个从文件中找到一个词的程序,比如逐词扫描,看是否相符.但如果我们的文件有几十TB,而且要从文件中找到上百个词,逐个扫描的办法就几乎不可行.我们需要优化程序,以便我们的程序可以应对复杂问题.算法研究解决问题的方法,而数据结构则是设计一种更好的组织数据和使用数据的方式.两者有很强的相互依赖关系,所以往往放在一起讨论.   我将这一系

浅谈算法和数据结构 十一 哈希表

在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度. 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table) 什么是哈希表 哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 哈希的思路很简单

浅谈算法和数据结构 三 合并排序

合并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序.合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行合并. 合并排序最大的优点是它的时间复杂度为O(nlgn),这个是我们之前的选择排序和插入排序所达不到的.他还是一种稳定性排序,也就是相等的元素在序列中的相对位置在排序前后不会发生变化.他的唯一缺点是,需要利用额外的N的空间来进行排序. 一 原理 合并排序依赖于合并操作,即将两个已经排序的序列合并成一个序列,

浅谈算法和数据结构 二 基本排序算法

本篇开始学习排序算法.排序与我们日常生活中息息相关,比如,我们要从电话簿中找到某个联系人首先会按照姓氏排序.买火车票会按照出发时间或者时长排序.买东西会按照销量或者好评度排序.查找文件会按照修改时间排序等等.在计算机程序设计中,排序和查找也是最基本的算法,很多其他的算法都是以排序算法为基础,在一般的数据处理或分析中,通常第一步就是进行排序,比如说二分查找,首先要对数据进行排序.在Donald Knuth 的计算机程序设计的艺术这四卷书中,有一卷是专门介绍排序和查找的. 排序的算法有很多,在维基百

浅谈算法和数据结构 一 栈和队列

最近晚上在家里看Algorithems,4th Edition,我买的英文版,觉得这本书写的比较浅显易懂,而且"图码并茂",趁着这次机会打算好好学习做做笔记,这样也会印象深刻,这也是写这一系列文章的原因.另外普林斯顿大学在Coursera 上也有这本书同步的公开课,还有另外一门算法分析课,这门课程的作者也是这本书的作者,两门课都挺不错的. 计算机程序离不开算法和数据结构,本文简单介绍栈(Stack)和队列(Queue)的实现,.NET中与之相关的数据结构,典型应用等,希望能加深自己对这