1. 二叉树的存储结构是怎样的有哪些类型的存储结构对应的c语言描述是
线性表的链式存储结构:
typedef
int
elemtype;
typedef
struct
lnode
{
elemtype
data;
struct
lnode
*next;
}lnode,*linklist;
(被封装好的每个节点,都有一个数据域data和一个指针域*next用于指向下一个节点)
二叉树的二叉链表:
typedef
int
telemtype;
typedef
struct
bitnode
{
telemtype
data;
struct
bitnode
*lchild,*rchild;
}bitnode,*bitree;
(被封装好的每个节点,都有一个数据域data和两个指针域
*lchild,*rchild分别指向左右子树)
需要什么类型的数据作为数据域可更改,或者typedef
int
elemtype;和typedef
int
telemtype;中的int,比如改为char、float等或者自定义数据类型。
2. 以二叉链表为存储结构,写一算法交换各结点的左右子树
问题:以二叉链表为存储结构, 写一算法交换各结点的左右子树核弯。
答案:
要交换各结点的左右子树,最方便的办法是用后序遍历算法,每访问一个结点时把两棵子树的指针进行交换,最后一次访问是交换根结点的子树。
void ChangeBinTree(BinTree *T)
{ //交换子树
if(*T)
{ //这里孝模以指针为参数使得交换在实参的结点上进巧氏缓行后序遍历
BinTree temp;
ChangeBinTree(&(*T)->lchild);
ChangeBinTree(&(*T)->rchild);
temp=(*T)->lchild;
(*T)->lchild=(*T)->rchild;
(*T)->rchild=temp;
}
}
3. 分别写出线性表的链式存储结构、二叉树的二叉链表存储机构的类C语言描述
线性表的链式存储结构:
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
(被封装好的每个节点,都有一个数据域data和一个指针域*next用于指向下一个节点)
二叉树的二叉链表:
typedef int TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
(被封装好的每个节点,都有一个数据域data和两个指针域 *lchild,*rchild分别指向左右子树)
需要什么类型的数据作为数据域可更改,或者typedef int ElemType;和typedef int TElemType;中的int,比如改为char、float等或者自定义数据类型。
4. 二叉链表作存储结构
//偶尔看到提问,翻了翻以前的课程设计,大部分功能类似...就直接复制上来啦,不知道能帮上忙不...都这么久了
//vc++ 6.0
#include "iostream.h"
#include "stdlib.h"
#include "stdio.h"
#define OK 1
#define NULL 0
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef char ElemType;//定义二叉树结点值的类型为字符型
const int MaxLength=10;//结点个数不超过10个
typedef struct BTNode{
ElemType data;
struct BTNode *lchild,*rchild;
}BTNode,* BiTree;
void CreateBiTree(BiTree &T){//按先序次序输入,构造二叉链表表示的二叉树T,空格表示空树
char ch;
ch=getchar(); //不能用cin来输入,在cin中不能识别空格。
if(ch==' ') T=NULL;
else
{
if(!(T=(BTNode *)malloc(sizeof(BTNode)))) cout<<"malloc fail!";
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T){//先序遍历
if(T){
cout<<T->data<<' ';
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T){ //中序遍历
if(T){
InOrderTraverse(T->激渣做lchild);
cout<<T->data<<' ';
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T){ //后序遍历
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout<<T->data<<' ';
}
}
void LevelOrderTraverse(BiTree T){ //层序遍历
BiTree Q[MaxLength];
int front=0,rear=0;
BiTree p;
if(T){ //根梁岁结点入队
Q[rear]=T;
rear=(rear+1)%MaxLength;
}
while(front!=rear){
p=Q[front]; //队头元素出队
front=(front+1)%MaxLength;
cout<<p->data<<' ';
if(p->lchild){ //左孩明衡子不为空,入队
Q[rear]=p->lchild;
rear=(rear+1)%MaxLength;
}
if(p->rchild){ //右孩子不为空,入队
Q[rear]=p->rchild;
rear=(rear+1)%MaxLength;
}
}
}
int BTDepth(BiTree T){ //二叉树的深度
if(!T) return 0;
else{
int h1=BTDepth(T->lchild);
int h2=BTDepth(T->rchild);
if(h1>h2) return h1+1;
else return h2+1;
}
}
int Leaf(BiTree T){ //二叉树的叶子数
if(!T)
return 0;
else if(!T->lchild&&!T->rchild)
return 1;
else
return(Leaf(T->lchild)+Leaf(T->rchild));
}
int NodeCount(BiTree T){ //二叉树的结点总数
if(!T)
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
int Initbitree (BiTree T) //空树
{
T=NULL;
return FALSE;
}
int Isempty(BiTree T) //判断为空否
{
if(T!=NULL)
return FALSE;
else
return TRUE;
}
int Destroy (BiTree &T) //销毁
{
if( T != NULL )
{ if(T->lchild!=NULL)
Destroy ( T->lchild );
if(T->rchild!=NULL)
Destroy ( T->rchild );
free(T);
T=NULL;
}
return 1;
}
char Root(BiTree T) //返回根节点
{
if(T==NULL)
return NULL;
else
return T->data;
}
ElemType Value(BiTree &p)
{//返回P所指结点的值
return p->data;
}
ElemType Assign(BiTree p,ElemType value)
{ //给P的结点赋新值
return p->data=value;
}
BiTree Parent(BiTree T, BiTree p)//返回父节点
{
if(T!=NULL)
{
if(T->lchild->data==p->data)
{return T;}
if(T->rchild->data==p->data)
return T;
if(T->lchild)
return Parent(T->lchild,p);
if(T->rchild)
return Parent(T->rchild,p);
}
else return NULL;
}
char LeftChild(BiTree p) //返回p的左孩子的值
{
if(p->lchild) //若p存在左孩子
return p->lchild->data;
if(p->lchild==NULL)
return NULL;
}
char RightChild(BiTree p) // 返回p的右孩子的值
{
if(p->rchild)
return p->rchild->data;
if(p->rchild==NULL)
return NULL;
}
int Deletelchild(BiTree p) //删除此二叉树中p节点的左子树
{
if(p)
{
Destroy(p->lchild);
return OK;
}
return ERROR;
}
int Deleterchild(BiTree p) //删除此二叉树中p节点的右子树
{
if(p)
{
Destroy(p->rchild);
return OK;
}
return ERROR;
}
void search(BiTree T,char h,BiTree &p)//查询节点
{
if(T==NULL)
return ;
else{
if(T->data==h)p=T;
search(T->lchild,h,p);
search(T->rchild,h,p);
}
}
void main()
{
BiTree T;
BiTree p;
BiTree q;
char ch;
T=NULL;
int select;
while(1){
cout<<"\n\n";
cout<<"**********************************\n";
cout<<"1.创建二叉树\n";
cout<<"2.前序递归遍历序列\n";
cout<<" 中序递归遍历序列\n";
cout<<" 后序递归遍历序列\n";
cout<<"3.层次遍历序列\n";
cout<<"4.二叉树的深度\n";
cout<<"5.叶子结点数目\n";
cout<<"6.求结点总数目\n";
cout<<"7.返回树根节点\n";
cout<<"8.返回节点p的左孩子\n";
cout<<" 返回节点p的右孩子\n";
cout<<" 返回节点p的 双亲\n";
cout<<"9.判断是否为空(是返回1,否返回0)\n";
cout<<"10.删除p节点的左子树\n";
cout<<"11.删除p节点的右子树\n";
cout<<"12.销毁树!\n";
cout<<"0.退出\n";
cout<<"**********************************\n";
cout<<"\n请选择要执行的操作(选择数字0-12):";
cin>>select;
switch(select){
case 0:
cout<<"退出!";
return;
case 1:
cout<<"请按先序次序输入各结点的值,以空格表示空节点:"<<endl;
CreateBiTree(T);
cout<<"成功!";
break;
case 2:
if(!T) cout<<"未建立树,请先建树!";
else{
cout<<"\n先序遍历:\n";
PreOrderTraverse(T);
cout<<"\n中序遍历:\n";
InOrderTraverse(T);
cout<<"\n后序遍历:\n";
PostOrderTraverse(T);
}
break;
case 3:
if(!T) cout<<"未建立树,请先建树!";
else{
cout<<"\n层序遍历:\n";
LevelOrderTraverse(T);
}
break;
case 4:
cout<<"二叉树的深度为:\n";
cout<<BTDepth(T);
break;
case 5:
cout<<"\n叶子节点数:\n";
cout<<Leaf(T);
break;
case 6:
cout<<"总节点数:\n";
cout<<NodeCount(T);
break;
case 7:
cout<<"返回根节点:"<<Root(T);
break;
case 8:
cout<<"\n请输入要查询的节点p值:";
cin>>ch;
search(T,ch,p);
cout<<ch<<"的左孩子是:"<<LeftChild(p)<<endl;
cout<<ch<<"的右孩子是:"<<RightChild(p)<<endl;
q=Parent(T,p);
cout<<ch<<"的父亲是:"<<Value(q)<<endl;
break;
case 9:
cout<<"判断是否为空(是为1,否为0:)"<<Isempty(T);
break;
case 10:
cout<<"\n请输入节点p值:";
cin>>ch;
search(T,ch,p);
cout<<Deletelchild( p);
cout<<"删除了"<<ch<<"的左孩子";
break;
case 11:
cout<<"\n请输入节点p值:";
cin>>ch;
search(T,ch,p);
cout<<Deleterchild( p);
cout<<"删除了"<<ch<<"的右孩子";
break;
case 12:
cout<<"销毁树!"<<Destroy(T);
break;
default:
cout<<"请确认选择项为数字1-12!\n";
}
}
}
5. 二叉链表存储结构,实现二叉树的遍历
前几天写的,输入二叉树的广义表形式,建立二叉树的链式存储。输出的是中序。有注释,看懂了应该其他的都能写了吧。#include<stdio.h>
#include<stdlib.h>
int n=0; //全局变量
struct tree //二叉树结构体
{
char data;
struct tree *lc;
struct tree *rc;
};
tree *creat(char a[]) //创建树的二叉树
{
tree *h;
h=(tree *)malloc(sizeof(tree));
h->lc=NULL;
h->rc=NULL;
if(a[n]!=')'&&a[n]!='('&&a[n]!=',') //当a[n]为字母存入a[]
{
h->data=a[n];
n++;
}
if(a[n]=='(') //a[n]为左括号对h->lc递归操作
{
n++;
h->lc=creat(a);
}
if(a[n]==',') //a[n]为逗号对h->rc递归操作
{
n++;
h->rc=creat(a);
return h;
}
if(a[n]==')') //a[n]为右括号返回h
{
n++;
return h;
}
else
return h;
}
void print(tree *h) //二叉树中序输出
{
if(h!=NULL)
{
print(h->lc);
printf("%c",h->data);
print(h->rc);
}
}
int high(char a[]) //判断树的高度
{
int i=0,max=0,p=0;
while(a[i]!=0)
{
if(a[i]=='(')
{
p++;
if(max<i)
max=p;
}
if(a[i]==')')
p--;
i++;
}
if(p!=0)
{
printf("左右括号数不等,输入错误\n"); //判断左右括号数是否相等
exit(1);
}
return max+1;
}
void main() //主函数
{
int i=0;
tree *h;
char a[50]={0};
gets(a);
while(a[i]!=0) //判断各种可能出现的输入错误
{
if(i==0&&(a[i]=='('||a[i]==')'||a[i]==',')) //判断数组首元素是否为字母
{
printf("首节点错误\n");
exit(1);
}
if(a[i]=='(') //左括号之前一定是字母
{
if(a[i-1]=='('||a[i-1]==')'||a[i-1]==',')
{
printf("输入错误\n");
exit(1);
}
}
if(a[i]!='('&&a[i]!=')'&&a[i]!=',') //两个字母不能在一起
{
if(a[i+1]!='('&&a[i+1]!=')'&&a[i+1]!=',')
{
printf("输入错误,两个字母不能在一起\n");
exit(1);
}
}
i++;
}
h=creat(a); //创建树
printf("该树的高度为:%d\n",high(a));
printf("该二叉树的中序输出为:");
print(h);
printf("\n");
}
6. 以二叉链为存储结构,写一算法求二叉树的叶子结点个数
只要在遍历右子树之前加上判断统计就可以了,下面给出一个Vc的程序例子,包括建树、遍历等等,下面先序建立一棵树abcd,
输入(输入一个字符回车一次):
a
b
#
#
c
#
d
#
#
输出;中序遍历结果和叶子节点数
实现程序如下:
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
typedef int Status;
//----二叉树-----
typedef char TElemType; //元素类型为字符类型
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode, *BiTree;
int NUM=0;
//------基本操作的函数
Status InitBitTree(BiTree &T) //构造一个空二叉树T
{
T=new BiTNode;
if(!T){ cout<<"构造空树时出错"<升者<endl; return false;}
T->data =NULL;
T->lchild =NULL;
T->rchild =NULL;
return true;
}//InitBitTree
Status CreateBiTree(BiTree &T) //构造一个二叉链中肆表表示的二叉树T
{
char ch;
cout<<"请输入结点的值(字符型,若空则用'#'): ";
cin>>ch;
if(ch=='#') T=NULL;
else
{
/卖笑轿/if(!(T=(BiTNode*)malloc(sizeof(BiTNode)))) exit(1);
T=new BiTNode;
if(!T) exit(1);
T->data =ch; //生成根结点
CreateBiTree(T->lchild ); //构建左子树
CreateBiTree(T->rchild ); //构建右子树
}
return 0;
} //CreateBiTree
Status Visit(TElemType e) //对结点的操作函数
{
cout<<e;
return ' ';
}
void InOrderTraverse(BiTree T,Status (*visit)(TElemType )) //中序遍历T,对每个结点调用函数Visit一次且仅一次,一旦失败,则操作失败
{
if(T) //若二叉树不为空
{
InOrderTraverse(T->lchild, visit); //递归调用访问左子树
visit(T->data ); //访问根结点,
if(T->rchild==NULL)
NUM++;
InOrderTraverse(T->rchild ,visit); //递归调用访问右子树
}
}
int main()
{
BiTree T;
InitBitTree(T);
CreateBiTree(T);
cout<<"中序遍历(打印); "<<endl;
InOrderTraverse(T,Visit);
printf("叶子节点数:%d\n",NUM);
cin.get();
//cin.get();
return 0;
}
7. 编写算法及程序,采用二叉链表作为存储结构
#include "stdio.h"
#include "malloc.h"
#define ELEMTYPE char
typedef struct BiTNode
{ ELEMTYPE data;
struct BiTNode *lchild,*rchild;
} BiTNode;
BiTNode *bulid() /*建树*/滑槐
{ BiTNode *q;
BiTNode *s[20];
int i,j;
char x;
printf("请按顺序输入二叉树的结茄让嫌点以输入0和*号结束\n");
printf("请输入你要颤手输入的为第几个结点i=\n");
scanf("%d",&i);
printf("请输入你要输入该结点的数为x=");
getchar();
scanf("%c",&x);
while(i!=0&&x!='*')
{q=(BiTNode*)malloc(sizeof(BiTNode));
q->data=x;
q->rchild=NULL;
q->lchild=NULL;
s[i]=q;
if(i!=1)
{ j=i/2;
if(i%2==0)
s[j]->lchild=q;
else
s[j]->rchild=q;
}
printf("请输入你要输入的为第几个结点x=\n");
scanf("%d",&i);
printf("请输入你要输入该结点的数x=");
getchar();
scanf("%c",&x);
}
return s[1];
}
void preoder(BiTNode *bt) /*先序遍历*/
{ if(bt!=NULL)
{
printf("%c\n",(bt->data));
preoder(bt->lchild);
preoder(bt->rchild);
}
}
void InOrder(BiTNode *bt) /*中序遍历*/
{ if(bt!=NULL)
{ InOrder(bt->lchild);
printf("%c\n",bt->data);
InOrder(bt->rchild);
}
}
void postOrder(BiTNode *bt) /*后序遍历*/
{ if(bt!=NULL)
{ postOrder(bt->lchild);
postOrder(bt->rchild);
printf("%c\n",bt->data);
}
}
main()
{ int a;
BiTNode *bt;
bt=bulid();
k1: printf("需要先序遍历输出请输入1,中序遍历请输入2,后序遍历请输入3,结束输入0:");
scanf("%d",&a);
switch(a)
{
case(1): preoder(bt); goto k1;
case(2): InOrder(bt); goto k1;
case(3): postOrder(bt); goto k1;
case(0): break;
}
}
8. 二叉树的二叉链表存储结构如何实现
大概这个样子,这个是我以前写的二叉搜索树:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int data,rep;
struct node *left,*right;
} node;
node* insert(node *tree,int x);
int search(node *tree,int x);
node* del(node *tree,int x);
int main()
{
char str[20],ch;
int x;
struct node *tree = NULL;
gets(str);
while (strcmp(str,"quit"))
{
if (!strcmp(str,"insert"))
{
scanf("%d",&x);
tree = insert(tree,x);
}
else if (!strcmp(str,"delete"))
{
scanf("%d",&x);
tree = del(tree,x);
}
else if (!strcmp(str,"search"))
{
scanf("%d",&x);
if (search(tree,x))
puts("Found!");
else
puts("Not Found!");
}
else
puts("There is an error!");
ch = getchar();
gets(str);
}
return 0;
}
node* insert(node *tree,int x)
{
if (tree == NULL)
{
tree = (struct node *)malloc(sizeof(struct node *));
tree->data = x;
tree->rep = 1;
tree->left = (struct node *)malloc(sizeof(struct node *));
tree->right = (struct node *)malloc(sizeof(struct node *));
tree->left = NULL;
tree->right = NULL;
}
else if (tree->data == x)
tree->rep++;
else if (x < tree->data)
tree->left = insert(tree->left,x);
else if (x > tree->data)
tree->right = insert(tree->right,x);
return tree;
}
int search(node *tree,int x)
{
if (tree == NULL)
return 0;
else if (tree->data == x)
return 1;
else if (x < tree->data)
return search(tree->left,x);
else if (x > tree->data)
return search(tree->right,x);
}
node* del(node *tree,int x)
{
struct node *p,*q;
if (tree == NULL) {}
else if (x < tree->data)
tree->left = del(tree->left,x);
else if (x > tree->data)
tree->right = del(tree->right,x);
else if (tree->data == x)
{
if (tree->rep > 1)
tree->rep--;
else
{
if (tree->left == NULL)
return tree->right;
else if (tree->right == NULL)
return tree->left;
else
{
p = tree->left;
q = tree;
while (p->right)
{
q = p;
p = p->right;
}
tree->data = p->data;
tree->rep = p->rep;
q->right = p->left;
}
}
}
return tree;
}
9. 以二叉链表为存储结构,写出求二叉树高度和宽度的算法
原题:
以二叉链表为存储结构,分别写出求二叉树高度及宽度的算法。所谓宽度是指在二叉树的各档基层上,具有结点数最多的那一层上的结点总数。
标准答案:
①求树的高度
思想:对非空二叉树,其深度等于左子树的最大深度加1。
Int
Depth(BinTree
*T)
{
int
dep1,dep2;
if(T==Null)
return(0);
else
{
dep1=Depth(T->lchild);
dep2=Depth(T->rchild);
if(dep1>dep2)
return(dep1+1);
else
return(dep2+1);
}
②求树的宽度
思想:按层遍历二叉树,采用一个队列q,让根结点入队列,最后出队列,若有左右子树,则左右子树根正码结点入队列,如此反复,直到队列为空。
int
Width(BinTree
*T)
{
int
front=-1,rear=-1;/*
队列初始化*/
int
flag=0,count=0,p;
/*
p用于指向树中层的最右边的结点,标志flag记录层中结点数的最大值。*/if(T!=Null)
{
rear++;
q[rear]=T;
flag=1;
p=rear;
}
while(front<p)
{
front++;
T=q[front];
if(T->lchild!=Null)
{
rear++;
q[rear]=T->lchild;
count++;
}
if(T->rchild!=Null)
{
rear++;
q[rear]=T->rchild;
count++;
}
if(front==p)
/*
当前层已遍历完毕*/
{
if(flag<行清谨count)
flag=count;
count=0;
p=rear;
/*
p指向下一层最右边的结点*/
}
}
/*
endwhile*/
return(flag);
}