实现二叉树中所有节点左右子树的交换

合集下载

二叉树的左右子树交换

二叉树的左右子树交换

#include<stdio.h>#include<malloc.h>#include<conio.h>typedef struct BiTreeNode{int data;struct BiTreeNode *lchild,*rchild;}BiTreeNode,*Bitree;void Inorder(BiTreeNode *Bt){if(Bt!=NULL){Inorder(Bt->lchild);printf("%d ",Bt->data);Inorder(Bt->rchild);}}void InsertBST(BiTreeNode *&Bt,int k){if(Bt==NULL){Bt=(BiTreeNode *)malloc(sizeof(BiTreeNode));Bt->data=k;Bt->lchild=NULL;Bt->rchild=NULL;}else{if(Bt->data>k){InsertBST(Bt->lchild,k);}if(Bt->data<k){InsertBST(Bt->rchild,k);}}}void Exchang(BiTreeNode *&Bt){if(Bt!=NULL){BiTreeNode *r;Bt->lchild=Bt->rchild;Bt->rchild=r;Exchang(Bt->lchild);Exchang(Bt->rchild);}}main(){BiTreeNode *Bt=NULL;printf("please input data and end with 0:\n");int k;scanf("%d",&k);while(k!=0){InsertBST(Bt,k);scanf("%d",&k);}Inorder(Bt);printf("\nthe order after exchanging is:\n");#include<stdio.h>#include<malloc.h>#include<conio.h>typedef struct BiTreeNode{int data;struct BiTreeNode *lchild,*rchild;}BiTreeNode,*Bitree;void Inorder(BiTreeNode *Bt){if(Bt!=NULL){Inorder(Bt->lchild);printf("%d ",Bt->data);Inorder(Bt->rchild);}}void InsertBST(BiTreeNode *&Bt,int k){if(Bt==NULL){Bt=(BiTreeNode *)malloc(sizeof(BiTreeNode));Bt->data=k;Bt->rchild=NULL;}else{if(Bt->data>k){InsertBST(Bt->lchild,k);}if(Bt->data<k){InsertBST(Bt->rchild,k);}}}void Exchang(BiTreeNode *&Bt){if(Bt!=NULL){BiTreeNode *r;r=Bt->lchild;Bt->lchild=Bt->rchild;Bt->rchild=r;Exchang(Bt->lchild);Exchang(Bt->rchild);}}main(){BiTreeNode *Bt=NULL;printf("please input data and end with 0:\n");int k;scanf("%d",&k);while(k!=0){InsertBST(Bt,k);scanf("%d",&k);}Inorder(Bt);printf("\nthe order after exchanging is:\n");Exchang(Bt);Inorder(Bt);getch(); Exchang(Bt);Inorder(Bt);getch();}。

实现二叉树中所有节点左右子树的交换

实现二叉树中所有节点左右子树的交换

实现二叉树中所有节点左右子树的交换在二叉树中,交换每个节点的左右子树可以通过递归算法实现。

让我们来看看如何实现这个功能。

首先,我们需要定义一个二叉树的节点类(Node),该类包含一个值属性和左右子树属性。

我们还可以添加一些其他方法来获取和设置节点的值以及左右子树。

```pythonclass Node:def __init__(self, value):self.value = valueself.left = Noneself.right = None```接下来,我们可以定义一个函数来交换每个节点的左右子树。

遍历二叉树的每个节点,并通过交换节点的左右子树来实现。

```pythondef swap_tree(node):if node is None:returntemp = node.leftnode.left = node.rightnode.right = tempswap_tree(node.left)swap_tree(node.right)```我们可以使用先序遍历的方法来遍历二叉树,即先访问根节点,然后递归地遍历左子树和右子树。

在遍历每个节点时,我们交换其左右子树。

最后,我们可以在一个示例二叉树上测试我们的代码。

假设我们有以下二叉树:```/\23/\\456```下面是测试代码和输出结果:```python#创建二叉树root = Node(1)root.left = Node(2)root.right = Node(3)root.left.left = Node(4)root.left.right = Node(5)root.right.right = Node(6)#交换每个节点的左右子树swap_tree(root)#打印交换后的二叉树#输出结果:132654def print_tree(node):if node is None:returnprint(node.value, end=" ")print_tree(node.left)print_tree(node.right)print_tree(root)```以上代码将输出交换后的二叉树的先序遍历结果:132654、可以看到,通过交换每个节点的左右子树,我们成功地改变了二叉树的结构。

可交换左右孩子的二叉树

可交换左右孩子的二叉树

