数据结构学习笔记 --- 二叉树

来源:互联网 发布:淘宝运营教学 编辑:程序博客网 时间:2024/06/09 13:47
#include "ds.h"#define CHAR // 字符型//#define INT // 整型(二者选一)#ifdef CHARtypedef char TElemType;TElemType Nil=' '; // 字符型以空格符为空#define form "%c" // 输入输出的格式为%c#endif#ifdef INTtypedef 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 DestroyBiTreetypedef 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的值为NULLSElemType *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));// 构造一个空栈Svoid 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,否则返回FALSEStatus StackEmpty(SqStack S){if (S.top == S.base)return TRUE;elsereturn FALSE;}// 返回S的元素个数,即栈的长度int StackLength(SqStack S){return S.top - S.base;  // not return S.stacksize;}// 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORStatus 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;否则返回ERRORStatus 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;elsereturn 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){TElemTypech;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;elsereturn TRUE;}int BiTreeDepth(BiTree T){int i, j;if (!T)return 0;if (T->lchild)i = BiTreeDepth(T->lchild);elsei = 0;if (T->rchild)j = BiTreeDepth(T->rchild);elsej = 0;return i > j ? i+1 : j+1;}TElemType Root(BiTree T){if (NULL == T)return Nil;elsereturn 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;QElemTypea;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;QElemTypea;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的非递归算法(利用栈),对每个数据元素调用函数Visitvoid 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的非递归算法(利用栈),对每个数据元素调用函数Visitvoid InOrderTraverse2(BiTree T,void(*Visit)(TElemType)){ SqStackS; 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);}

0 0
原创粉丝点击