题目:设计并验证如下算法:按中序序列建立两棵二叉树的二叉链表结构,判断两棵二叉树是否相等
思路:
如何确定唯一二叉树:
如先序扩展序列972#1##6#53##4##8##可确定唯一的二叉树,但它的中序扩展序列为#2#1#7#6#3#5#4#9#8#,两个结点之间有且仅有一个'#',无法确定唯一的二叉树。因此在中序序列上,为每个子树加上括号,变成:(((#2(#1#))7(#6((#3#)5(#4#))))9(#8#)),有点类似广义表了,则可确定唯一的二叉树。实际上将#去除也是可以的,(((2(1))7(6((3)5(4))))9(8)),懒得改了,有空再说吧。
如何找根、左子树、右子树:
首先将所有字符放入顺序表(或数组)
1、跳过第一个'('括号,当'('和')'的数量抵消时,则找到根结点;
2、左子树向左找,在当前结点左侧跳一个')',当'('和')'的数量抵消时,则找到左子树结点;
2、右子树向右找,在当前结点左侧跳一个'(',当'('和')'的数量抵消时,则找到右子树结点;
程序代码如下:
/*
*FileName :InCreateTree
*CopyRight :Dengguang
*/
#include
#include
#include
#include
#define OK 1
#define ERROR 0
typedef int Status;
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
int position;
}BiTNode, *BiTree;
typedef char SElemType;
#include"StackForBiTNode.h" //储存结点指针的栈
Stack S;
#include"SqListFor52.h" //存储字符的顺序表
Status InitBiTree(BiTree *);
BiTree CreateBiTree(BiTree *); //中序递归建树
Status PreOrder(BiTree );
Status InOrder(BiTree );
Status PostOrder(BiTree );
bool Equal(BiTree , BiTree ); //判断两二叉树是否相等
bool ExitLeft(SqList , int); //判断是否有左子树
bool ExitRight(SqList , int); //判断是否有右子树
int LeftData(SqList , int ); //找左子树结点,返回在顺序表的位置
int RightData(SqList , int ); //找右子树结点,返回在顺序表的位置
Status BiTreeInsLeft(BiTree *, char ); //为某结点插入左子树
Status BiTreeInsRight(BiTree *, char ); //为某结点插入右子树
int main() {
int flag=1, select;
BiTree BT1, BT2;
TElemType ch;
InitStack(&S);
printf("\nCreate Binary Tree 1\nplease input PreOrder with '#' :");
InitBiTree(&BT1);
BT1 = CreateBiTree(&BT1);
printf("Create BiTree successfully!\n");
printf("\nCreate Binary Tree 2\nplease input PreOrder with '#' :");
InitBiTree(&BT2);
BT2 = CreateBiTree(&BT2);
printf("Create BiTree successfully!\n\n");
while(flag) {
printf("\t*\tPlease select:\n");
printf("\t*\t1.PreOrder Traversal *\n");
printf("\t*\t2.InOrder Traversal *\n");
printf("\t*\t3.PostOrder Traversal *\n");
printf("\t*\t4.Equal *\n");
printf("\t*\t5.Exit *\n");
scanf("%d", &select);
switch(select) {
case 1: printf("\n The PreOrder Traversal of Binary Tree 1 is: ");
PreOrder(BT1);
printf("\n The PreOrder Traversal of Binary Tree 2 is: ");
PreOrder(BT2); break;
case 2: printf("\n The InOrder Traversal of Binary Tree 1 is: ");
InOrder(BT1);
printf("\n The InOrder Traversal of Binary Tree 2 is: ");
InOrder(BT2); break;
case 3: printf("\n The PostOrder Traversal of Binary Tree 1 is: ");
PostOrder(BT1);
printf("\n The PostOrder Traversal of Binary Tree 2 is: ");
PostOrder(BT2); break;
case 4: if(Equal(BT1, BT2))
printf("\n The BiTree BT1 and BT2 are equal!\n");
else
printf("\n The BiTree BT1 and BT2 are not equal!\n");
break;
default:flag = 0;
printf("Press any key to exit!\n");
getch();
}//switch
printf("\n");
}
return 0;
}
Status InitBiTree(BiTree *BT) {
*BT = NULL;
}
BiTree CreateBiTree(BiTree *BT) {
TElemType ch;
SqList L;
InitList_SqList(&L);
InputList_SqList(&L);
printlist_SqList(L);
BiTNode *node, *root;
int index = 0, count = 0;
//跳过第一个"("括号,当左右括号抵消时,找到根结点
for(int i = 1; i < L.length; i++) {
if(L.elem[i].data == '(')
count ++;
if(L.elem[i].data == ')')
count --;
if(count == 0) {
index = i+1;break;
}
}//for
//如果该位置不是data,则往后一个位置
while(L.elem[index].IsData == false)
index++;
*BT = (BiTNode *)malloc(sizeof(BiTNode));
(*BT)->data = L.elem[index].data;
(*BT)->position = index;
(*BT)->lchild = NULL;
(*BT)->rchild = NULL;
push(&S, *BT);
root = *BT; //root指向根结点
while(!emptyStack(&S)) {
node = getTop(&S);
index = node->position;
//存在左子树且目前左子树为空
if(ExitLeft(L, index) && node->lchild == NULL) {
//找到左子树结点并插入
index = LeftData(L, index-2);
ch = L.elem[index].data;
BiTreeInsLeft(&(*BT),ch);
node->lchild->position = index;
push(&S,node->lchild);
}
//存在右子树且目前右子树为空
else if(ExitRight(L, index) && node->rchild == NULL) {
node = pop(&S);
//找到右子树结点并插入
index = RightData(L, index+2);
ch = L.elem[index].data;
*BT = node;
BiTreeInsRight(&(*BT), ch);
node->rchild->position = index;
push(&S,node->rchild);
}
else {
node = pop(&S);
index = node->position;
}
}//while
return root;
}
//判断是否存在左子树
bool ExitLeft(SqList L, int index) {
while(index >= 0) {
index--;
//左侧有')'即说明存在左子树
if(L.elem[index].data == ')')
return true;
if(L.elem[index].data == '(')
return false;
}
return false;
}
//判断是否存在右子树
bool ExitRight(SqList L, int index) {
while(index < L.length) {
index++;
//右侧有'('即说明存在左子树
if(L.elem[index].data == '(')
return true;
if(L.elem[index].data == ')')
return false;
}
return false;
}
//找左子树结点,返回在顺序表的位置
int LeftData(SqList L, int index) {
int ind, count = 0;
//从index位置开始,当左右括号抵消时,找到左子树结点
for(int i = index; i >= 0; i--) {
if(L.elem[i].data == ')')
count ++;
if(L.elem[i].data == '(')
count --;
if(count == 0) {
ind = i-1; break;
}
}
//如果该位置不是data,则往后一个位置
while(L.elem[ind].IsData == false)
ind++;
return ind;
}
//找右子树结点,返回在顺序表的位置
int RightData(SqList L, int index) {
int ind, count = 0;
//从index位置开始,当左右括号抵消时,找到右子树结点
for(int i = index; i < L.length; i++) {
if(L.elem[i].data == '(')
count ++;
if(L.elem[i].data == ')')
count --;
if(count == 0) {
ind = i+1; break;
}
}
//如果该位置不是data,则往前一个位置
while(L.elem[ind].IsData == false)
ind--;
return ind;
}
//为结点BT插入值为data的左子树
Status BiTreeInsLeft(BiTree *BT, char data) {
BiTNode *new_node;
new_node = (BiTNode *)malloc(sizeof(BiTNode));
if(BT == NULL)
return -1;
else {
if((*BT)->lchild != NULL)
return -1;
else
(*BT)->lchild = new_node;
}
new_node->data = data;
new_node->lchild = NULL;
new_node->rchild = NULL;
*BT = new_node;
return 0;
}
//为结点BT插入值为data的右子树
Status BiTreeInsRight(BiTree *BT, char data) {
BiTNode *new_node;
new_node = (BiTNode *)malloc(sizeof(BiTNode));
if(BT == NULL)
return -1;
else {
if((*BT)->rchild != NULL)
return -1;
else
(*BT)->rchild = new_node;
}
new_node->data = data;
new_node->lchild = NULL;
new_node->rchild = NULL;
*BT = new_node;
return 0;
}
Status PreOrder(BiTree BT) {
if(BT) {
if(!(BT->data))
return ERROR;
printf("%c ", BT->data);
PreOrder(BT->lchild);
PreOrder(BT->rchild);
return OK;
}
}
Status InOrder(BiTree BT) {
if(BT) {
if(!(BT->data))
return ERROR;
InOrder(BT->lchild);
printf("%c ", BT->data);
InOrder(BT->rchild);
return OK;
}
}
Status PostOrder(BiTree BT) {
if(BT) {
if(!(BT->data))
return ERROR;
PostOrder(BT->lchild);
PostOrder(BT->rchild);
printf("%c ", BT->data);
return OK;
}
}
//判断两二叉树是否相等
bool Equal(BiTree BT1, BiTree BT2) {
if((!BT1) && (!BT2)) //都为空,返回true
return true;
//值相同且左子树和右子树相等,返回true
if(BT1->data == BT2->data)
if(Equal(BT1->lchild, BT2->lchild) && (Equal(BT1->rchild, BT2->rchild)))
return true;
return false;
}
头文件SqListFor52
#include
#include
#include
#include
#define ERROR 0
#define OK 1
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 20
typedef int Status;
struct Data{
char data;
bool IsData;
};
typedef struct Data ElemType;
struct LIST{
ElemType *elem;
int length;
int listsize;
};
typedef struct LIST SqList;
Status InitList_SqList(SqList *);
void InputList_SqList(SqList *);
Status Destroy_SqList(SqList *);
void DeleteList_SqList(SqList *);
void ReverseList_SqList(SqList *);
void printlist_SqList(SqList );
Status InitList_SqList(SqList *L) {
L->elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return OK;
}
void InputList_SqList(SqList *L) {
ElemType e;
ElemType *newbase, *p;
char a;
while(1) {
scanf("%c", &a);
if(a == '\n')
break;
e.data = a;
e.IsData = false;
if(a != '(' && a != ')' && a != '#')
e.IsData = true;
if(L->length >= L->listsize) {
newbase = (ElemType *)realloc(L->elem, (L->listsize+LISTINCREMENT)*sizeof(ElemType));
L->elem = newbase;
L->listsize += LISTINCREMENT;
}
p=&L->elem[L->length];
*p = e;
L->length++;
}
}
Status Destroy_SqList(SqList *L) {
free(L);
}
void DeleteList_SqList(SqList *L) {
ElemType *p, *q;
int len = 1, i = 1;
p = &L->elem[0];
q = &L->elem[1];
while(i < L->length) {
if(p->data != q->data) {
*p++;
*p = *q;
len++;
}
*q++;
i++;
}
L->length = len;
}
void ReverseList_SqList(SqList *L) {
int i=0, j= L->length-1;
ElemType e;
ElemType *temp, *p, *q;
temp = &e;
p = &L->elem[i];
q = &L->elem[j];
while(j > i) {
*temp = *p;
*p = *q;
*q = *temp;
*p++;
*q--;
i++;
j--;
}
}
void printlist_SqList(SqList L) {
printf("data:\t");
for(int i=0; i
头文件StackForBiTNode
#include
#include
#include
#define STACKSIZE 50
typedef struct Stack
{
BiTNode *base[STACKSIZE];
int top;
int stacksize;
}Stack;
void InitStack(Stack *);
void push(Stack *, BiTNode *);
int emptyStack(Stack * );
BiTNode* pop(Stack * );
BiTNode* getTop(Stack * );
void InitStack(Stack *stack)
{
stack->top = -1;
stack->stacksize = 0;
}
void push(Stack *stack, BiTNode *node)
{
if(stack->stacksize == STACKSIZE)
exit(-1);
stack->base[++stack->top] = node;
stack->stacksize++;
}
int emptyStack(Stack *stack)
{
if((-1 == stack->top) && (0 == stack->stacksize))
return 1;
else
return 0;
}
BiTNode* pop(Stack *stack)
{
if(stack->top < 0)
exit(-1);
else
{
stack->stacksize--;
return stack->base[stack->top--];
}
}
BiTNode* getTop(Stack *stack)
{
if(stack->top < 0)
exit(-1);
return stack->base[stack->top];
}
测试:
Create Binary Tree 1
please input PreOrder with '#' :(((#2(#1#))7(#6((#3#)5(#4#))))9(#8#))
data: ( ( ( # 2 ( # 1 # ) ) 7 ( # 6 ( ( # 3 # ) 5 ( # 4 # ) ) ) ) 9 ( # 8 # ) )
Create BiTree successfully!
Create Binary Tree 2
please input PreOrder with '#' :(((#2(#1#))7(#6((#3#)5(#4#))))9(#2#))
data: ( ( ( # 2 ( # 1 # ) ) 7 ( # 6 ( ( # 3 # ) 5 ( # 4 # ) ) ) ) 9 ( # 2 # ) )
Create BiTree successfully!
* Please select:
* 1.PreOrder Traversal *
* 2.InOrder Traversal *
* 3.PostOrder Traversal *
* 4.Equal *
* 5.Exit *
1
The PreOrder Traversal of Binary Tree 1 is: 9 7 2 1 6 5 3 4 8
The PreOrder Traversal of Binary Tree 2 is: 9 7 2 1 6 5 3 4 2
2
The InOrder Traversal of Binary Tree 1 is: 2 1 7 6 3 5 4 9 8
The InOrder Traversal of Binary Tree 2 is: 2 1 7 6 3 5 4 9 2
3
The PostOrder Traversal of Binary Tree 1 is: 1 2 3 4 5 6 7 8 9
The PostOrder Traversal of Binary Tree 2 is: 1 2 3 4 5 6 7 2 9
4
The BiTree BT1 and BT2 are not equal!
转载请通知并标明,谢谢!