数据结构二叉树应用课程设计含源代码实现

合集下载

数据结构二叉树程序代码

数据结构二叉树程序代码

数据结构⼆叉树程序代码#include#include#define STACK_INIT_SIZE 100#define STACKINCREMENT 10#define MAX_TREE_SIZE 100//⼆叉树的最⼤结点#define TRUE 1#define FALSE 0#define OVERFLOW -2#define telemtype char#define selemtype chartypedef telemtype sqbitree[MAX_TREE_SIZE];//0号单元储存根结点sqbitree bt;typedef struct bitnode{telemtype data;struct bitnode *lchild,*rchild;}bitnode,*bitree;bitree T;typedef struct{bitree *base;bitree *top;int stacksize;}sqstack;sqstack s;void menu();//菜单void initstack(sqstack &s);//初始化void clearstack(sqstack &s);//置空栈void push(sqstack &s,bitnode e);//⼊栈void pop(sqstack &s,bitnode e);//出栈void gettop(sqstack &s);//取栈顶元素int stackempty(sqstack s);//判断栈是否为空void createbitree(bitree &T);//创建树void traversetree(bitree T);//遍历树void preordertraverse(bitree T);//先序遍历void inordertraverse(bitree T);//中序遍历void postordertraverse(bitree T);//后序遍历int treedepth(bitree T);//求树深度void treenature(bitree T);//---------------------主函数----------------------void main(){int a;initstack(s);for(;;){menu();printf("请输⼊要操作的数字\n");scanf("%d",&a);switch(a){case 1:createbitree(T);break;case 2:traversetree(T);break;case 3:treenature(T);break;case 4:exit(0);break;default:printf("please input a number again!");}}}//---------------------⼦函数----------------------------void menu()//菜单{printf("************菜单*************\n");printf("********1、树的创建*********\n");printf("********2、树的遍历*********\n");printf("********3、树的属性*********\n");printf("********4、退出*********\n");}void initstack(sqstack &s)//初始化{s.base=(bitree*)malloc(STACK_INIT_SIZE*sizeof(bitree));if(!s.base)exit(OVERFLOW);s.top=s.base;s.stacksize=STACK_INIT_SIZE;}void clearstack(sqstack &s)//置空栈{s.top=s.base;}void push(sqstack &s,bitree e)//⼊栈{if(s.top-s.base>=s.stacksize){s.base=(bitree*)realloc(s.base,(s.stacksize+STACKINCREMENT)*sizeof(bitree)); if(!s.base)exit(OVERFLOW);s.top=s.base+s.stacksize;s.stacksize+=STACKINCREMENT;}*s.top++=e;}void pop(sqstack &s,bitree &e)//出栈{if(s.top==s.base)printf("栈为空!\n");e=*--s.top;}void gettop(sqstack &s,bitree &e)//取栈顶元素{if(s.top==s.base)printf("栈为空!\n");e=*(s.top-1);}int stackempty(sqstack s)//判断栈为空{if(s.top==s.base)return TRUE;else return FALSE;}void createbitree(bitree &T)//创建树{telemtype ch;telemtype a;a=getchar();scanf("%c",&ch);if(ch=='#')T=NULL;else{if(!(T=(bitnode*)malloc(sizeof(bitnode))))exit(OVERFLOW);T->data=ch;createbitree(T->lchild);createbitree(T->rchild);}}void traversetree(bitree T)//遍历树{int n,i;for(i=0;i<4;i++){printf("************树的遍历************\n");printf("**********1、先序遍历***********\n"); printf("**********2、中序遍历***********\n"); printf("**********3、后序遍历***********\n"); printf("**********4、退出应⽤***********\n"); scanf("%d",&n);switch(n){case 1:preordertraverse(T);break;case 2:inordertraverse(T);break;case 3:postordertraverse(T);break;case 4:printf("树的遍历已退出!\n");break; default:printf("输⼊有误,请重新输⼊!\n");}}}/*void preordertraverse(bitree T)//递归先序遍历{if(T){printf("%c",T->data);preordertraverse(T->lchild); preordertraverse(T->rchild);}printf("\n");}*/void preordertraverse(bitree T)//⾮递归先序遍历{sqstack s;initstack(s);bitree p;p=T;while(p||!stackempty(s)){if(p){printf("%c",p->data);p=p->lchild;}else p=p->rchild;}printf("\n");}/*void inordertraverse(bitree T)//递归中序遍历{if(T){inordertraverse(T->lchild);printf("%c",T->data);inordertraverse(T->rchild);printf("\n");}}*/void inordertraverse(bitree T)//⾮递归中序遍历{sqstack s;initstack(s);bitree p;p=T;while(p||!stackempty(s)){if(p){ push(s,p);p=p->lchild;}else{pop(s,p);printf("%c",p->data);p=p->rchild;}}printf("\n");}/*void postordertraverse(bitree T)//递归后序遍历{if(T){postordertraverse(T->lchild); postordertraverse(T->rchild);printf("%c",T->data);printf("\n");}}*/void postordertraverse(bitree T)//⾮递归后序遍历{bitree p;initstack(s);p = T;int tag;while(p||!stackempty(s)){if(p){push(s,p);tag=0;p = p->lchild;}else{if(tag==1){pop(s,p);printf("%c",p->data);p = NULL;}else{gettop(s,p);tag=1;p = p->rchild;}}}printf("\n");}int treedepth(bitree T)//求树深度{int depthall,depthl,depthr;if(!T)depthall = 0;else{depthl=treedepth(T->lchild);depthr=treedepth(T->rchild);depthall=(depthl > depthr ? depthl:depthr)+1;}//printf("树的深度为:%d\n",depthall);return depthall;}void treenature(bitree T)//树的结点数,叶⼦数,⼀度结点数,树的深度等属性。

数据结构二叉树应用课程设计含源代码实现

数据结构二叉树应用课程设计含源代码实现

