中序序列建立二叉树

题目:设计并验证如下算法:按中序序列建立两棵二叉树的二叉链表结构,判断两棵二叉树是否相等

思路

如何确定唯一二叉树:

如先序扩展序列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!
转载请通知并标明,谢谢!

你可能感兴趣的:(数据结构)