#include <stdio.h>#include <malloc.h>#include <conio.h>#include<stdlib.h>#define MaxSize 100typedef char ElemType;typedef struct node{ElemType data;//数据元素struct node *lchild; //指向左孩子struct node *rchild; //指向右孩子} BTNode;void CreateBTNode(BTNode *&b,char *str)//创建二叉树{BTNode *st[MaxSize],*p=NULL;//BTNode *st[MaxSize]定义了一个栈,以栈的方式来实现二叉树元素的录入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;}}}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);}}}}int nodes(BTNode *b){int num1,num2;if(b==NULL)//原错误语句:b->data==NULL{return 0;}else{num1=nodes(b->lchild);num2=nodes(b->rchild);return (num1+num2+1);}}int yezinodes(BTNode *b)//叶子结点个数{int num1,num2;if(b==NULL){return 0;}else{if(b->lchild==NULL&&b->rchild==NULL){return 1;}else{num1=yezinodes(b->lchild);num2=yezinodes(b->rchild);return(num1+num2);}}}void parent(BTNode *b,ElemType x)//查找双亲{BTNode *t;if(b==NULL){return;}else{if(b->data==x){printf("此结点是根结点,无双亲!\n");return;}else{if(b->lchild!=NULL&&b->lchild->data==x||b->rchild!=NULL&&b->rchild->data==x) {t=b;printf("此结点的双亲为:%c\n",t->data);return;}else{parent(b->lchild,x);parent(b->rchild,x);}}}}void BTreeChange(BTNode *&b)//交换左右孩子算法{BTNode *p;if(b==NULL){return;}else{if(b->lchild==NULL&&b->rchild==NULL){return ;}else{p=b->lchild;b->lchild=b->rchild;b->rchild=p;BTreeChange(b->lchild);BTreeChange(b->rchild);}}}BTNode *LchildNode(BTNode *p)//找左孩子结点问题:这边的函数该如何引用{return p->lchild;}BTNode *RchildNode(BTNode *p)//找右孩子结点{return p->rchild;}int BTNodeHeight(BTNode *b)//求树的高度{int lchild,rchild;if(b==NULL){return (0);}else{lchild=BTNodeHeight(b->lchild);rchild=BTNodeHeight(b->rchild);return (lchild>rchild)?(lchild+1):(rchild+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(")");}}}void PreOrder(BTNode *b, int i)//前序遍历{if(b!=NULL){printf("%c %d \n",b->data,i);PreOrder(b->lchild,i+1);PreOrder(b->rchild,i+1);}}void InOrder(BTNode *b)//中序遍历{if(b!=NULL){InOrder(b->lchild);printf("%c",b->data);InOrder(b->rchild);}}void PostOrder(BTNode *b)//后序遍历{if(b!=NULL){PostOrder(b->lchild);PostOrder(b->rchild);printf("%c",b->data);}}void main(){char cc[]={"A(B(D(,G)),C(E,F))"};BTNode *b;BTNode *q;BTNode *t;char c;int p;printf("创建二叉树!\n");CreateBTNode(b,cc); //CreateBTNode函数用于根据括号表示法构建二叉链表,此函数在实验指导书上printf("创建二叉树成功!\n");printf("1.二叉树的括号表示法为:\n");DispBTNode(b);printf("\n");p=BTNodeHeight(b);printf("2.二叉树的深度为:%d\n",p);printf("3.二叉树的结点总数为:%d\n",nodes(b));printf("4.二叉树的叶子结点个数为:%d\n",yezinodes(b));printf("5.请输入一个结点:\n");scanf("%c",&c);t=findNode(b,c);if(t==NULL){printf("二叉树为空!\n");}else{if(t->lchild!=NULL){printf("此结点的左孩子是:%c\n",LchildNode(t)->data);}else{printf("此结点的左孩子不存在!\n");}if(t->rchild!=NULL){printf("此结点的右孩子是:%c\n",RchildNode(t)->data);}else{printf("此结点的右孩子不存在!\n");}}parent(b,c);printf("\n");printf("6.二叉树的前序遍历为:\n");PreOrder(b,0);printf("\n");printf("7.二叉树的中序遍历为:\n");InOrder(b);printf("\n");printf("8.二叉树的后序遍历为:\n");PostOrder(b);printf("\n");BTreeChange(b);printf("交换后的二叉树输出如下:\n");DispBTNode(b);printf("\n");}。

二叉树中所有节点左右字数节点的交换及遍历

二叉树中所有节点左右字数节点的交换及遍历