递归法的先序遍历:按照输出根、输出左孩子、输出右孩子的顺
序来递归的调用先序遍历函数。
递归法的中序遍历:输出左孩子、按照输出根、输出右孩子的顺
2 / 17
序来递归的调用中序遍历函数。 递归法的后序遍历:输出左孩子、输出右孩子、按照输出根的顺
序来递归的调用后序遍历函数。 二叉树的先序、中序、后序遍历的非递归方法是要借助数据结构
层序遍历。求二叉树的高度、宽度,结点数。判断是否为二叉排序树。
[ห้องสมุดไป่ตู้本要求]
(1) 从文件中读入建树信息,树的节点数目不小于 20 个,树的高
度不小于 4。
(2) 采用二叉链表结构。
(3) 至少 2 组输入数据,分别是二叉排序树和不是二叉排序树。
3.2 数据结构
***********************************************************
typedef struct
{
SElemType *base; //栈底指针
SElemType *top;
//栈顶指针
int stacksize;
//栈的容量
}SqStack;
//栈
3.3 算法设计思想
首先从文件中读取二叉树,按照先序遍历的顺序递归建树,先建
立它的左子树,再建立它的右子树,最后递归结束,整棵树构建成功!
cout<<"文件打开失败!请重试!"<<endl; exit(0); } ReadFile>>sum; while(sum--) { cout<<"case:"<<++case1<<endl; CreatBiTree(Head, ReadFile);

数据结构 二叉树的基本操作实现及其应用

数据结构 二叉树的基本操作实现及其应用

实验三二叉树的基本操作实现及其应用一、实验目的1.熟悉二叉树结点的结构和对二叉树的基本操作。

2.掌握对二叉树每一种操作的具体实现。

3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。

4.会用二叉树解决简单的实际问题。

二、实验内容题目一设计程序实现二叉树结点的类型定义和对二叉树的基本操作。

该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。

1 按先序次序建立一个二叉树,2按(A:先序 B:中序 C:后序)遍历输出二叉树的所有结点以上比做,以下选做3求二叉树中所有结点数4求二叉树的深度**************************************************************** /* 定义DataType为char类型 */typedef char DataType;/* 二叉树的结点类型 */typedef struct BitNode{ DataType data;struct BitNode *lchild,*rchild;}*BitTree;相关函数声明:1、/* 初始化二叉树,即把树根指针置空 */void BinTreeInit(BitTree *BT)2、/* 按先序次序建立一个二叉树*/void BinTreeCreat(BitTree *BT)3、/* 检查二叉树是否为空 */int BinTreeEmpty(BitTree *BT)4、/*按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */void BinTraverse(BitTree *BT)5、/* 求二叉树的深度 */int BinTreeDepth(BitTree BT)6、/* 求二叉树中所有结点数 */int BinTreeCount(BitTree BT)题目二、The Number of the Same BST【Description】Many people knows binary search tree. The keys in a binary search tree are always stored in such a way as to satisfy the BST property:Let X be a node in a binary search tree. If Y is a node in the left subtree of X , then Y<= X. If Y is a node in the right subtree of X , then Y > X.For example,It is a binary search tree. And it can be built by inserting the elements of vector A= (12, 6, 3, 18, 20, 10, 4, 17, 20) sequentially. But it can also be built by the vector B= (12, 18, 17, 6, 20, 3, 10, 4, 20).Now given a vector X, then you may get a binary search tree from X. Your job is to calculate how many different vectors can build the same binary search tree. To make it easy, you should just output the number of different vectors mod 9901.【Input】Input consists of several cases. Each case starts with a line containing one positive integer n, which is the length of test vector. The integer n is less than 20. Following this there will be n positive integers, which are less then 1000, on the next line. The input will end with a case starting with n = 0. This case should not be processed.【Output】For each test case, print a line with a single integer, which is the number of different vectors mod 9901.【Sample Input】32 1 395 6 3 18 20 10 4 17 20【Sample output】2168三、实验步骤㈠、数据结构与核心算法的设计描述㈡、函数调用及主函数设计(可用函数的调用关系图说明)㈢程序调试及运行结果分析㈣实验总结四、主要算法流程图及程序清单1、主要算法流程图:2、程序清单(程序过长,可附主要部分)。

数据结构实验二叉树C完整代码

数据结构实验二叉树C完整代码

#include<iostream>using namespace std;const int MAXSIZE = 100 ;template <class T > struct BiNode //二叉链表结点{T data;//数据域BiNode<T>* lch;//左指针域BiNode<T>* rch;//右指针域};template <class T> class BiTree //二叉树的实现{public:void Create (BiNode<T> * &R,T data[] ,int i);//创建二叉树void Release(BiNode<T> *R); //释放二叉树BiNode<T> *root; //根节点BiTree(T a[]){Create(root,a,1);};//构造函数BiNode<T> * Getroot(){return root;};//根节点地址返回void PrintWay(T data, T a[]);void PreOrder(BiNode<T> *R); //前序遍历void InOrder(BiNode<T> *R); //中序遍历void LevelOrder(BiNode<T> *R);//层序遍历void PostOrder(BiNode<T> *R); //后序遍历~BiTree();//析构函数int GetDepth(BiNode<T> *R,int d);//求二叉树深度void GetPath(T x,BiNode<T>*R);//求指定结点到根结点的路径};template <class T> void BiTree <T>::Create (BiNode<T> * &R,T data[] ,int i)//顺序结构存储二叉链表{//i表示位置,从1开始if(data[i-1]!=0){R=new BiNode<T>;//创建根节点R->data=data[i-1];Create(R->lch,data,2*i);//创建左子树Create(R->rch,data,2*i+1);//创建右子树}elseR=NULL;}template <class T> void BiTree <T>::PreOrder(BiNode<T> *R)//前序遍历的实现{if(R!=NULL){cout<<R->data;//访问结点PreOrder(R->lch);//遍历左子树PreOrder(R->rch);//遍历右子树}}template <class T> void BiTree <T>::InOrder(BiNode<T> *R)//中序遍历的实现{if(R!=NULL){PreOrder(R->lch);//遍历左子树cout<<R->data;//访问结点PreOrder(R->rch);//遍历右子树}}template <class T> void BiTree <T>::PostOrder(BiNode<T> *R)//后序遍历的实现{if(R!=NULL){PreOrder(R->lch);//遍历左子树PreOrder(R->rch);//遍历右子树cout<<R->data;//访问结点}}template <class T> void BiTree <T>::LevelOrder(BiNode<T> *R)//层序遍历的实现{BiNode<T> * queue[MAXSIZE];//利用队列实现层序遍历int f = 0,r = 0;//初始化空队列if(R!=NULL)queue[++r] = R;while(f!=r){BiNode<T> *p=queue[++f];//队头元素出列cout<<p->data;if(p->lch!=NULL)queue[++r]=p->lch;if(p->rch!=NULL)queue[++r]=p->rch;}}template <class T> void BiTree<T>::Release(BiNode<T> *R)//释放二叉树{if (R!=NULL){Release(R->lch);Release(R->rch);delete R;}}template <class T> BiTree<T>::~BiTree() //调用Release函数{Release(root);}template <class T> int BiTree<T>::GetDepth(BiNode<T> *R,int d) //求二叉树的深度{if (R==NULL) return d;if ((R->lch==NULL) && (R->rch==NULL))return d+1;else{int m = GetDepth(R->lch,d+1);int n = GetDepth(R->rch,d+1);return n>m? n:m;}}template<class T> void BiTree<T>::PrintWay(T data, T a[])//打印路径{int x;for(int i=1;i<100;i++){if(a[i-1]==data)//数组中各元素和指定元素比较、查找所在位置i{x=i;break;}}cout<<"该结点到根结点的路径为:"<<endl;while(x!=0){cout<<a[x-1]<<endl;x/=2;//子节点对应父节点编号}}void main(){char buf[MAXSIZE]={'j','u','s','t','l','o','v','e','u','f','o','r','e','v','e','r'};BiTree <char> Test(buf);BiNode<char> * A = Test.Getroot();cout<<"前序遍历:";Test.PreOrder(A);cout<<endl;cout<<"中序遍历:";Test.InOrder(A);cout<<endl;cout<<"后续遍历:";Test.PostOrder(A);cout<<endl;cout<<"层序遍历:";Test.LevelOrder(A);cout<<endl;int depth=0;cout<<"深度为";cout<<Test.GetDepth(A,depth)<<endl;cout<<endl;Test.PrintWay('f',buf);}。

数据结构实验六二叉树操作代码实现

数据结构实验六二叉树操作代码实现

#include<iostream>using namespace std;#define MAXLEN 20 //最大长度int num;typedef char DATA;//定义元素类型struct CBTType// 定义二叉树结点类型{DATA data;//元素数据CBTType * left;//左子树结点指针CBTType * right;//右子树结点指针int leftSize = 0;};/*********************初始化二叉树***********************/ CBTType *InitTree(){CBTType * node;if (node = new CBTType)//申请内存{num++;cout << "请先输入一个根节点数据:" << endl;cin >> node->data;node->left = NULL;node->right = NULL;if (node != NULL)//如果二叉树结点不为空{return node;}else{return NULL;}}return NULL;}/***********************查找结点*************************/ CBTType *TreeFindNode(CBTType *treeNode, DATA data){CBTType *ptr;if (treeNode == NULL){return NULL;}else{if (treeNode->data == data){return treeNode;}else//分别向左右子树查找{if (ptr = TreeFindNode(treeNode->left, data))//左子树递归查找{return ptr;}else if (ptr = TreeFindNode(treeNode->right, data))//右子树递归查找{return ptr;}else{return NULL;}}}}/**********************添加结点*************************/void AddTreeNode(CBTType *treeNode){CBTType *pnode, *parent;DATA data;char menusel;if (pnode = new CBTType) //分配内存{cout << "输入添加的二叉树结点数据:" << endl;cin >> pnode->data;pnode->left = NULL; //设置左子树为空pnode->right = NULL; //设置左子树为空cout << "输入该结点的父结点数据:" << endl;cin >> data;parent = TreeFindNode(treeNode, data); //查找父结点,获得结点指针if (!parent) //没找到{cout << "没有找到父结点!" << endl;delete pnode;return;}cout << "**********************" << endl;cout << "*请输入相应数字:*" << endl;cout << "*1.添加该结点到左子树*" << endl;cout << "*2.添加该结点到右子树*" << endl;cout << "**********************" << endl;do{cin >> menusel;if (menusel == '1' || menusel == '2'){switch (menusel){case '1': //添加结点到左子树if (parent->left) //左子树不为空{cout << "左子树结点不为空" << endl;}else{parent->left = pnode;parent->leftSize++;num++;cout << "数据添加成功!" << endl;}break;case '2': //添加结点到右子树if (parent->right) //右子树不为空{cout << "右子树结点不为空" << endl;}else{parent->right = pnode;num++;cout << "数据添加成功!" << endl;}break;default:cout << "子节点选择错误!" << endl;break;}}} while (menusel != '1'&&menusel != '2');}}/***********************计算二叉树的深度********************************/int TreeDepth(CBTType *treeNode){int depleft, depright;if (treeNode == NULL){return 0; //结点为空的时候,深度为0}else{depleft = TreeDepth(treeNode->left); //左子树深度(递归调用)depright = TreeDepth(treeNode->right); //右子树深度(递归调用)if (depleft){return ++depleft;}else{return ++depright;}}}/*************************显示结点数据*********************************/void ShowNodeData(CBTType *treeNode){cout << treeNode->data << " ";}/***********************清空二叉树************************************/void ClearTree(CBTType *treeNode){if (treeNode)//判断当前树不为空{ClearTree(treeNode->left); //清空左子树ClearTree(treeNode->right); //清空右子树delete treeNode; //释放当前结点所占用的内存}}/**************************按层遍历算法*********************************/void LevelTree(CBTType *treeNode){CBTType *p;CBTType *q[MAXLEN]; //定义一个队列int head = 0, tail = 0;if (treeNode) //如果队首指针不为空{tail = (tail + 1) % MAXLEN; //计算循环队列队尾序号q[tail] = treeNode; //二叉树根指针进入队列while (head != tail){head = (head + 1) % MAXLEN; //计算循环队列的队首序号p = q[head]; //获取队首元素ShowNodeData(p); //输出队首元素if (p->left != NULL) //如果存在左子树{tail = (tail + 1) % MAXLEN; //计算队列的队尾序号q[tail] = p->left; //左子树入队}if (p->right != NULL) //如果存在右子树{tail = (tail + 1) % MAXLEN; //计算队列的队尾序号q[tail] = p->right; //右子树入队}}}}/*************************先序遍历算法**********************************/void DLRTree(CBTType *treeNode){if (treeNode){ShowNodeData(treeNode); //显示结点内容DLRTree(treeNode->left); //显示左子树内容DLRTree(treeNode->right); //显示右子树内容}}/***********************中序遍历算法************************************/void LDRTree(CBTType *treeNode){if (treeNode){LDRTree(treeNode->left); //显示左子树内容ShowNodeData(treeNode); //显示结点内容DLRTree(treeNode->right); //显示右子树内容}}/***********************后序遍历算法************************************/void LRDTree(CBTType *treeNode){if (treeNode){LRDTree(treeNode->left); //显示左子树内容DLRTree(treeNode->right); //显示右子树内容ShowNodeData(treeNode); //显示结点内容}}char find(int theKey,CBTType* root){CBTType *p = root;while (p != NULL)if (theKey < p->leftSize)p = p->left;elseif (theKey > p->leftSize){theKey -= (p->leftSize+1);p = p->right;}elsereturn p->data;//return NULL;}struct TreeNode{struct TreeNode* left;struct TreeNode* right;char elem;};void BinaryTreeFromOrderings(char* inorder, char* preorder, int length){if (length == 0){//cout<<"invalid length";return;}TreeNode* node = new TreeNode;//Noice that [new] should be written out.node->elem = *preorder;int rootIndex = 0;for (; rootIndex < length; rootIndex++){if (inorder[rootIndex] == *preorder)break;}//LeftBinaryTreeFromOrderings(inorder, preorder + 1, rootIndex);//RightBinaryTreeFromOrderings(inorder + rootIndex + 1, preorder + rootIndex + 1, length - (rootIndex + 1));cout << node->elem << ' ';return;}/*************************主函数部分************************************/int main(){int cycle = 1;while (cycle == 1)//主循环{int x;cout << "----------------------------------" << endl;cout << " 主菜单" << endl;cout << "**********************************" << endl;cout << "*0.退出*" << endl;cout << "*1.对二叉树进行操作*" << endl;cout << "*2.输入前序序列和中序序列转为后序*" << endl;cout << "**********************************" << endl;cin >> x;CBTType *root = NULL;switch (x){//二叉树操作case 1:{char menusel;//设置根结点root = InitTree();//添加结点do{cout << "你想为二叉树添加结点吗?(y/n)" << endl;cin >> menusel;switch (menusel){case 'y':AddTreeNode(root);break;case 'n':break;default:cout << "添加结点错误!" << endl;break;}} while (menusel != 'n');//输出树的深度cout << "--------------------" << endl;cout << "二叉树建立完毕!" << endl;cout << "二叉树树高为:" << TreeDepth(root) << endl;//输出结点内容cout << "二叉树节点个数:" << num << endl;cout << "--------------------" << endl;do{cout << "请选择菜单遍历二叉树,输入0表示退出:" << endl;cout << "1.层次遍历" << endl;cout << "2.先序遍历" << endl;cout << "3.中序遍历" << endl;cout << "4.后序遍历" << endl;cout << "-------------------------------------" << endl;cin >> menusel;switch (menusel){case '0':break;case '1':cout << "按层遍历的结果:" << endl;LevelTree(root);cout << endl;break;case '2':cout << "先序遍历的结果:" << endl;DLRTree(root);cout << endl;break;case '3':cout << "中序遍历的结果:" << endl;LDRTree(root);cout << endl;break;case '4':cout << "后序遍历的结果:" << endl;LRDTree(root);cout << endl;break;default:cout << "选择出错!" << endl;break;}} while (menusel != '0');//清空二叉树ClearTree(root);break;}case 2:{ int n;printf("请输入元素个数:\n");cin >> n;char *pr = new char[n];printf("请输入前序序列:\n");for (int i = 0; i < n; i++){cin >> pr[i];}char *in = new char[n];printf("请输入中序序列:\n");for (int i = 0; i < n; i++){cin >> in[i];}printf("转换成后序序列为:\n"); BinaryTreeFromOrderings(in, pr, n);cout << endl;break;}case 0:cycle = 0;cout << endl;cout << "**************已退出**************" << endl;break;}}return 0;}。

数据结构-课程设计报告二叉排序树的实现

数据结构-课程设计报告二叉排序树的实现

课程设计课程名称数据构造课程设计题目名称二叉排序树的实现学院应用数学学院专业班级学号学生XX指导教师2013 年12 月26 日1.设计任务1)实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进展先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。

