#include "ds.h" #define CHAR // 字符型 //#define INT // 整型(二者选一) #ifdef CHAR typedef char TElemType; TElemType Nil=' '; // 字符型以空格符为空 #define form "%c" // 输入输出的格式为%c #endif #ifdef INT typedef int TElemType; TElemType Nil=0; // 整型以0为空 #define form "%d" // 输入输出的格式为%d #endif typedef struct BiTNode { TElemType data; BiTNode *lchild, *rchild; }BiTNode, *BiTree; typedef BiTree QElemType; // 设队列元素为二叉树的指针类型 typedef BiTree SElemType; // 设栈元素为二叉树的指针类型 /****************************************************************************************/ #define ClearBiTree DestroyBiTree typedef struct QNode{ QElemType data; struct QNode *next; }*QueuePtr; struct LinkQueue{ QueuePtr front, rear; }; //栈的顺序存储结构和其基本操作 #define STACK_INIT_SIZE 10 // 存储空间初始分配量 #define STACK_INCREMENT 2 // 存储空间分配增量 typedef struct SqStack { SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL SElemType *top; // 栈顶指针 int stacksize; // 当前已分配的存储空间,以元素为单位 }SqStack; void InitStack(SqStack &S); void DestroyStack(SqStack &S); void ClearStack(SqStack &S); Status StackEmpty(SqStack S); int StackLength(SqStack S); Status GetTop(SqStack S, SElemType &e); void Push(SqStack &S, SElemType e); Status Pop(SqStack &S, SElemType &e); void StackTraverse(SqStack S, void(* visit)(SElemType)); // 构造一个空栈S void InitStack(SqStack &S) { S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if (!S.base) exit(OVERFLOW); S.top = S.base; S.stacksize = STACK_INIT_SIZE; } // 销毁栈S,S不再存在 void DestroyStack(SqStack &S) { free(S.base); S.base = NULL; S.top = NULL; S.stacksize = 0; } // 把S置为空栈 void ClearStack(SqStack &S) { S.top = S.base; } // 若栈S为空栈,则返回TRUE,否则返回FALSE Status StackEmpty(SqStack S) { if (S.top == S.base) return TRUE; else return FALSE; } // 返回S的元素个数,即栈的长度 int StackLength(SqStack S) { return S.top - S.base; // not return S.stacksize; } // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR Status GetTop(SqStack S, SElemType &e) { if (S.top > S.base) { memcpy(&e, S.top - 1, sizeof(SElemType)); return OK; } else { return ERROR; } } // 插入元素e为新的栈顶元素 void Push(SqStack &S, SElemType e) { if (S.top - S.base >= S.stacksize) { S.base = (SElemType*)realloc(S.base, (S.stacksize + STACK_INCREMENT) * sizeof(SElemType)); if (!S.base) exit(OVERFLOW); S.top = S.base + S.stacksize; S.stacksize += STACK_INCREMENT; } memcpy(S.top, &e, sizeof(SElemType)); S.top++; } // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR Status Pop(SqStack &S, SElemType &e) { if (S.top == S.base) return ERROR; memcpy(&e, --S.top, sizeof(SElemType)); return OK; } // 从栈底到栈顶依次对栈中每个元素调用函数visit() void StackTraverse(SqStack S, void(* visit)(SElemType)) { SElemType *p = S.base; while(p < S.top) { visit(*p++); } printf("\n"); } /****************************************************************************************/ void InitQueue(LinkQueue &Q); void DestroyQueue(LinkQueue &Q); void ClearQueue(LinkQueue &Q); Status QueueEmpty(LinkQueue Q); int QueueLength(LinkQueue Q); Status GetHead(LinkQueue Q, QElemType &e); void EnQueue(LinkQueue &Q, QElemType e); Status DeQueue(LinkQueue &Q, QElemType &e); void QueueTraverse(LinkQueue Q, void(*vi)(QElemType)); // 带头结点的单链队列 void InitQueue(LinkQueue &Q) { Q.front = (QueuePtr)malloc(sizeof(QNode)); if (!Q.front) exit(OVERFLOW); Q.front->next = NULL; Q.rear = Q.front; } void DestroyQueue(LinkQueue &Q) { QueuePtr q, p = Q.front; while (p) { q = p->next; free(p); p = q; } Q.front = Q.rear = NULL; } void ClearQueue(LinkQueue &Q) { QueuePtr q, p = Q.front->next; while (p) { q = p->next; free(p); p = q; } Q.front->next = NULL; Q.rear = Q.front; } Status QueueEmpty(LinkQueue Q) { if (Q.front == Q.rear) return TRUE; else return FALSE; } int QueueLength(LinkQueue Q) { int i = 0; QueuePtr p = Q.front->next; while (p) { i++; p = p->next; } return i; } Status GetHead(LinkQueue Q, QElemType &e) { if (Q.front->next) { memcpy(&e, &(Q.front->next->data), sizeof(QElemType)); return OK; } else { return FALSE; } } void EnQueue(LinkQueue &Q, QElemType e) { QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); if (!p) exit(OVERFLOW); p->next = NULL; memcpy(&(p->data), &e, sizeof(QElemType)); Q.rear->next = p; Q.rear = p; } Status DeQueue(LinkQueue &Q, QElemType &e) { QueuePtr p = Q.front, q; if (Q.front == Q.rear) return FALSE; q = p->next; memcpy(&e, &(q->data), sizeof(QElemType)); p->next = q->next; if (Q.rear == q) Q.rear = Q.front; free(q); return OK; } void QueueTraverse(LinkQueue Q, void(*vi)(QElemType)) { QueuePtr p = Q.front->next; while (p) { vi(p->data); p = p->next; } printf("\n"); } /****************************************************************************************/ Status InitBiTree(BiTree &T) { T = NULL; return OK; } void DestroyBiTree(BiTree &T) { if (T) { if (T->lchild) DestroyBiTree(T->lchild); if (T->rchild) DestroyBiTree(T->rchild); free(T); T = NULL; } } // 按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义), // 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动 void CreateBiTree(BiTree &T) { TElemType ch; scanf(form, &ch); if (ch == Nil) T = NULL; else { T = (BiTree)malloc(sizeof(BiTNode)); if (!T) exit(OVERFLOW); T->data = ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } } Status BiTreeEmpty(BiTree T) { if (T) return FALSE; else return TRUE; } int BiTreeDepth(BiTree T) { int i, j; if (!T) return 0; if (T->lchild) i = BiTreeDepth(T->lchild); else i = 0; if (T->rchild) j = BiTreeDepth(T->rchild); else j = 0; return i > j ? i+1 : j+1; } TElemType Root(BiTree T) { if (NULL == T) return Nil; else return T->data; } TElemType Value(BiTree p) { return p->data; } void Assign(BiTree p, TElemType value) { p->data = value; } // 初始条件:二叉树T存在,e是T中某个结点 // 操作结果:若e是T的非根结点,则返回它的双亲,否则返回"空" TElemType Parent(BiTree T, TElemType e) { LinkQueue q; QElemType a; if (T) { InitQueue(q); EnQueue(q, T); while (!QueueEmpty(q)) { DeQueue(q, a); if (a->lchild && a->lchild->data == e || a->rchild && a->rchild->data == e) return a->data; else { if (a->lchild) EnQueue(q, a->lchild); if (a->rchild) EnQueue(q, a->rchild); } } } return Nil; } // 返回二叉树T中指向元素值为s的结点的指针。 BiTree Point(BiTree T, TElemType s) { LinkQueue q; QElemType a; if (T) { InitQueue(q); EnQueue(q, T); while (!QueueEmpty(q)) { DeQueue(q, a); if (a->data == s) return a; if (a->lchild) EnQueue(q, a->lchild); if (a->rchild) EnQueue(q, a->rchild); } } return NULL; } // 初始条件:二叉树T存在,e是T中某个结点。操作结果:返回e的左孩子。若e无左孩子,则返回"空" TElemType LeftChild(BiTree T, TElemType e) { BiTree a; if (T) { a = Point(T, e); if (a && a->lchild) return a->lchild->data; } return Nil; } TElemType RightChild(BiTree T, TElemType e) { BiTree a; if (T) { a = Point(T, e); if (a && a->rchild) return a->rchild->data; } return Nil; } // 初始条件:二叉树T存在,e是T中某个结点 // 操作结果:返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" TElemType LeftSibling(BiTree T,TElemType e) { TElemType a; BiTree p; if (T) { a = Parent(T, e); if (a != Nil) { p = Point(T, a); if (p->lchild && p->rchild && p->rchild->data == e) return p->lchild->data; } } return Nil; } TElemType RightSibling(BiTree T,TElemType e) { TElemType a; BiTree p; if (T) { a = Parent(T, e); if (a != Nil) { p = Point(T, a); if (p->lchild && p->rchild && p->lchild->data == e) return p->rchild->data; } } return Nil; } // 初始条件:二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T不相交且右子树为空 // 操作结果:根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的 // 原有左或右子树则成为c的右子树 Status InsertChild(BiTree p, int LR, BiTree c) { if (p) { if (LR == 0) { c->rchild = p->lchild; // p所指结点的原有左或右子树则成为c的右子树 p->lchild = c; } else { c->rchild = p->rchild; p->rchild = c; } return OK; } return ERROR; } // 初始条件:二叉树T存在,p指向T中某个结点,LR为0或1 // 操作结果:根据LR为0或1,删除T中p所指结点的左或右子树 Status DeleteChild(BiTree p, int LR) { if (p) { if (LR == 0) { ClearBiTree(p->lchild); } else { ClearBiTree(p->rchild); } return OK; } return ERROR; } // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。算法6.3,有改动 // 中序遍历二叉树T的非递归算法(利用栈),对每个数据元素调用函数Visit void InOrderTraverse1(BiTree T, void(*Visit)(TElemType)) { SqStack S; InitStack(S); while (T || !StackEmpty(S)) { if (T) { Push(S, T); T = T->lchild; } else { Pop(S, T); Visit(T->data); T = T->rchild; } } printf("\n"); } // 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。算法6.2,有改动 // 中序遍历二叉树T的非递归算法(利用栈),对每个数据元素调用函数Visit void InOrderTraverse2(BiTree T,void(*Visit)(TElemType)) { SqStack S; BiTree p; InitStack(S); Push(S, T); while (!StackEmpty(S)) { while (GetTop(S, p) && p) Push(S, p->lchild); Pop(S, p); // 空指针退栈 if (!StackEmpty(S)) { Pop(S, p); Visit(p->data); Push(S, p->rchild); } } printf("\n"); } // 初始条件:二叉树T存在,Visit是对结点操作的应用函数 // 操作结果:后序递归遍历T,对每个结点调用函数Visit一次且仅一次 void PostOrderTraverse(BiTree T,void(*Visit)(TElemType)) { if(T) // T不空 { PostOrderTraverse(T->lchild,Visit); // 先后序遍历左子树 PostOrderTraverse(T->rchild,Visit); // 再后序遍历右子树 Visit(T->data); // 最后访问根结点 } } // 初始条件:二叉树T存在,Visit是对结点操作的应用函数 // 操作结果:先序递归遍历T,对每个结点调用函数Visit一次且仅一次 void PreOrderTraverse(BiTree T,void(*Visit)(TElemType)) { if(T) // T不空 { Visit(T->data); // 先访问根结点 PreOrderTraverse(T->lchild,Visit); // 再先序遍历左子树 PreOrderTraverse(T->rchild,Visit); // 最后先序遍历右子树 } } // 初始条件:二叉树T存在,Visit是对结点操作的应用函数 // 操作结果:层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次 void LevelOrderTraverse(BiTree T,void(*Visit)(TElemType)) { LinkQueue q; QElemType a; if(T) { InitQueue(q); // 初始化队列q EnQueue(q,T); // 根指针入队 while(!QueueEmpty(q)) // 队列不空 { DeQueue(q,a); // 出队元素(指针),赋给a Visit(a->data); // 访问a所指结点 if(a->lchild!=NULL) // a有左孩子 EnQueue(q,a->lchild); // 入队a的左孩子 if(a->rchild!=NULL) // a有右孩子 EnQueue(q,a->rchild); // 入队a的右孩子 } printf("\n"); } } void visitT(TElemType e) { printf(form" ", e); } int main() { int i; BiTree T,p,c; TElemType e1,e2; InitBiTree(T); printf("构造空二叉树后,树空否?%d(1:是 0:否)树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T)); e1=Root(T); if(e1!=Nil) printf("二叉树的根为: "form"\n",e1); else printf("树空,无根\n"); #ifdef CHAR printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n"); #endif #ifdef INT printf("请先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n"); #endif CreateBiTree(T); printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n",BiTreeEmpty(T),BiTreeDepth(T)); e1=Root(T); if(e1!=Nil) printf("二叉树的根为: "form"\n",e1); else printf("树空,无根\n"); printf("中序递归遍历二叉树:\n"); InOrderTraverse1(T,visitT); printf("\n后序递归遍历二叉树:\n"); PostOrderTraverse(T,visitT); printf("\n请输入一个结点的值: "); scanf("%*c"form,&e1); p=Point(T,e1); // p为e1的指针 printf("结点的值为"form"\n",Value(p)); printf("欲改变此结点的值,请输入新值: "); scanf("%*c"form"%*c",&e2); // 后一个%*c吃掉回车符,为调用CreateBiTree()做准备 Assign(p,e2); printf("层序遍历二叉树:\n"); LevelOrderTraverse(T,visitT); e1=Parent(T,e2); if(e1!=Nil) printf("%c的双亲是"form"\n",e2,e1); else printf(form"没有双亲\n",e2); e1=LeftChild(T,e2); if(e1!=Nil) printf(form"的左孩子是"form"\n",e2,e1); else printf(form"没有左孩子\n",e2); e1=RightChild(T,e2); if(e1!=Nil) printf(form"的右孩子是"form"\n",e2,e1); else printf(form"没有右孩子\n",e2); e1=LeftSibling(T,e2); if(e1!=Nil) printf(form"的左兄弟是"form"\n",e2,e1); else printf(form"没有左兄弟\n",e2); e1=RightSibling(T,e2); if(e1!=Nil) printf(form"的右兄弟是"form"\n",e2,e1); else printf(form"没有右兄弟\n",e2); InitBiTree(c); printf("构造一个右子树为空的二叉树c:\n"); #ifdef CHAR printf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n"); #endif #ifdef INT printf("请先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n"); #endif CreateBiTree(c); printf("先序递归遍历二叉树c:\n"); PreOrderTraverse(c,visitT); printf("\n层序遍历二叉树c:\n"); LevelOrderTraverse(c,visitT); printf("树c插到树T中,请输入树T中树c的双亲结点 c为左(0)或右(1)子树: "); scanf("%*c"form"%d",&e1,&i); p=Point(T,e1); // p是T中树c的双亲结点指针 InsertChild(p,i,c); printf("先序递归遍历二叉树:\n"); PreOrderTraverse(T,visitT); printf("\n中序非递归遍历二叉树:\n"); InOrderTraverse1(T,visitT); printf("删除子树,请输入待删除子树的双亲结点 左(0)或右(1)子树: "); scanf("%*c"form"%d",&e1,&i); p=Point(T,e1); DeleteChild(p,i); printf("先序递归遍历二叉树:\n"); PreOrderTraverse(T,visitT); printf("\n中序非递归遍历二叉树(另一种方法):\n"); InOrderTraverse2(T,visitT); DestroyBiTree(T); }