二叉树中所有节点的左右子树相互交换递归与非递归程序(2006-10-11 11:24:09)转载分类:数据结构//将二叉树中所有节点的左右子树相互交换BiNode* Exchange(BiNode* T){BiNode* p;if(NULL==T || (NULL==T->lchild && NULL==T->rchild)) return T;p = T->lchild;T->lchild = T->rchild;T->rchild = p;if(T->lchild){T->lchild = Exchange(T->lchild);}if(T->rchild){T->rchild = Exchange(T->rchild);}return T;}//将二叉树中所有节点的左右子树相互交换//不使用递归void NonRecursive_Exchange(BiNode* T){Stack s;BiNode* p;if(NULL==T)return;InitStack(&s);Push(&s,T);while(!isEmpty(&s)){T = Pop(&s);p = T->lchild;T->lchild = T->rchild;T->rchild = p;if(T->rchild)Push(&s,T->rchild);if(T->lchild)Push(&s,T->lchild); }DestroyStack(&s);}//递推形式的前续遍历,不使用递归和堆栈,//但每个节点增加了一个parent指针和Mark标记void Iteration_Mark_PreOrderTraverse(BiPMNode* T) {if(NULL == T)return;while(NULL != T){if(0 == T->mark){T->mark ++;printf("%d ",T->data);while(NULL != T->lchild){T = T->lchild;T->mark ++;printf("%d ",T->data);}T->mark ++;if(NULL != T->rchild)T = T->rchild;continue;}if(1 == T->mark){T->mark ++;if(NULL != T->rchild)T = T->rchild;continue;}if(2 == T->mark){T = T->parent;}}}//递推形式的中续遍历,不使用递归和堆栈,//但每个节点增加了一个parent指针和Mark标记void Iteration_Mark_InOrderTraverse(BiPMNode* T) {if(NULL == T)return;while(NULL != T){if(0 == T->mark){T->mark ++;while(NULL != T->lchild){T = T->lchild;T->mark ++;}printf("%d ",T->data);T->mark ++;if(NULL != T->rchild)T = T->rchild;continue;}if(1 == T->mark){printf("%d ",T->data);T->mark ++;if(NULL != T->rchild)T = T->rchild;continue;}if(2 == T->mark){T = T->parent;}}}//递推形式的后续遍历,不使用递归和堆栈,//但每个节点增加了一个parent指针和Mark标记void Iteration_Mark_PostOrderTraverse(BiPMNode* T) {if(NULL == T)return;while(NULL != T){if(0 == T->mark){T->mark ++;while(NULL != T->lchild){T = T->lchild;T->mark ++;}T->mark ++;if(NULL != T->rchild)T = T->rchild;continue;}if(1 == T->mark){T->mark ++;if(NULL != T->rchild)T = T->rchild;continue;}if(2 == T->mark){printf("%d ",T->data);T = T->parent;}}}二叉树层次遍历(2006-10-10 11:12:31)转载分类:数据结构//二叉树的层次遍历,使用队列实现void LayerOrderTraverse(BiNode* T) {Queue q;if(NULL == T)return;InitQueue(&q);EnQueue(&q,T);while(!isQueueEmpty(&q)){T = DeQueue(&q);printf("%d ",T->data);if(T->lchild)EnQueue(&q,T->lchild);if(T->rchild)EnQueue(&q,T->rchild);}DestroyQueue(&q);}typedef struct _QNode{BiNode* data;struct _QNode* next;}QNode;typedef struct _queue{QNode* front;QNode* rear;}Queue;void InitQueue(Queue* q){q->front = q->rear = (QNode*)malloc(sizeof(QNode)); q->front->next = NULL;}bool isQueueEmpty(Queue* q){if(q->front == q->rear)return true;elsereturn false;}void EnQueue(Queue* q, BiNode* data){QNode* pNode;pNode = (QNode*)malloc(sizeof(QNode));pNode->data = data; pNode->next = NULL;q->rear->next = pNode;q->rear = pNode;}BiNode* DeQueue(Queue* q){QNode* pNode;BiNode* pData;assert(q->front != q->rear); pNode = q->front->next;q->front->next = pNode->next; if(q->rear == pNode){q->rear = q->front;}pData = pNode->data;free(pNode);return pData;}void DestroyQueue(Queue* q) {while(NULL != q->front){q->rear = q->front->next;free(q->front);q->front = q->rear;}}二叉排序树-创建(2006-10-10 10:05:04)转载分类:数据结构typedef struct BiNode{int data;struct BiNode *lchild;struct BiNode *rchild;}BiNode;BiNode* Insert(BiNode* T, int data){if(NULL == T){T = (BiNode*)malloc(sizeof(BiNode));T->data = data;T->lchild = NULL;T->rchild = NULL;return T;}if(data <= T->data)T->lchild = Insert(T->lchild, data);elseT->rchild = Insert(T->rchild, data);return T;}//创建一个二叉排序树, input -1 to endBiNode* createBiSortTree(){BiNode *root = NULL;int data;while(1){scanf("%d",&data);if(-1 == data)break;root = Insert(root, data);}return root;}查看文章交换二叉树所有节点的左右子树2010-12-03 21:44//实验题目:已知二叉树以二叉链表作为存储结构,写一个算法来交换二叉树的所有节点的左右子树//先建立二叉树的二叉链表存储结构,再完成算法,注意结果的输出形式#include <stdio.h>#include <malloc.h>#include <windows.h>#define STACK_INIT_SIZE 100;#define STACKINCREMENT 10;//定义二叉树数据类型typedef char TElemtype;typedef struct BiTNode{TElemtype data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;//-------二叉树基本操作-------//初始化二叉树bool InitBiTree(BiTree &T){T=(BiTree)malloc(sizeof(BiTNode));T->data=NULL;T->lchild=NULL;T->rchild=NULL;return true;}//创建二叉树void CreateBiTree(BiTree &T){TElemtype c=' ';c=getchar();getchar();if(c==' '){T=NULL;}else{InitBiTree(T);T->data=c;CreateBiTree(T->lchild);CreateBiTree(T->rchild); }}//操作函数---输出bool Visit(TElemtype e){if(e!=NULL){printf("%c ",e);return true;}else{return false;}//先序遍历二叉树bool PreOrderTraverse(BiTree T,bool Visit(TElemtype)) {if(T){if(Visit(T->data)){if (PreOrderTraverse(T->lchild,Visit)){if (PreOrderTraverse(T->rchild,Visit)){return true;}}}return false;}else{return true;}}//----------------------------//定义栈的数据类型typedef struct{TElemtype *base;TElemtype *top;int stacksize;}SqStack;//交换左右子树void exchange(BiTree &rt){BiTree temp = NULL;if(rt->lchild == NULL && rt->rchild == NULL)return;else{temp = rt->lchild;rt->lchild = rt->rchild;rt->rchild = temp;}if(rt->lchild)exchange(rt->lchild);if(rt->rchild)exchange(rt->rchild);}//-------Main函数----void main(){BiTree T;MessageBox(NULL,"请按照先序遍历输入二叉树!","提示",MB_OK|MB_ICONWARNING); MessageBox(NULL,"请输入数据!(空格表示结束)","提示",MB_OK|MB_ICONWARNING); CreateBiTree(T);MessageBox(NULL,"输入结束!","提示",MB_OK|MB_ICONWARNING);printf("\n按先序输出\n");PreOrderTraverse(T,Visit);MessageBox(NULL,"输出结束!","提示",MB_OK|MB_ICONWARNING);printf("\n交换后\n");exchange(T);PreOrderTraverse(T,Visit);}二叉树左右子树交换(麻烦)/*对任意一颗二叉树,是将其说有结点的左右子树交换,并将交换前后不同二叉树分别用层序、前序,中序三种不同的方法进行遍历。