4)分别用二叉排序树和数组去存储一个班(50人以上)的成员信息(至少包括学号、XX、成绩3项),比照查找效率,并说明为什么二叉排序树效率高〔或者低〕。

2. 函数模块:2.1.主函数main模块功能1.通过bstree CreatTree()操作建立二叉排序树。

2.在二叉排序树t中通过操作bstree InsertBST(bstree t,intkey,nametype name,double grade)插入一个节点。

3. 从二叉排序树t中通过操作void Delete(bstree &p)删除任意节点。

4. 在二叉排序树t中通过操作bstnode *SearchBST(bstree t,keytype key)查找节点。

5. 在二叉排序树t中通过操作p=SearchBST(t,key)查询,并修改节点信息6. 非递归遍历二叉排序树。

7. 定义函数void pare()对数组和二叉排序树的查找效率进展比拟比拟。

2.2创立二叉排序树CreatTree模块从键盘中输入关键字及记录,并同时调用插入函数并不断进展插入。

最后,返回根节点T。

2.3删除模块:二叉排序树上删除一个阶段相当于删去有序系列中的一个记录,只要在删除某个节点之后依旧保持二叉排序树的性质即可。

假设二叉排序树上删除节点为*p〔指向节点的指针为p〕,其双亲节点为*f〔节点指针为f〕。