『NOIP2018普及组题解』

『NOIP2018普及组题解』

『NOIP2018普及组题解』<更新提⽰><第⼀次更新><正⽂>标题统计题⽬描述凯凯刚写了⼀篇美妙的作⽂,请问这篇作⽂的标题中有多少个字符?注意:标题中可能包含⼤、⼩写英⽂字母、数字字符、空格和换⾏符。

统计标题字符数时,空格和换⾏符不计算在内。

输⼊格式输⼊⽂件只有⼀⾏,⼀个字符串 s。

输出格式输出⽂件只有⼀⾏,包含⼀个整数,即作⽂标题的字符数(不含空格和换⾏符)。

样例数据input1234output13input2Ca 45output24样例说明样例 1 :标题中共有 3 个字符,这 3 个字符都是数字字符。

样例 2 :标题中共有 5 个字符,包括 1 个⼤写英⽂字母, 1 个⼩写英⽂字母和 2 个数字字符,还有 1 个空格。

由于空格不计⼊结果中,故标题的有效字符数为 4 个。

数据规模与约定规定∣s∣表⽰字符串 s 的长度(即字符串中的字符和空格数)。

对于 %40 的数据,1 ≤ |s| ≤ 5,保证输⼊为数字字符及⾏末换⾏符。

对于 %80 的数据,1 ≤ |s| ≤ 5,输⼊只可能包含⼤、⼩写英⽂字母、数字字符及⾏末换⾏符。

对于 %100 的数据,1 ≤ |s| ≤ 5,输⼊可能包含⼤、⼩写英⽂字母、数字字符、空格和⾏末换⾏符。

时间限制:1s空间限制:256MB解析T1和往年⼀样,还是签到题。

不过这⼀次好像更注重考察语⾔了,不少不熟悉语⾔的⼩伙伴可能就没有分了啦。

⼤概是考察如何处理输⼊吧,会⽤getline()的基本都⽤了getline()了吧,当然,不会⽤的还有其他的办法,主要是while(cin>>str)和scanf()读到换⾏符为⽌。

这样的话,只要暴⼒统计⼀下就可以了啦。

Code:#include<bits/stdc++.h>using namespace std;string s;int ans=0;int main(void){freopen("title.in","r",stdin);freopen("title.out","w",stdout);getline(cin,s);for(int i=0;i<s.size();i++){if(s[i]!=' ')ans++;}printf("%d\n",ans);return 0;}#include<bits/stdc++.h>using namespace std;char s;int ans=0;int main(){freopen("title.in","r",stdin);freopen("title.out","w",stdout);while (cin>>s){if(s>='0'&&s<='9'||s>='a'&&s<='z'||s>='A'&&s<='Z')ans++;}cout<<ans<<endl;return 0;}龙虎⽃题⽬描述轩轩和凯凯正在玩⼀款叫《龙虎⽃》的游戏,游戏的棋盘是⼀条线段,线段上有 n个兵营(⾃左⾄右编号 1 ∼n),相邻编号的兵营之间相隔1 厘⽶,即棋盘为长度为 n-1 厘⽶的线段。

c交换左右子树的算法非递归

c交换左右子树的算法非递归

c交换左右子树的算法非递归前言:本文旨在介绍一种非递归的交换左右子树的算法,通过该算法,可以在C语言中实现树结构的左右子树交换操作。

树是一种常见的数据结构,广泛应用于计算机科学中,而交换左右子树是树操作中的一种常见操作。

本文将详细介绍该算法的实现过程和代码示例。

一、算法描述:非递归交换左右子树算法的基本思路是使用栈来模拟递归过程。

首先,将根节点入栈,同时将根节点的左子树和右子树分别压入另一个栈中。

然后,依次弹出左子树和右子树的节点,并交换它们的左右子节点。

当所有节点都被弹出后,再将根节点从另一个栈中弹出,并交换其左右子树。

二、代码实现:以下是一个基于上述算法的C语言代码实现示例:```c#include <stdio.h>#include <stdlib.h>// 定义树节点结构体typedef struct TreeNode {int val;struct TreeNode* left;struct TreeNode* right;} TreeNode;// 非递归交换左右子树函数void swap_subtrees(TreeNode* root) {// 创建一个空栈来模拟递归过程TreeNode* stack[100];int top = -1;stack[++top] = root; // 将根节点入栈while (top >= 0) {TreeNode* node = stack[top--]; // 弹出当前节点if (node->left) { // 如果当前节点有左子树,将其压入另一个栈中stack[++top] = node->left;}if (node->right) { // 如果当前节点有右子树,将其压入另一个栈中stack[++top] = node->right;}}// 交换左右子树TreeNode* temp = root->left; // 保存当前节点的左子树root->left = root->right; // 交换当前节点的左右子树root->right = temp; // 将保存的左子树重新赋值给当前节点的右子树}```三、使用示例:以下是一个简单的使用示例,展示如何使用上述代码实现交换左右子树的操作:```cint main() {// 创建一棵二叉树并初始化数据TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));root->val = 1;root->left = (TreeNode*)malloc(sizeof(TreeNode));root->left->val = 2;root->right = (TreeNode*)malloc(sizeof(TreeNode));root->right->val = 3;root->left->left = NULL; // 左子树为空树结构root->right->right = NULL; // 右子树为空树结构// 交换左右子树并输出结果swap_subtrees(root);printf("交换后的二叉树为:\n");print_tree(root); // 输出二叉树结构,以验证交换结果是否正确return 0;}```四、总结:本文介绍了非递归的交换左右子树的算法,并给出了相应的C语言代码实现示例。

交换左右子树

交换左右子树