假设*p节点为叶子节点,那么即左右均为空树,由于删去叶子节点不破坏整棵树的构造,那么只需修改其双亲节点的指针即可;假设*p节点只有左子树或只有右子树,此时只要令左子树或右子树直接成为其双亲节点*f的左子树即可;假设*p节点的左子树和右子树均不为空,其一可以令*p的左子树为*f的左子树,而*p的右子树为*s的右子树,其二可以令*p的直接前驱〔或直接后继〕替代*p,然后再从二叉排序树中删去它的直接前驱〔或直接后继〕。

《数据结构》树和二叉树代码整理(C语言实现)

《数据结构》树和二叉树代码整理(C语言实现)

《数据结构》树和⼆叉树代码整理(C语⾔实现)前⾔: 排版很难看,没办法,我绝对不是因为懒得排⽽懒得排,⽽是因为只有被命运⽯之门选中的⼈才能从头到尾够看到底。

先序创建⼆叉树(这⾥⽤了C++ <引⽤>的特性,使⽤⼆重指针代替或者将函数返回值设成指针再做点⼩修改也能实现)1void CreateTree(TreeRoot &Root)2 {//创建(先序)3char c;4 c=getchar();5if(c!='#')6 {7 Root=(TreeRoot)malloc(sizeof(TNode));8 Root->data=c;9 CreateTree(Root->pleft);10 CreateTree(Root->pright);11 }12else13 {14 Root=NULL;15 }16 }⼆叉树遍历(前|中|后序)--递归(核⼼代码)12void InorderTraversal( BinTree BT )3 {4if( BT ) {5 InorderTraversal( BT->Left );6/* 此处假设对BT结点的访问就是打印数据 */7 printf("%d ", BT->Data); /* 假设数据为整型 */8 InorderTraversal( BT->Right );9 }10 }1112void PreorderTraversal( BinTree BT )13 {14if( BT ) {15 printf("%d ", BT->Data );16 PreorderTraversal( BT->Left );17 PreorderTraversal( BT->Right );18 }19 }2021void PostorderTraversal( BinTree BT )22 {23if( BT ) {24 PostorderTraversal( BT->Left );25 PostorderTraversal( BT->Right );26 printf("%d ", BT->Data);27 }28 }2930 ————————————————31版权声明:本⽂为CSDN博主「BrianOne」的原创⽂章,遵循CC 4.0 BY-SA版权协议,转载请附上原⽂出处链接及本声明。

数据结构二叉树实验报告(附代码)

数据结构二叉树实验报告(附代码)

一、【实验构思(Conceive)】(10%)(本部分应包括:描述实验实现的基本思路,包括所用到的离散数学、工程数学、程序设计、算法等相关知识)首先构造二叉树的存储结构,用data存储当前节点的值,分别用*lchild,*rchild 表示该节点的左右孩子。

然后应用BiTree Create函数,根据用户的输入构造二叉树,当输入#时表示没有孩子。

采用递归的思想构造Preorder,Inorder,Postorder函数,分别实现二叉树的先序,中序,和后序的遍历。

然后编写了Sumleaf,Depth函数,来求叶子节点的数目和二叉树的深度。

二、【实验设计(Design)】(20%)(本部分应包括:抽象数据类型的功能规格说明、主程序模块、各子程序模块的伪码说明,主程序模块与各子程序模块间的调用关系)二叉树的存储结构:typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;子程序模块:BiTree Create(BiTree T){char ch;ch=getchar();if(ch=='#')T=NULL;else{if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))printf("Error!");T->data=ch;T->lchild=Create(T->lchild);T->rchild=Create(T->rchild);}return T;}void Preorder(BiTree T){if(T){printf("%c",T->data);Preorder(T->lchild);Preorder(T->rchild);}}int Sumleaf(BiTree T){int sum=0,m,n;if(T){if((!T->lchild)&&(!T->rchild)) sum++;m=Sumleaf(T->lchild);sum+=m;n=Sumleaf(T->rchild);sum+=n;}return sum;}void Inorder(BiTree T) {if(T){Inorder(T->lchild); printf("%c",T->data); Inorder(T->rchild); }}void Postorder(BiTree T) {if(T){Postorder(T->lchild); Postorder(T->rchild); printf("%c",T->data); }}int Depth(BiTree T){int dep=0,depl,depr;if(!T)dep=0;else{depl=Depth(T->lchild);depr=Depth(T->rchild);dep=1+(depl>depr?depl:depr);}return dep;}主程序模块:int main(){BiTree T = 0;int sum,dep;printf("请输入你需要建立的二叉树\n");printf("例如输入序列ABC##DE#G##F###(其中的#表示空)\n并且输入过程中不要加回车\n输入完之后可以按回车退出\n");T=Create(T);printf("先序遍历的结果是:\n");Preorder(T);printf("\n");printf("中序遍历的结果是:\n");Inorder(T);printf("\n");printf("后序遍历的结果是:\n");Postorder(T);printf("\n");printf("统计的叶子数:\n");sum=Sumleaf(T);printf("%d",sum);printf("\n统计树的深度:\n");dep=Depth(T);printf("\n%d\n",dep);}三、【实现描述(Implement)】(30%)(本部分应包括:抽象数据类型具体实现的函数原型说明、关键操作实现的伪码算法、函数设计、函数间的调用关系,关键的程序流程图等,给出关键算法的时间复杂度分析。

数据结构 树和二叉树代码

数据结构 树和二叉树代码

一、参照给定的二叉树类的程序样例,验证给出的有关二叉树的常见算法,并实现有关的操作。

1、掌握二叉树、哈夫曼树和树的特点。

掌握它们的常见算法。

2、提交实验报告,报告内容包括:目的、要求、算法描述、程序结构、主要变量说明、程序清单、调试情况、设计技巧、心得体味。

1.设计实现二叉树类,要求:(1)编写一个程序,首先建立不带头结点的二叉链式存储结构的二叉树,然后分别输出按照前序遍历二叉树、中序遍历二叉树和后序遍历二叉树访问各结点的序列信息,最后再测试查找函数和撤销函数的正确性。

(2)实现二叉树层次遍历的非递归算法。

(3) 假设二叉树采用链式存储结构进行存储,编写一个算法,输出一个二叉树的所有叶子结点,并统计叶子结点个数。

(4)编写求二叉树高度的函数(5)编写一主函数来验证算法实现。

2. 设计实现二叉线索链表类,要求:(1)编写一个程序,首先建立中序线索链表的二叉树,然后实现中序线索链表的遍历算法。

(2)编写一主函数来验证算法实现。

*3. 编写创建哈夫曼树和生成哈夫曼编码的算法。

*4.假设二叉树采用链式存储结构进行存储,试设计一个算法,输出从每一个叶子结点到根结点的路径。

*5.假设二叉树采用链式存储结构进行存储,试设计一个算法,求二叉树的宽度(即具有结点数最多的层次上结点总数)#include<iostream>#include<queue>using namespace std;template <class T>struct BiNode{T data;BiNode<T> *lchild, *rchild;};int max(int a,int b){return a > b ? a : b; }template <class T>class BiTree{public:BiTree( ); //构造函数,初始化一棵空的二叉树~BiTree()//二叉树的析构函数算法 BiTree{ Release(root); }void InOrder() { InOrder(root);} //中序遍历二叉树void PreOrder(){ PreOrder(root);}void PostOrder(){PostOrder(root);} //后序遍历二叉树void LeverOrder(){LeverOrder(root);}void Count(){Count(root);}//层序遍历二叉树void PreOrdercnt(){PreOrdercnt(root);}int Depth(){int www = Depth(root); return www;} private:BiNode<T> *root; //指向根结点的头指针void Creat(BiNode<T> *&root);void PreOrder(BiNode<T> *root); void InOrder(BiNode<T> *root); void PostOrder(BiNode<T> *root); void LeverOrder(BiNode<T> *root); //前序遍历二叉树//层序遍历二叉树void Release(BiNode<T> *root); //析构函数调用void Count(BiNode<T> *root) ;/////求二叉树的结点个数void PreOrdercnt(BiNode<T> *root);///设计算法按前序次序打印二叉树中的叶子结点;int Depth(BiNode<T> *root);//深度;};template <class T>BiTree<T>::BiTree(){Creat(root);}template <class T>void BiTree<T> ::Creat(BiNode<T> *&root) {char ch;cin>>ch;if (ch=='#') root=NULL; //建立一棵空树else {root=new BiNode<T>;root->data=ch;Creat(root->lchild);Creat(root->rchild);}}template <class T> //生成一个结点//递归建立左子树//递归建立右子树void BiTree<T>::LeverOrder(BiNode<T> *root){BiNode<T> * Q[100];int front = 0, rear = 0; //采用顺序队列,并假定不会发生上溢if (root==NULL) return;Q[++rear]=root;while (front!=rear){BiNode<T> * q=Q[++front];cout<<q->data<<" ";if (q->lchild!=NULL) Q[++rear]=q->lchild;if (q->rchild!=NULL) Q[++rear]=q->rchild;}template <class T>void BiTree<T>::PostOrder(BiNode<T> *root){if (root == NULL) return; //递归调用的结束条件else {PostOrder(root->lchild); //后序递归遍历 root 的左子树PostOrder(root -> rchild);//后序递归遍历root 的右子树cout<<root->data<<" ";//访问根结点的数据域}}template <class T>void BiTree<T>::PreOrder(BiNode<T> *root){if (root ==NULL) return; //递归调用的结束条件else {cout<<root->data<<" ";PreOrder(root->lchild);PreOrder(root->rchild);}}template <class T>//访问根结点的数据域//前序递归遍历root 的左子树//前序递归遍历root 的右子树void BiTree<T> ::Release(BiNode<T> *root) {if (root!=NULL) {Release(root->lchild);Release(root->rchild);delete root;}} //释放左子树//释放右子树template <class T>void BiTree<T>::InOrder (BiNode<T> *root)//二叉树的中序遍历递归算法InOrder{if (root==NULL) return; //递归调用的结束条件else {InOrder(root->lchild);cout<<root->data<<" ";InOrder(root->rchild);}}int n = 0; //中序递归遍历root 的左子树//访问根结点的数据域//中序递归遍历root 的右子树template <class T>void BiTree<T>::Count(BiNode<T> *root) //n为全局量并已初始化为 0 {if (root){Count(root->lchild);n++; ///求二叉树的结点个数Count(root->rchild);}int cnt = 0;template <class T>void BiTree<T>::PreOrdercnt(BiNode<T> *root)///设计算法按前序次序打印二叉树中的叶子结点;{if (root) {if (!root->lchild && !root->rchild){cout<<root->data <<" ";cnt++;}PreOrdercnt(root->lchild);PreOrdercnt(root->rchild);}}template <class T>int BiTree<T>::Depth(BiNode<T> *root)//算法求二叉树的深度{if (root==NULL) return 0;else {int hl= Depth(root->lchild);int hr= Depth(root ->rchild);return max(hl, hr)+1;}}int main(){BiTree<char> mytree;cout<< "结点总个数: ";mytree.Count();cout<<n<<endl; cout << endl;cout<< "前序遍利: ";mytree.PreOrder();cout << endl; cout<< "中序遍利: ";mytree.InOrder();cout << endl; cout<<"后序遍利: ";mytree.PostOrder(); cout << endl;cout<<"层序遍利: ";mytree.LeverOrder();cout << endl; cout<<"叶子结点为: ";mytree.PreOrdercnt(); cout<<" 个数: ";cout<<cnt<<" "; cout << endl;cout<<"二叉树的深度: ";cout <<mytree.Depth()<<endl;return 0;}2.//声明类 InThrBiTree 及定义结构 ThrNode,文件名为 inthrbitree.h#ifndef INTHRBITREE_H#define INTHRBITREE_Henum flag {Child, Thread}; //枚举类型,枚举常量 Child=0,Thread=1template <class T>struct ThrNode //二叉线索树的结点结构{T data;ThrNode<T> *lchild, *rchild;flag ltag, rtag;};template <class T>class InThrBiTree{public:InThrBiTree( ); ~InThrBiTree( ); //构造函数,建立中序线索链表//析构函数,释放线索链表中各结点的存储空间ThrNode<T>* Getroot( ); ThrNode<T>* Next(ThrNode<T>* p); void InOrder(ThrNode<T>* root); //获取根结点//查找结点p 的后继//中序遍历线索链表private:ThrNode<T>* root; ThrNode<T>* Creat( ); //指向线索链表的头指针//构造函数调用void ThrBiTree(ThrNode<T>* root);void Release(ThrNode<T>* root); };#endif //构造函数调用//析构函数调用//定义类 InThrBiTree 中的成员函数,文件名为 inthrbitree.cpp #include<iostream>#include<string>#include"inthrbitree.h"using namespace std;//构造一棵中序线索二叉树template <class T>InThrBiTree<T>::InThrBiTree( ){ThrNode<T>* pre = NULL;this->root = Creat( );ThrBiTree(root);}//释放中序线索二叉链表中各结点的存储空间template <class T>InThrBiTree<T>::~InThrBiTree(void){Release(root);}//获取指向中序线索二叉树根结点的指针template <class T>ThrNode<T>* InThrBiTree<T>::Getroot( ){return root;}//输出指向结点p 的后继结点的指针template <class T>ThrNode<T>* InThrBiTree<T>::Next(ThrNode<T>* p){ThrNode<T>* q;if (p->rtag==Thread) q = p->rchild; //右标志为 1,可直接得到后继结点else{q = p->rchild;while (q->ltag==Child){q = q->lchild;}} //工作指针初始化//查找最左下结点return q;}//中序遍历一棵线索二叉树template <class T>void InThrBiTree<T>::InOrder(ThrNode<T> *root) {ThrNode<T>* p = root;if (root==NULL) return;while (p->ltag==Child){p = p->lchild;}cout<<p->data<<" ";while (p->rchild!=NULL){p = Next(p);cout<<p->data<<" ";}cout<<endl;} //如果线索链表为空,则空操作返回//查找中序遍历序列的第一个结点 p 并访问//当结点 p 存在后继,挨次访问其后继结点//构造一棵二叉树,构造函数调用template <class T>ThrNode<T>* InThrBiTree<T>::Creat( ){ThrNode<T> *root;T ch;cout<<"请输入创建一棵二叉树的结点数据"<<endl;cin>>ch;if (ch=="#") root = NULL;else{root=new ThrNode<T>; //生成一个结点root->data = ch;root->ltag = Child;root->rtag = Child;root->lchild = Creat( ); //递归建立左子树root->rchild = Creat( ); //递归建立右子树}return root;}//给二叉树建立线索template <class T>void InThrBiTree<T>::ThrBiTree(ThrNode<T> *root) {if (root==NULL) return; ThrBiTree(root->lchild); if (!root->lchild){ //递归结束条件//对root 的左指针进行处理root->ltag = Thread;root->lchild = pre; //设置 pre 的前驱线索}if (!root->rchild) root->rtag = Thread; //对 root 的右指针进行处理if(pre != NULL){if (pre->rtag==Thread) pre->rchild = root; //设置 pre 的后继线索}pre = root;ThrBiTree(root->rchild);}//释放中序线索二叉树的存储空间,析构函数调用template<class T>void InThrBiTree<T>::Release(ThrNode<T>* root){if (root!=NULL){Release(root->lchild);Release(root->rchild);delete root;} //释放左子树//释放右子树}//线索二叉树的主函数,文件名为 inthrbitreemain.cpp#include<iostream>#include<string>#include"inthrbitree.cpp"using namespace std;ThrNode<string>* pre;void main(){InThrBiTree<string> inbt;//构造一棵线索二叉树ThrNode<string>* p = inbt.Getroot( ); //获取指向根结点的指针cout<<"----中序遍历线索二叉树------"<<endl;inbt.InOrder(p);}注意问题1.注意理解有关树的各种递归算法的执行步骤。

数据结构课程设计二叉树相关操作源代码

数据结构课程设计二叉树相关操作源代码

可运行c语言数据结构课程设计二叉树相关操作源代码#include<stdio.h>#include<stdlib.h>#define MAXSIZE 1000structBiTNode{int c;intlchild,rchild;}BiTNode,*BiTree;structBiTNode tree[MAXSIZE];void creat()//创建二叉树函数{inti,j;printf("需要输入权值个数:\n");scanf("%d",&j);if (j<8)//判断二叉树是否达到4层{printf("错误:二叉树的层数少于4层!\n"); return;}printf("开始输入权值:\n");for(i=1;i<=j;i=i+1)//权值的录入{scanf("%d",&tree[i].c);tree[i].lchild=2*i;tree[i].rchild=2*i+1;}printf("成功创建二叉树\n");}int leaves()//统计叶子个数函数{intl,i;l=0;for (i=1;tree[i].c!=NULL;i++)//计算二叉树结点的个数{l++;}if ((l%2))//判断结点的奇偶性从而计算叶子的个数{return(((l-1)/2)+1);}elsereturn(l/2);}int deep()//求二叉树的深度{intd,i,sum;sum=1;for (i=1;tree[i].c!=NULL;i++);//计算二叉树结点的个数for (d=1;sum<=i;d++)//求出二叉树的深度{if (d!=1){sum=sum+sum*2;}}return(d-1);}void qian(int a)//前序遍历输出列表{if (tree[a].c!=NULL)//判断当前结点是否有值,若有执行如下操作,若无则返回上一层{printf("%d,",tree[a].c);//首先输出当前结点(根节点)的权值qian((a*2));//递归调用,用当前结点的左孩子作根节点重复当前函数的操作qian((a*2+1));//递归调用,用当前结点的右孩子作根节点重复当前函数的操作}elsereturn;}void zhong(int a)//中序遍历输出列表{if (tree[2*a].c!=NULL)//首先判断当前结点的左孩子是否为空,不是就进行递归调用,用当前结点的左孩子作根节点重复当前函数的操作{zhong((2*a));}printf("%d,",tree[a].c);//输出当前结点的权值if (tree[2*a+1].c!=NULL)//判断当前结点的右孩子是否为空,不是就进行递归调用,用当前结点的右孩子作根节点重复当前函数的操作{zhong((2*a+1));}}void hou(int a)//后序遍历输出序列{if (tree[2*a].c!=NULL)//判断当前结点的左孩子是否为空,不是就进行递归调用,用当前结点的左孩子作根节点重复当前函数的操作{hou((2*a));}if (tree[2*a+1].c!=NULL)//判断当前结点的右孩子是否为空,不是就进行递归调用,用当前结点的右孩子作根节点重复当前函数的操作{hou((2*a+1));}printf("%d,",tree[a].c);//输出当前结点的权值}void main(){intd,l,i;i=10;printf("******************目录******************\n");printf("1、创建二叉树\n");printf("2、统计叶子个数\n");printf("3、求二叉树的深度\n");printf("4、前序遍历输出列表\n");printf("5、中序遍历输出列表\n");printf("6、后序遍历输出序列\n");printf("0、退出操作\n");printf("*****************************************\n"); while(i!=0) {printf("选择操作:\n");scanf("%d",&i);if(i==0){break;}else if(i==1){printf("开始创建二叉树(层数不少于4层)\n");creat();}else if(i==2){l=leaves();printf("叶子个数为:%d\n",l);}else if(i==3){d=deep();printf("二叉树的深度是%d\n",d);}else if(i==4){printf("用前序遍历输出的结果是:\n"); qian(1);printf("\n");}else if(i==5){printf("用中序遍历输出的结果是:\n"); zhong(1);printf("\n");}else if(i==6){printf("用后序遍历输出的结果是:\n"); hou(1);printf("\n");}elseprintf("错误:没有该操作!\n");}printf("欢迎使用!\n");}。

数据结构二叉树基本操作技巧源代码

数据结构二叉树基本操作技巧源代码

数据结构二叉树基本操作(1).// 对二叉树的基本操作的类模板封装//------------------------------------------------------------------------------------------------------------------------#include<iostream>using namespace std;//------------------------------------------------------------------------------------------------------------------------//定义二叉树的结点类型BTNode,其中包含数据域、左孩子,右孩子结点。

template <class T>struct BTNode{T data ; //数据域BTNode* lchild; //指向左子树的指针BTNode* rchild; //指向右子树的指针};//------------------------------------------------------------------------------------------------------------------------//CBinary的类模板template <class T>class BinaryTree{BTNode<T>* BT;public:BinaryTree(){BT=NULL;} // 构造函数,将根结点置空~BinaryTree(){clear(BT);} // 调用Clear()函数将二叉树销毁void ClearBiTree(){clear(BT);BT=NULL;}; // 销毁一棵二叉树void CreateBiTree(T end); // 创建一棵二叉树,end为空指针域标志bool IsEmpty(); // 判断二叉树是否为空int BiTreeDepth(); // 计算二叉树的深度bool RootValue(T &e); // 若二叉树不为空用e返回根结点的值,函数返回true,否则函数返回falseBTNode<T>*GetRoot(); // 二叉树不为空获取根结点指针,否则返回NULLbool Assign(T e,T value); // 找到二叉树中值为e的结点,并将其值修改为value。

二叉树应用源代码和实验报告

二叉树应用源代码和实验报告

实验十一二叉树的应用姓名:高翠莹学号:09 专业班级:数媒151一、实验项目名称二叉树的应用二、实验目的1.通过实验理解二叉树的逻辑结构;2.通过实验掌握二叉树的二叉链表存储结构;3.通过实验掌握二叉树的应用。

三、实验基本原理1、数据结构typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;2、算法思想这次实验主要是对二叉树的一些应用:(1)在二叉树中查找值为value的结点:即寻找每一个节点的data,若与value相同则返回;(2)统计出二叉树中叶子结点的数目:如果一个左孩子和右孩子都为空,则返回1,然后递归访问左子树和右子树,统计出所有的叶子结点;(3)统计出二叉树中非叶子结点的数目:用所有结点个数减去叶子结点个数即可;(4)统计出二叉树中所有结点的数目:递归调用,返回左子树结点个数加右结点个数,再加1;(5)求二叉树的高度递归求左子树高度h1和右子树高度h2,如果h1>h2,则返回h1+1,否则返回h2+1;3、算法描述见代码四、主要仪器设备及耗材1、硬件环境2、开发平台Dev C++五、实验步骤1.分析题目,确定数据结构类型,设计正确的算法;2.编写代码;3.运行及调试程序;4.修改程序,提高其健壮性。

六、实验数据及处理结果1、程序清单#include<iostream>#include<cstdlib>using namespace std;typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;算二叉树中所有结点的数目"<<endl;cout<<"2.计算二叉树中所有叶子结点的数目"<<endl;cout<<"3.计算二叉树中所有非叶子结点的数目"<<endl;cout<<"4.查找二叉树中值为value的结点"<<endl;cout<<"5.求二叉树中的高度"<<endl;cout<<"0.退出"<<endl;}int main(){cout<<"***************二叉树的应用*************"<<endl;cout<<"一、创建二叉树"<<endl;BiTree T;cout<<"按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树"<<endl;CreateBiTree(T);cout<<"先序遍历这课树: "<<endl;PreOrder(T);cout<<endl;cout<<"二、具体操作"<<endl;Tips();int op;char x;cin>>op;while(op){switch(op){case 1:cout<<"树的所有节点个数为: ";cout<<countBTreeNode(T);break;case 2:cout<<"所有叶子结点个数为: ";cout<<Calleaf(T);break;case 3:int count;cout<<"非叶子结点的个数为: "<<countBTreeNode(T)-Calleaf(T)<<endl;break;case 4:cout<<"请输入value的值:";cin>>x;cout<<"值为"<<x<<"的结点为: ";locate(T,x);break;case 5:cout<<"树的高度为: ";cout<<BTreeHigh(T);break;}Tips(); cin>>op;}}2、运行结果(1)创建(2)操作求所有结点个数:求所有叶子结点个数:求所有非叶子结点个数:求值为value的结点:求二叉树的高度:七、思考讨论题或体会或对改进实验的建议这次实验之后,我更加了解树的逻辑结构,它有很强的递归属性,所以只要理解了递归的本质,就不难理解本次实验的操作,因为在操作时基本上都用到了递归方法,可以用少量的代码就能实现功能。

数据结构与算法问题分析及源代码之二叉树

数据结构与算法问题分析及源代码之二叉树

二叉树1 题目编写一个程序,实现二叉树的各种运算,并在此基础上设计一个主程序完成如下功能(b 为如图示的一棵二叉树):输出二叉树b;输出‘H’节点的左、右孩子结点值;输出二叉树b的深度;输出二叉树b的结点个数;输出二叉树b的叶子结点个数。

2 目标熟悉二叉树的定义及其基本操作的实现3 设计思想二叉树的每个结点都有指向其左右孩子的指针,对二叉树的表示可以有很多方法,这里采用中序的带括号表示法,以字符串形式读入输出。

建立存储结构的时候,从根结点开始,赋值定义其左右指针,由于二叉树的每个结点操作类似,因此可以采用递归的方法。

4 算法描述(1)输入建立二叉树:读入字符串,根据括号表示法的规则,a(b,c)的括号中左右元素表示结点的左右子树结点,若结点是树(括号中还有括号),则再调用改操作,直至结点全部读入。

(2)输出二叉树:从根结点开始,打印根结点数据,如果结点的左右孩子指针不为空,就打印左括号,并按先左后右的次序调用此操作,最后输出右括号完成括号表示。

(3)输出二叉树的深度:从根结点开始,如果左或右孩子不是树的话返回深度加一,否则继续调用此操作,直到完全返回(返回深度是左、右深度中的最大值)。

(4)输出二叉树叶子结点数:从根结点开始,用ln和r n分别表示结点左右叶子结点数,函数返回叶子结点数之和,递归调用该函数,直到左右指针指空。

(5)输出二叉树结点数:结点数即是叶子数加一。

5 程序结构图6 源程序typedef struct node{char data;struct node *lchild;struct node *rchild;}*Bitree;Bitree bt;void CreateBitree(Bitree &bt,char *str){Bitree St[100],p=NULL;//100个结点的二叉树int top=-1,k,j=0;char ch;bt=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 = (struct node*)malloc(sizeof(struct node)); p->data=ch;p->lchild=p->rchild=NULL;if (bt==NULL)//是根结点bt=p;else//是叶子结点{ switch(k){case 1:St[top]->lchild=p;break;case 2:St[top]->rchild=p;break; }}}j++;ch=str[j];}}void DispBTNode(Bitree bt){Bitree p;if(bt==NULL) return ;else {printf("%c",bt->data);if(bt->lchild!=NULL||bt->rchild!=NULL) {printf("(");DispBTNode(bt->lchild);if(bt->rchild!=NULL)printf(",");DispBTNode(bt->rchild);printf(")");}}}int BtNodeDepth(Bitree bt){int lh,rh;if(bt==NULL)return 0;else{lh=BtNodeDepth(bt->lchild);rh=BtNodeDepth(bt->rchild);return (lh>rh?lh:rh)+1;}}int NodeNum(Bitree bt){int ln,rn;if(bt==NULL)return 0;else{ln=NodeNum(bt->lchild);rn=NodeNum(bt->rchild);return ln+rn+1;}}int LeafNodeNum(Bitree bt){int ln,rn;if(bt==NULL)return 0;else if(bt->lchild==NULL&&bt->rchild==NULL)return 1;else{ln=LeafNodeNum(bt->lchild);rn=LeafNodeNum(bt->rchild);return ln+rn;}}#include<stdio.h>#include<stdlib.h>#include"bintree.h"void main(){int m,length;Bitree p;char e;char choice;printf("请选择(输入退出)\n1 创建二叉树b\n2 打印二叉树b(中续括号表示法)\n3 二叉树b的长度\n4 二叉树b的结点数\n5 二叉树b的叶子数\n");while(choice!='0'){// system("cls");scanf("%c",&choice);switch (choice){case'1':CreateBitree(bt,"A(B(D,E(H(J,K(L,M(,N))),)),C(F,G(,I)))");break;case'2':DispBTNode(bt);printf("\n");break;case'3':printf("二叉树b的长度为:%d\n",BtNodeDepth(bt));break;case'4':printf("二叉树结点数为:%d\n",NodeNum(bt));break;case'5':printf("二叉树叶子结点数为:%d\n",LeafNodeNum(bt));break;case'0':return;}getchar();}}。

二叉树课程设计c语言

二叉树课程设计c语言

二叉树是计算机科学中常用的一种数据结构,可以用于表示各种类型的数据。

以下是一个简单的二叉树课程设计,使用C语言实现。

```c#include <stdio.h>#include <stdlib.h>// 定义二叉树节点结构体typedef struct Node {int data;struct Node *left;struct Node *right;} Node;// 创建新节点Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node));if (!newNode) {printf("内存分配失败\n");return NULL;}newNode->data = data;newNode->left = NULL;newNode->right = NULL;return newNode;}// 插入节点Node* insertNode(Node* root, int data) {if (root == NULL) {return createNode(data);}if (data <= root->data) {root->left = insertNode(root->left, data); } else {root->right = insertNode(root->right, data); }return root;}// 中序遍历二叉树void inorderTraversal(Node* root) {if (root == NULL) {return;}inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}int main() {Node* root = NULL; // 初始时,根节点为空int arr[] = {8, 3, 10, 1, 6, 14, 4, 7, 13}; // 要插入的节点数据数组int n = sizeof(arr) / sizeof(arr[0]); // 数组元素个数for (int i = 0; i < n; i++) { // 插入节点到二叉树中 root = insertNode(root, arr[i]);}printf("中序遍历二叉树的结果为:"); // 中序遍历二叉树,输出结果为升序排列的节点数据数组inorderTraversal(root);printf("\n");return 0;}```。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5 / 17
(8)求宽度:O(n^2)
(9)判断是否是二叉排序树:O(n^2)
3.6 源代码
#include<iostream> #include<stdlib.h>//exit(0); #include<fstream>//fstream
using namespace std;
typedef int TElemType;
typedef struct BiTNode //二叉树的数据结构 {
再取栈顶元素进行相应判断。输出根结点后就是要找它的左孩子,直 到左孩子为 NULL 后,退一个结点向右一次(找它的右孩子),然后继 续循环找这个右孩子的左孩子。直到所有的左右孩子都找完(栈空), 此时先序遍历结束。
中序遍历,是先找左孩子,直到左孩子为 NULL,这时退一个结点 输出,然后再向右一次(找其右孩子),继续循环找这个右孩子的左 孩子。直到栈空全部找完,此时中序遍历结束。
3.2 数据结构
***********************************************************
typedef int TElemType;
typedef struct BiTNode
{
TElemType data;
//值
struct BiTNode *lchild,*rchild;
SElemType *top;
//栈顶指针
int stacksize;
//栈的容量
}SqStack;
//栈
3.3 算法设计思想
首先从文件中读取二叉树,按照先序遍历的顺序递归建树,先建
立它的左子树,再建立它的右子树,最后递归结束,整棵树构建成功!
递归法的先序遍历:按照输出根、输出左孩子、输出右孩子的顺
1 / 17
struct QNode *next;
}QNode,*QueuePtr;
//队列结点
***********************************************************
typedef struct
{
QueuePtr front;
QueuePtr rear;
结点数在递归建树的时候就可以求出,不用额外写函数。每次增 加新结点,总结点数(从 0 开始)就加一,全部建好,此时的结点数 就是这棵树的结点数。
判断是否为二叉排序树,可知二叉排序树的中序遍历是一个有序 数组(从小到大),通过这一点,对中序遍历进行改变,对每次结点 都判断是否满足左孩子大于根大于右孩子,如果有一个不满足,那么 这棵树就不是二叉排序树。 3.4 测试数据和结果 (1)测试数据: 2 50 40 28 20 15 0 0 27 0 0 33 31 30 0 0 32 0 0 35 0 36 0 0 45 43 0 44 0 0 48 0 49 0 0 55 54 52 51 0 0 53 0 0 0 59 57 0 0 66 63 60 0 0 64 0 65 0 0 70 0 0
//左右孩子指针
}BiTNode,*BiTree;
//二叉树结点
***********************************************************
typedef BiTree QElemType;
typedef struct QNode
{
QElemType data;
}LinkQueue;
//队列
***********************************************************
typedef BiTree SElemType; //定义 SElemType 的类型为 int
typedef struct
{
SElemType *base; //栈底指针
7 9 11 17 23 15 0 0 18 0 0 0 19 60 0 0 70 0 0 20 0 0 10 13
4 / 17
66 0 0 77 99 55 61 0 0 62 0 0 56 0 0 101 0 0 16 0 0(2)运行 运行结果:
3.5 时间复杂度 (1)建树:O(n) (2)递归法的先序中序和后序遍历:O(1) (3)层次遍历:O(n) (4)非递归法的先序遍历:O(n^2) (5)非递归法的中序遍历:O(n^2) (6)非递归法的后序遍历:O(n) (7)求树高:O(1)
序来递归的调用先序遍历函数。
递归法的中序遍历:输出左孩子、按照输出根、输出右孩子的顺
2 / 17
序来递归的调用中序遍历函数。 递归法的后序遍历:输出左孩子、输出右孩子、按照输出根的顺
序来递归的调用后序遍历函数。 二叉树的先序、中序、后序遍历的非递归方法是要借助数据结构
栈来实现的。 先序遍历是最先输出二叉树的结点,所以入栈时输出即可,然后
后序遍历,先输出左右孩子再输出结点。要保证根结点在左孩子 和右孩子访问之后才能访问,因此对于任一结点 P,先将其入栈。如 果 P 不存在左孩子和右孩子,则可以直接访问它;或者 P 存在左孩子 或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直 接访问该结点。
若非上述两种情况,则将 P 的右孩子和左孩子依次入栈,这样就 保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子 和右孩子都在根结点前面被访问。
3.1 题目简介
பைடு நூலகம்
[问题描述]
编程实现二叉树的建立,先序、中序、后序(递归和非递归方法)、
层序遍历。求二叉树的高度、宽度,结点数。判断是否为二叉排序树。
[基本要求]
(1) 从文件中读入建树信息,树的节点数目不小于 20 个,树的高
度不小于 4。
(2) 采用二叉链表结构。
(3) 至少 2 组输入数据,分别是二叉排序树和不是二叉排序树。
层次遍历是用数据结构队列。队头输出这一层的结点,队尾不断
3 / 17
将输出结点的非空左右孩子入队。直到队列空,层次遍历结束。 递归法求树的高度,先求左子树的高度,再求右子树的高度,再
取左右子树高的最大值,将这个最大值+1(根结点)就是这棵树的高 度。
求树的宽度,用层次遍历来改编,求每一层的结点数,用 max 记 录目前为止的最大宽度,与下一层相比较,如果 max 较小就更新,直 到队空,此时的 max 存放的就是整棵树的宽度。
相关文档
最新文档