交换左右⼦树可能编译时会有些语法⼩错误(⽐如分号,->,等),很容易就⾃⼰纠正了哦,思路绝对是完全正确的,所以⽤的话就⾃⼰试着改改吧,直接复制粘贴,就正确,岂不是太没写代码体验了,⾃⼰改改才印象更加深刻的呢(▽)~~~~;交换左右⼦树//算法5.5 计算⼆叉树的深度,增加左右⼦数交换等功能#include<iostream>using namespace std;//⼆叉树的⼆叉链表存储表⽰typedef struct BiNode{char data; //结点数据域struct BiNode *lchild,*rchild; //左右孩⼦指针}BiTNode,*BiTree;//⽤算法5.3建⽴⼆叉链表void CreateBiTree(BiTree &T){//按先序次序输⼊⼆叉树中结点的值(⼀个字符),创建⼆叉链表表⽰的⼆叉树Tchar ch;cin >> ch;if(ch=='#') T=NULL; //递归结束,建空树else{T=new BiTNode;T->data=ch; //⽣成根结点CreateBiTree(T->lchild); //递归创建左⼦树CreateBiTree(T->rchild); //递归创建右⼦树} //else} //CreateBiTreeint Depth(BiTree T){int m,n;if(T == NULL ) return 0; //如果是空树,深度为0,递归结束else{m=Depth(T->lchild); //递归计算左⼦树的深度记为mn=Depth(T->rchild); //递归计算右⼦树的深度记为nif(m>n) return(m+1); //⼆叉树的深度为m 与n的较⼤者加1else return (n+1);}}void InOrderTraverse(BiTree T){//中序遍历⼆叉树T的递归算法if(T){InOrderTraverse(T->lchild);cout << T->data;InOrderTraverse(T->rchild);}}void inChangeLR(BiTree &T){BiTree temp;if(T){if(T->lchild==NULL&&T->rchild==NULL){return;} else{temp=T->lchild;T->lchild = T->rchild;T->rchild=temp;}inChangeLR(T->lchild);inChangeLR(T->rchild);}}void preChangeLR(BiTree &T){BiTree temp;if(T){inChangeLR(T->lchild);if(T->lchild==NULL&&T->rchild==NULL){return;} else{temp=T->lchild;T->lchild = T->rchild;T->rchild=temp;}inChangeLR(T->rchild);}}void postChangeLR(BiTree &T){BiTree temp;if(T){inChangeLR(T->lchild);inChangeLR(T->rchild);if(T->lchild==NULL&&T->rchild==NULL){ return;} else{temp=T->lchild;T->lchild = T->rchild;T->rchild=temp;}}}int main(){BiTree tree;cout<<"请输⼊建⽴⼆叉链表的序列:\n";CreateBiTree(tree);InOrderTraverse(tree);cout<<"数的深度为:"<<Depth(tree)<<endl; cout<<"中序遍历的结果为:\n";InOrderTraverse(tree);cout<<"\n";//以下三种执⾏其中⼀种cout<<"交换后中序遍历的结果为:\n";inChangeLR(tree);InOrderTraverse(tree);cout<<"\n";cout<<"交换后前序序遍历的结果为:\n";preChangeLR(tree);InOrderTraverse(tree);cout<<"\n";cout<<"交换后后序遍历的结果为:\n";postChangeLR(tree);InOrderTraverse(tree);return 0;}。

5-21交换二叉树 西电

5-21交换二叉树 西电

//交换左右子树的程序代码#include<stdio.h>#include<malloc.h>//二叉链表的结构类型定义const int maxsize=1024;typedef char datatype;typedef struct node{datatype data;struct node *lchild,*rchild;}bitree;bitree*creattree();void preorder(bitree*);void swap(bitree*);void main(){bitree*pb;pb=creattree();preorder(pb);printf("\n");swap(pb);preorder(pb);printf("\n");}//二叉树的建立bitree*creattree(){char ch;bitree*Q[maxsize];int front,rear;bitree*root,*s;root=NULL;front=1;rear=0;printf("按层次输入二叉树,虚结点输入'@',以'#'结束输入:\n");while((ch=getchar())!='#'){s=NULL;if(ch!='@'){s=(bitree*)malloc(sizeof(bitree));s->data=ch;s->lchild=NULL;s->rchild=NULL;}rear++;Q[rear]=s;if(rear==1)root=s;else{if(s&&Q[front])if(rear%2==0)Q[front]->lchild=s;else Q[front]->rchild=s;if(rear%2==1)front++;}}return root;}//先序遍历按层次输出二叉树void preorder(bitree*p){if(p!=NULL){printf("%c",p->data);if(p->lchild!=NULL||p->rchild!=NULL){printf("(");preorder(p->lchild);if(p->rchild!=NULL)printf(",");preorder(p->rchild);printf(")");}}}//交换左右子树void swap(bitree*p){bitree*t;if(p!=NULL){if(p->lchild!=NULL&&p->rchild!=NULL&&p->lchild->data>p->rchild->data){t=p->lchild;p->lchild=p->rchild;p->rchild=t;}swap(p->lchild);swap(p->rchild);}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实现二叉树中所有节点左右子树的交换IMB standardization office【IMB 5AB- IMBK 08- IMB 2C】数据结构课程设计实验报告题目名称:实现二叉树中所有节点左右子树的交换学院:信息科学与工程学院专业班级:计算机科学与技术1003班姓名:叶成功学号:指导教师:陈国良教授李立三教授日期:2012年7月3日目录一、问题描述二叉树是一种常见的特殊的树型结构,在计算机领域有着极为广泛的应用。

在二叉树的一些应用中,常常要求在树中查找具有某些特征的结点或者对树中全部结点逐一进行某种处理,这就提出了遍历二叉树。

根据遍历的方向的不同,有前序遍历、中序遍历、后序遍历以及层序遍历。

在本次课程设计中,要求学生通过编写程序完成对二叉树的一些操作,比如可以构造二叉树、打印二叉树、遍历二叉树以及对左右子树进行交换等等。

二、基本要求要求:。

构造一颗20个节点的完全二叉树或者20个节点以上的满二叉树。

实现如下步骤:(1)实现二叉树的构造过程,并打印出二叉树(2)对该二叉树分别用层序、前序、中序和后序四种不同的方法进行遍历;(3)将该二叉树的所有左右子树进行交换,得到新的二叉树,并打印出该二叉树;(4)对新获得的二叉树分别用层序、前序、中序和后序四种不同的方法进行遍历。

三、数据结构的设计由数据结构中二叉树的定义可知,二叉树的结点由一个数据元素和分别指向其左、右子树的两个分支构成,所以在本程序二叉树的构造是采用二叉链表的链式存储结构,链表中的结点应包含三个域:数据域和左、右孩子的指针域。

这种存储结构可以方便二叉树的建立以及遍历。

1、结点的数据结构structnode{chardata;structnode*lchild,*rchild;}2、基本操作voidCreate(BiTNode**p)初始条件:按照结点的结构体构造二叉树;操作结果:构造一棵二叉树。

voidPreOrderTraverse(BiTreeT)初始条件:二叉树T存在;操作结果:按照前序遍历方法遍历二叉树。

voidInOrderTraverse(BiTreeT)初始条件:二叉树T存在;操作结果:按照中序遍历方法遍历二叉树。

voidPostOrderTraverse(BiTreeT)初始条件:二叉树T存在;操作结果:按照后序遍历方法遍历二叉树。

voidLevelOrderTraverse(BiTreeT)初始条件:二叉树T存在;操作结果:按照层序遍历方法遍历二叉树。

voidSwapChild(BiTNode**p)初始条件:二叉树存在且交换的结点有子树;操作结果:将二叉树左右结点交换。

voidPaint(BiTreeT)初始条件:二叉树T存在;操作结果:将二叉树的结点打印出来。

四、软件模块结构图五、程序设计思想1、程序设计基本思想(1)本实验要求编写一个程序实现对二叉树的各种基本操作,并以此为目的设计一个程序,完成如下功能:1、输入二叉树的先序序列字符,建立二叉链表。

注意:输入时,必须加入虚结点以示空指针的位置;假设虚结点输入时用空格字符表示。

2、打印二叉树。

3、按先序、中序、后序和层序三种不同方法遍历二叉树。

4、交换二叉树的所有左右子树。

5、打印二叉树,并且分别按照先序、中序、后序和层序三种不同方法遍历二叉树。

6、在设计一个简单的菜单,分别调试上述算法。

7、编写主程序完成各功能的调用和实现。

(2)测试数据:1、按照先序序列依次输入字符。

2、打印二叉树并且按先序、中序和后序遍历二叉树并输出遍历结果。

3、输出交换二叉树的左右子树并且打印二叉树并且按先序、中序和后序遍历二叉树并输出遍历结果。

2、程序设计基本思想本程序含有7个函数;①主函数main()②前序遍历二叉树PreOrderTraverse(T,PrintChar)③中序遍历二叉树Inorder(T)④后续遍历二叉树Postorder(T)⑤层序遍历二叉树LevelOrderTraverse(T)⑥打印二叉树Paint(T)⑦交换二叉树所有左右子树SwapChild(T)六、程序流程图1、创建函数chare;e=getchar();if(e=='*')(*p)=NULL;else{if(!((*p)=(BiTree)malloc(sizeof(BiTNode)))){printf("分配失败\n");exit(0);}(*p)->data=e;Create(&((*p)->lchild));Create(&((*p)->rchild));}}2、前序遍历函数Y{if(T) { printf("%c",T->data); PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild);} }3、中序遍历函数Y{if(T) {InOrderTraverse(T->lchild);printf("%c",T->data); InOrderTraverse(T->rchild);} }4、后序遍历函数N{if(T) { PostOrderTraverse(T->lchild); PostOrderTraverse(T->rchild); printf("%c",T->data);} }5、层序遍历函数voidLevelOrderTraverse(BiTreeT) {BiTreeQ[MaxLength]; intfront=0,rear=0;printf("----------------------------------\n"); printf("你的选择:");printf("4.交换左右子树\n");printf("0.退出\n");printf("----------------------------------\n");printf("你的选择:");scanf("%d",choice);getchar();R S T序.后序递归算法的复杂度是相同的,递归算法非常的简单。

例如先序先访问跟节点,然后访问左节点,再访问右节点。

仔细看一下递归程序,就会发现,其实每次都是子树的左子树(lchild),直到左子树为空,然后开始从递归的最深处返回,然后开始恢复递归现场,访问右子树。

其实过程很简单:一直往左走root->lchild->lchild->lchild...->null,由于是先序遍历,因此一遇到节点,便需要立即访问;由于一直走到最左边后,需要逐步返回到父节点访问右节点,时间方面每个节点调用一次函数,访问一次,是O(n).没有空间开销,所以是0.中序.后序递归算法同先序一样。

时间复杂度是O(n),空间复杂度是0.同理可知中序与后序也是一样的。

非递归层序遍历有不一样。

层序遍历中每次将节点压入队,然后弹出,再让左子树入队,再让右子树入队,在遍历过程中,左右子树依次入队出队。

时间复杂度O(n),空间复杂度为0。

问题一:前序遍历、中序遍历以及后序遍历为递归算法很简单就没什么可说的了,而层次遍历就需要用到队列处理稍微复杂一点。

创建二叉树时,要求二叉树内容可以是各种形式,刚开始编创建算法的时候调试总是出错,后来经过参考数据结构相关资料才发现有一个地方少写一行申请空间的代码。

问题二:非递归算法在编程时都是不很顺利,其中层序遍历有点难,需要掌握队列的知识,但是经过我不懈努力,最终成功的解决了这个问题。

问题三:要注意输入必要的头文件,比如调用malloc需要的头文件,否者编译出错,有时不知道头文件可以查询书本。

问题四:在这次课程设计中其实主要问题就是编程完成后会有很多小错误。

所以需要耐心调试算法的改进设想:我没有想到更好的算法,我想到的最好的算法编出的C语言程序代码只有100多行,但是可以非常成功的解决了问题。

我认为我的算法应该算是最简洁的算法了。

九、数据测试数据测试主要是由截图来说明,编译成功后,按照前序遍历的方法输入子树,空子树用*表示,在本程序中输入的是一个有二十个结点的二叉树,输入ABDHP**Q**IR**S**EJT***K**CFL**M**GN**O**,则构成一棵拥有二十个结点的完全二叉树,如图:R S T输入二叉树后,分别调用打印函数、前序遍历函数、中序遍历函数、后序遍历函数以及层次遍历函数,在功能实现后。

调换二叉树所有的左右子树,再分别调用打印函数、前序遍历函数、中序遍历函数、后序遍历函数以及层次遍历函数。

所有功能都实现后,退出程序。

程序运行中的截图如下所示。

1、主菜单界面2、建立一棵有二十个结点的完全二叉树3、打印二叉树4、遍历二叉树5、二叉树左右子树交换6、交换后打印二叉树7、交换后二叉树的遍历8、退出程序十、用户使用手册十一、心得体会为期两周的课程设计结束了,在这次的课程设计中我们将抽象的数据结构理论知识与大一所学的C语言相结合,完成了这次课程设计。

在完成这个课程设计的过程中,从问题分析、程序设计以及程序调试每个环节都必须要做到完美,因为这几环都是环环相扣的,只有在前一环做好的情况下才能完好的做第二步课程设计是我们专业课程知识综合应用的实践训练,着是我们迈向社会,从事职业工作前一个必不少的过程.”千里之行始于足下”,通过这次课程设计,我深深体会到这句千古名言的真正含义.我今天认真的进行课程设计,学会脚踏实地迈开这一步,就是为明天能稳健地在社会大潮中奔跑打下坚实的基础.通过这次程序设计,我在许多方面都有所提高。

通过这次课程设计,综合运用本专业所学课程:数据结构与C语言程序的理论知识,同时也将相关的理论知识都有了全面的复习,独立思考的能力也有了提高。

在这次设计过程中,体现出自己单独设计程序的能力以及综合运用知识的能力,体会了学以致用、突出自己劳动成果的喜悦心情,从中发现自己平时学习的不足和薄弱环节,从而加以弥补。

在此感谢我们的所有的课程设计的指导老师.,老师严谨细致、一丝不苟的作风一直是我工作、学习中的榜样;老师循循善诱的教导和不拘一格的思路给予我无尽的启迪;这次课程设计中遇到了各种各样的困难,有些不能自己解决的都得到老师您的细心指导。

而您开朗的个性和宽容的态度,也帮助我能够很顺利的完成了这次课程设计。

同时感谢对我帮助过的同学们,谢谢你们对我的帮助和支持,让我感受到同学的友谊。

相关文档
最新文档