来源:互联网 发布:mac上不显示u盘 编辑:程序博客网 时间:2024/04/30 15:45

1.公共部分

结构体

#ifndef ELEMTYPE_H#define ELEMTYPE_H#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define CHAR /* 字符型 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#ifdef CHARtypedef char TElemType;//TElemType Nil = ' ';#endif#ifdef INTtypedef int TElemType;//TElemType Nil = 0;#endiftypedef struct BiTNode{TElemType data;struct BiTNode *lchild, *rchild; /* 左右孩子指针 */}BiTNode, *BiTree;#endif


顺序非循环队列

/* c1.h (程序名) */#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<process.h> /* exit() *//* 函数结果状态代码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1 #define OVERFLOW -2 typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef int QElemType;/* c3-3.h 队列的顺序存储结构(可用于循环队列和非循环队列) */#define MAXQSIZE 5 /* 最大队列长度(对于循环队列,最大队列长度要减1) */typedef struct{QElemType *base; /* 初始化的动态分配存储空间 */int front; /* 头指针,若队列不空,指向队列头元素 */int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */}SqQueue;Status InitQueue(SqQueue *Q);Status DestroyQueue(SqQueue *Q);Status ClearQueue(SqQueue *Q);Status QueueEmpty(SqQueue Q);int QueueLength(SqQueue Q);Status GetHead(SqQueue Q, QElemType *e);Status EnQueue(SqQueue *Q, QElemType e);Status DeQueue(SqQueue *Q, QElemType *e);Status QueueTraverse(SqQueue Q, void(*vi)(QElemType));

#include "queue.h"Status InitQueue(SqQueue *Q){ /* 构造一个空队列Q */(*Q).base = (QElemType *)malloc(MAXQSIZE*sizeof(QElemType));if (!(*Q).base) /* 存储分配失败 */exit(OVERFLOW);(*Q).front = (*Q).rear = 0;return OK;}Status DestroyQueue(SqQueue *Q){ /* 销毁队列Q,Q不再存在 */if ((*Q).base)free((*Q).base);(*Q).base = NULL;(*Q).front = (*Q).rear = 0;return OK;}Status ClearQueue(SqQueue *Q){ /* 将Q清为空队列 */(*Q).front = (*Q).rear = 0;return OK;}Status QueueEmpty(SqQueue Q){ /* 若队列Q为空队列,则返回TRUE,否则返回FALSE */if (Q.front == Q.rear) /* 队列空的标志 */return TRUE;elsereturn FALSE;}int QueueLength(SqQueue Q){ /* 返回Q的元素个数,即队列的长度 */return(Q.rear - Q.front);}Status GetHead(SqQueue Q, QElemType *e){ /* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */if (Q.front == Q.rear) /* 队列空 */return ERROR;*e = *(Q.base + Q.front);return OK;}Status EnQueue(SqQueue *Q, QElemType e){ /* 插入元素e为Q的新的队尾元素 */if ((*Q).rear >= MAXQSIZE){ /* 队列满,增加1个存储单元 */(*Q).base = (QElemType *)realloc((*Q).base, ((*Q).rear + 1)*sizeof(QElemType));if (!(*Q).base) /* 增加单元失败 */return ERROR;}*((*Q).base + (*Q).rear) = e;(*Q).rear++;return OK;}Status DeQueue(SqQueue *Q, QElemType *e){ /* 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */if ((*Q).front == (*Q).rear) /* 队列空 */return ERROR;*e = (*Q).base[(*Q).front];(*Q).front = (*Q).front + 1;return OK;}Status QueueTraverse(SqQueue Q, void(*vi)(QElemType)){ /* 从队头到队尾依次对队列Q中每个元素调用函数vi()。一旦vi失败,则操作失败 */int i;i = Q.front;while (i != Q.rear){vi(*(Q.base + i));i++;}printf("\n");return OK;}

链队列

//#include "ElemType.h"//typedef BiTree QElemType;//#include "PaTree.h"//#include "CSTree.h"#include "SanTree.h"//typedef struct//{//int num;//TElemType name;//}QElemType; /* 定义队列元素类型 *///typedef CSTree QElemType; /* 定义队列元素类型 */typedef BiPTree QElemType; /* 设队列元素为二叉树的指针类型 */typedef struct QNode{QElemType data;struct QNode *next;}QNode, *QueuePtr;typedef struct{QueuePtr front, rear; /* 队头、队尾指针 */}LinkQueue;Status InitQueue(LinkQueue *Q);Status DestroyQueue(LinkQueue *Q);Status ClearQueue(LinkQueue *Q);Status QueueEmpty(LinkQueue Q);int QueueLength(LinkQueue Q);Status GetHead_Q(LinkQueue Q, QElemType *e);Status EnQueue(LinkQueue *Q, QElemType e);Status DeQueue(LinkQueue *Q, QElemType *e);Status QueueTraverse(LinkQueue Q, void(*vi)(QElemType));

#include "linkQueue.h"Status InitQueue(LinkQueue *Q){ /* 构造一个空队列Q */(*Q).front = (*Q).rear = (QueuePtr)malloc(sizeof(QNode));if (!(*Q).front)exit(OVERFLOW);(*Q).front->next = NULL;return OK;}Status DestroyQueue(LinkQueue *Q){ /* 销毁队列Q(无论空否均可) */while ((*Q).front){(*Q).rear = (*Q).front->next;free((*Q).front);(*Q).front = (*Q).rear;}return OK;}Status ClearQueue(LinkQueue *Q){ /* 将Q清为空队列 */QueuePtr p, q;(*Q).rear = (*Q).front;p = (*Q).front->next;(*Q).front->next = NULL;while (p){q = p;p = p->next;free(q);}return OK;}Status QueueEmpty(LinkQueue Q){ /* 若Q为空队列,则返回TRUE,否则返回FALSE */if (Q.front == Q.rear)return TRUE;elsereturn FALSE;}int QueueLength(LinkQueue Q){ /* 求队列的长度 */int i = 0;QueuePtr p;p = Q.front;while (Q.rear != p){i++;p = p->next;}return i;}Status GetHead_Q(LinkQueue Q, QElemType *e) /* 避免与bo2-6.c重名 */{ /* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */QueuePtr p;if (Q.front == Q.rear)return ERROR;p = Q.front->next;*e = p->data;return OK;}Status EnQueue(LinkQueue *Q, QElemType e){ /* 插入元素e为Q的新的队尾元素 */QueuePtr p = (QueuePtr)malloc(sizeof(QNode));if (!p) /* 存储分配失败 */exit(OVERFLOW);p->data = e;p->next = NULL;(*Q).rear->next = p;(*Q).rear = p;return OK;}Status DeQueue(LinkQueue *Q, QElemType *e){ /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */QueuePtr p;if ((*Q).front == (*Q).rear)return ERROR;p = (*Q).front->next;*e = p->data;(*Q).front->next = p->next;if ((*Q).rear == p)(*Q).rear = (*Q).front;free(p);return OK;}Status QueueTraverse(LinkQueue Q, void(*vi)(QElemType)){ /* 从队头到队尾依次对队列Q中每个元素调用函数vi()。一旦vi失败,则操作失败 */QueuePtr p;p = Q.front->next;while (p){vi(p->data);p = p->next;}printf("\n");return OK;}


顺序栈

#include "ElemType.h"typedef BiTree SElemType;#define STACK_INIT_SIZE 10 /* 存储空间初始分配量 */#define STACKINCREMENT 2 /* 存储空间分配增量 */typedef struct SqStack{SElemType *base; /* 在栈构造之前和销毁之后,base的值为NULL */SElemType *top; /* 栈顶指针 */int stacksize; /* 当前已分配的存储空间,以元素为单位 */}SqStack; /* 顺序栈 *//* bo3-1.c 顺序栈(存储结构由c3-1.h定义)的基本操作(9个) */Status InitStack(SqStack *S);Status DestroyStack(SqStack *S);Status ClearStack(SqStack *S);Status StackEmpty(SqStack S);int StackLength(SqStack S);Status GetTop(SqStack S, SElemType *e);Status Push(SqStack *S, SElemType e);Status Pop(SqStack *S, SElemType *e);Status StackTraverse(SqStack S, Status(*visit)(SElemType));

/* bo3-1.c 顺序栈(存储结构由c3-1.h定义)的基本操作(9个) */#include "stack.h"Status InitStack(SqStack *S){ /* 构造一个空栈S */(*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if (!(*S).base)exit(OVERFLOW); /* 存储分配失败 */(*S).top = (*S).base;(*S).stacksize = STACK_INIT_SIZE;return OK;}Status DestroyStack(SqStack *S){ /* 销毁栈S,S不再存在 */free((*S).base);(*S).base = NULL;(*S).top = NULL;(*S).stacksize = 0;return OK;}Status ClearStack(SqStack *S){ /* 把S置为空栈 */(*S).top = (*S).base;return OK;}Status StackEmpty(SqStack S){ /* 若栈S为空栈,则返回TRUE,否则返回FALSE */if (S.top == S.base)return TRUE;elsereturn FALSE;}int StackLength(SqStack S){ /* 返回S的元素个数,即栈的长度 */return S.top - S.base;}Status GetTop(SqStack S, SElemType *e){ /* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */if (S.top>S.base){*e = *(S.top - 1);return OK;}elsereturn ERROR;}Status Push(SqStack *S, SElemType e){ /* 插入元素e为新的栈顶元素 */if ((*S).top - (*S).base >= (*S).stacksize) /* 栈满,追加存储空间 */{(*S).base = (SElemType *)realloc((*S).base, ((*S).stacksize + STACKINCREMENT)*sizeof(SElemType));if (!(*S).base)exit(OVERFLOW); /* 存储分配失败 */(*S).top = (*S).base + (*S).stacksize;(*S).stacksize += STACKINCREMENT;}*((*S).top)++ = e;return OK;}Status Pop(SqStack *S, SElemType *e){ /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */if ((*S).top == (*S).base)return ERROR;*e = *--(*S).top;return OK;}Status StackTraverse(SqStack S, Status(*visit)(SElemType)){ /* 从栈底到栈顶依次对栈中每个元素调用函数visit()。 *//* 一旦visit()失败,则操作失败 */while (S.top>S.base)visit(*S.base++);printf("\n");return OK;}


2. 顺序树

#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<process.h> /* exit() *//* 函数结果状态代码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef int ElemType;/* c6-1.h 二叉树的顺序存储表示 */#define MAX_TREE_SIZE 100 /* 二叉树的最大结点数 */typedef ElemType SqBiTree[MAX_TREE_SIZE]; /* 0号单元存储根结点 */#include "queue.h"typedef struct{int level, order; /* 结点的层,本层序号(按满二叉树计算) */}position;Status InitBiTree(SqBiTree T);void DestroyBiTree();Status CreateBiTree(SqBiTree T);#define ClearBiTree InitBiTree /* 在顺序存储结构中,两函数完全一样 */Status BiTreeEmpty(SqBiTree T);int BiTreeDepth(SqBiTree T);Status Root(SqBiTree T, ElemType *e);ElemType Value(SqBiTree T, position e);Status Assign(SqBiTree T, position e, ElemType value);ElemType Parent(SqBiTree T, ElemType e);ElemType LeftChild(SqBiTree T, ElemType e);ElemType RightChild(SqBiTree T, ElemType e);ElemType LeftSibling(SqBiTree T, ElemType e);ElemType RightSibling(SqBiTree T, ElemType e);void Move(SqBiTree q, int j, SqBiTree T, int i);Status InsertChild(SqBiTree T, ElemType p, Status LR, SqBiTree c);typedef int QElemType; /* 设队列元素类型为整型(序号) */Status DeleteChild(SqBiTree T, position p, int LR);//在C语言中,这里只会视为一个指针,并产生一个函数,但是在C++中,将产生一个实体函数,此时在前面加上static防止重复定义Status(*VisitFunc)(ElemType); /* 函数变量 */void PreTraverse(SqBiTree T, int e);Status PreOrderTraverse(SqBiTree T, Status(*Visit)(ElemType));void InTraverse(SqBiTree T, int e);Status InOrderTraverse(SqBiTree T, Status(*Visit)(ElemType));void PostTraverse(SqBiTree T, int e);Status PostOrderTraverse(SqBiTree T, Status(*Visit)(ElemType));void LevelOrderTraverse(SqBiTree T, Status(*Visit)(ElemType));void Print(SqBiTree T);

#include "sTree.h"#define Nil 0int pow(int m, int n){int ret = 1;while (n > 0){if ((n & 1) == 1){ret *= m;m *= m;n >>= 1;continue;}m *= m;n >>= 1;}return ret;}Status InitBiTree(SqBiTree T){ /* 构造空二叉树T。因为T是固定数组,不会改变,故不需要& */int i;for (i = 0; i<MAX_TREE_SIZE; i++)T[i] = Nil; /* 初值为空 */return OK;}void DestroyBiTree(){ /* 由于SqBiTree是定长类型,无法销毁 */}Status CreateBiTree(SqBiTree T){ /* 按层序次序输入二叉树中结点的值(字符型或整型), 构造顺序存储的二叉树T */int i = 0;#if CHARint l;char s[MAX_TREE_SIZE];printf("请按层序输入结点的值(字符),空格表示空结点,结点数≤%d:\n", MAX_TREE_SIZE);gets(s); /* 输入字符串 */l = strlen(s); /* 求字符串的长度 */for (; i<l; i++) /* 将字符串赋值给T */{T[i] = s[i];if (i != 0 && T[(i + 1) / 2 - 1] == Nil&&T[i] != Nil) /* 此结点(不空)无双亲且不是根 */{printf("出现无双亲的非根结点%c\n", T[i]);exit(ERROR);}}for (i = l; i<MAX_TREE_SIZE; i++) /* 将空赋值给T的后面的结点 */T[i] = Nil;#elseprintf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤%d:\n", MAX_TREE_SIZE);while (1){scanf("%d", &T[i]);if (T[i] == 999)break;if (i != 0 && T[(i + 1) / 2 - 1] == Nil&&T[i] != Nil) /* 此结点(不空)无双亲且不是根 */{printf("出现无双亲的非根结点%d\n", T[i]);exit(ERROR);}i++;}while (i<MAX_TREE_SIZE){T[i] = Nil; /* 将空赋值给T的后面的结点 */i++;}#endifreturn OK;}#define ClearBiTree InitBiTree /* 在顺序存储结构中,两函数完全一样 */Status BiTreeEmpty(SqBiTree T){ /* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */if (T[0] == Nil) /* 根结点为空,则树空 */return TRUE;elsereturn FALSE;}int BiTreeDepth(SqBiTree T){ /* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */int i, j = -1;for (i = MAX_TREE_SIZE - 1; i >= 0; i--) /* 找到最后一个结点 */if (T[i] != Nil)break;i++; /* 为了便于计算 */doj++;while (i >= pow(2, j));return j;}Status Root(SqBiTree T, ElemType *e){ /* 初始条件: 二叉树T存在 *//* 操作结果:  当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义 */if (BiTreeEmpty(T)) /* T空 */return ERROR;else{*e = T[0];return OK;}}ElemType Value(SqBiTree T, position e){ /* 初始条件: 二叉树T存在,e是T中某个结点(的位置) *//* 操作结果: 返回处于位置e(层,本层序号)的结点的值 */return T[(int)pow(2, e.level - 1) + e.order - 2];}Status Assign(SqBiTree T, position e, ElemType value){ /* 初始条件: 二叉树T存在,e是T中某个结点(的位置) *//* 操作结果: 给处于位置e(层,本层序号)的结点赋新值value */int i = (int)pow(2, e.level - 1) + e.order - 2; /* 将层、本层序号转为矩阵的序号 */if (value != Nil&&T[(i + 1) / 2 - 1] == Nil) /* 给叶子赋非空值但双亲为空 */return ERROR;else if (value == Nil && (T[i * 2 + 1] != Nil || T[i * 2 + 2] != Nil)) /*  给双亲赋空值但有叶子(不空) */return ERROR;T[i] = value;return OK;}ElemType Parent(SqBiTree T, ElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */int i;if (T[0] == Nil) /* 空树 */return Nil;for (i = 1; i <= MAX_TREE_SIZE - 1; i++)if (T[i] == e) /* 找到e */return T[(i + 1) / 2 - 1];return Nil; /* 没找到e */}ElemType LeftChild(SqBiTree T, ElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左孩子。若e无左孩子,则返回"空" */int i;if (T[0] == Nil) /* 空树 */return Nil;for (i = 0; i <= MAX_TREE_SIZE - 1; i++)if (T[i] == e) /* 找到e */return T[i * 2 + 1];return Nil; /* 没找到e */}ElemType RightChild(SqBiTree T, ElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右孩子。若e无右孩子,则返回"空" */int i;if (T[0] == Nil) /* 空树 */return Nil;for (i = 0; i <= MAX_TREE_SIZE - 1; i++)if (T[i] == e) /* 找到e */return T[i * 2 + 2];return Nil; /* 没找到e */}ElemType LeftSibling(SqBiTree T, ElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */int i;if (T[0] == Nil) /* 空树 */return Nil;for (i = 1; i <= MAX_TREE_SIZE - 1; i++)if (T[i] == e&&i % 2 == 0) /* 找到e且其序号为偶数(是右孩子) */return T[i - 1];return Nil; /* 没找到e */}ElemType RightSibling(SqBiTree T, ElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回"空" */int i;if (T[0] == Nil) /* 空树 */return Nil;for (i = 1; i <= MAX_TREE_SIZE - 1; i++)if (T[i] == e&&i % 2) /* 找到e且其序号为奇数(是左孩子) */return T[i + 1];return Nil; /* 没找到e */}void Move(SqBiTree q, int j, SqBiTree T, int i) /* InsertChild()用到。加 */{ /* 把从q的j结点开始的子树移为从T的i结点开始的子树 */if (q[2 * j + 1] != Nil) /* q的左子树不空 */Move(q, (2 * j + 1), T, (2 * i + 1)); /* 把q的j结点的左子树移为T的i结点的左子树 */if (q[2 * j + 2] != Nil) /* q的右子树不空 */Move(q, (2 * j + 2), T, (2 * i + 2)); /* 把q的j结点的右子树移为T的i结点的右子树 */T[i] = q[j]; /* 把q的j结点移为T的i结点 */q[j] = Nil; /* 把q的j结点置空 */}Status InsertChild(SqBiTree T, ElemType p, Status LR, SqBiTree c){ /* 初始条件: 二叉树T存在,p是T中某个结点的值,LR为0或1,非空二叉树c与T *//*           不相交且右子树为空 *//* 操作结果: 根据LR为0或1,插入c为T中p结点的左或右子树。p结点的原有左或 *//*           右子树则成为c的右子树 */int j, k, i = 0;for (j = 0; j<(int)pow(2, BiTreeDepth(T)) - 1; j++) /* 查找p的序号 */if (T[j] == p) /* j为p的序号 */break;k = 2 * j + 1 + LR; /* k为p的左或右孩子的序号 */if (T[k] != Nil) /* p原来的左或右孩子不空 */Move(T, k, T, 2 * k + 2); /* 把从T的k结点开始的子树移为从k结点的右子树开始的子树 */Move(c, i, T, k); /* 把从c的i结点开始的子树移为从T的k结点开始的子树 */return OK;}Status DeleteChild(SqBiTree T, position p, int LR){ /* 初始条件: 二叉树T存在,p指向T中某个结点,LR为1或0 *//* 操作结果: 根据LR为1或0,删除T中p所指结点的左或右子树 */int i;Status k = OK; /* 队列不空的标志 */SqQueue q;InitQueue(&q); /* 初始化队列,用于存放待删除的结点 */i = (int)pow(2, p.level - 1) + p.order - 2; /* 将层、本层序号转为矩阵的序号 */if (T[i] == Nil) /* 此结点空 */return ERROR;i = i * 2 + 1 + LR; /* 待删除子树的根结点在矩阵中的序号 */while (k){if (T[2 * i + 1] != Nil) /* 左结点不空 */EnQueue(&q, 2 * i + 1); /* 入队左结点的序号 */if (T[2 * i + 2] != Nil) /* 右结点不空 */EnQueue(&q, 2 * i + 2); /* 入队右结点的序号 */T[i] = Nil; /* 删除此结点 */k = DeQueue(&q, &i); /* 队列不空 */}return OK;}void PreTraverse(SqBiTree T, int e){ /* PreOrderTraverse()调用 */VisitFunc(T[e]);if (T[2 * e + 1] != Nil) /* 左子树不空 */PreTraverse(T, 2 * e + 1);if (T[2 * e + 2] != Nil) /* 右子树不空 */PreTraverse(T, 2 * e + 2);}Status PreOrderTraverse(SqBiTree T, Status(*Visit)(ElemType)){ /* 初始条件: 二叉树存在,Visit是对结点操作的应用函数 *//* 操作结果: 先序遍历T,对每个结点调用函数Visit一次且仅一次。 *//*           一旦Visit()失败,则操作失败 */VisitFunc = Visit;if (!BiTreeEmpty(T)) /* 树不空 */PreTraverse(T, 0);printf("\n");return OK;}void InTraverse(SqBiTree T, int e){ /* InOrderTraverse()调用 */if (T[2 * e + 1] != Nil) /* 左子树不空 */InTraverse(T, 2 * e + 1);VisitFunc(T[e]);if (T[2 * e + 2] != Nil) /* 右子树不空 */InTraverse(T, 2 * e + 2);}Status InOrderTraverse(SqBiTree T, Status(*Visit)(ElemType)){ /* 初始条件: 二叉树存在,Visit是对结点操作的应用函数 *//* 操作结果: 中序遍历T,对每个结点调用函数Visit一次且仅一次。 *//*           一旦Visit()失败,则操作失败 */VisitFunc = Visit;if (!BiTreeEmpty(T)) /* 树不空 */InTraverse(T, 0);printf("\n");return OK;}void PostTraverse(SqBiTree T, int e){ /* PostOrderTraverse()调用 */if (T[2 * e + 1] != Nil) /* 左子树不空 */PostTraverse(T, 2 * e + 1);if (T[2 * e + 2] != Nil) /* 右子树不空 */PostTraverse(T, 2 * e + 2);VisitFunc(T[e]);}Status PostOrderTraverse(SqBiTree T, Status(*Visit)(ElemType)){ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 *//* 操作结果: 后序遍历T,对每个结点调用函数Visit一次且仅一次。 *//*           一旦Visit()失败,则操作失败 */VisitFunc = Visit;if (!BiTreeEmpty(T)) /* 树不空 */PostTraverse(T, 0);printf("\n");return OK;}void LevelOrderTraverse(SqBiTree T, Status(*Visit)(ElemType)){ /* 层序遍历二叉树 */int i = MAX_TREE_SIZE - 1, j;while (T[i] == Nil)i--; /* 找到最后一个非空结点的序号 */for (j = 0; j <= i; j++)  /* 从根结点起,按层序遍历二叉树 */if (T[j] != Nil)Visit(T[j]); /* 只遍历非空的结点 */printf("\n");}void Print(SqBiTree T){ /* 逐层、按本层序号输出二叉树 */int j, k;position p;ElemType e;for (j = 1; j <= BiTreeDepth(T); j++){printf("第%d层: ", j);for (k = 1; k <= pow(2, j - 1); k++){p.level = j;p.order = k;e = Value(T, p);if (e != Nil)printf("%d:%d ", k, e);}printf("\n");}}

#include "sTree.h"Status visit(ElemType e){printf("%d ", e);return OK;}void main(){Status i;int j;position p;ElemType e;SqBiTree T, s;InitBiTree(T);CreateBiTree(T);printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));i = Root(T, &e);if (i)printf("二叉树的根为:%d\n", e);elseprintf("树空,无根\n");printf("层序遍历二叉树:\n");LevelOrderTraverse(T, visit);printf("中序遍历二叉树:\n");InOrderTraverse(T, visit);printf("后序遍历二叉树:\n");PostOrderTraverse(T, visit);printf("请输入待修改结点的层号 本层序号: ");scanf("%d%d", &p.level, &p.order);e = Value(T, p);printf("待修改结点的原值为%d请输入新值: ", e);scanf("%d", &e);Assign(T, p, e);printf("先序遍历二叉树:\n");PreOrderTraverse(T, visit);printf("结点%d的双亲为%d,左右孩子分别为", e, Parent(T, e));printf("%d,%d,左右兄弟分别为", LeftChild(T, e), RightChild(T, e));printf("%d,%d\n", LeftSibling(T, e), RightSibling(T, e));InitBiTree(s);printf("建立右子树为空的树s:\n");CreateBiTree(s);printf("树s插到树T中,请输入树T中树s的双亲结点 s为左(0)或右(1)子树: ");scanf("%d%d", &e, &j);InsertChild(T, e, j, s);Print(T);printf("删除子树,请输入待删除子树根结点的层号 本层序号 左(0)或右(1)子树: ");scanf("%d%d%d", &p.level, &p.order, &j);DeleteChild(T, p, j);Print(T);ClearBiTree(T);printf("清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));i = Root(T, &e);if (i)printf("二叉树的根为:%d\n", e);elseprintf("树空,无根\n");}

二叉树,指针表示

#include "ElemType.h"/* c6-2.h 二叉树的二叉链表存储表示 */Status InitBiTree(BiTree *T);void DestroyBiTree(BiTree *T);void CreateBiTree(BiTree *T);Status BiTreeEmpty(BiTree T);#define ClearBiTree DestroyBiTreeint BiTreeDepth(BiTree T);TElemType Root(BiTree T);TElemType Value(BiTree p);void Assign(BiTree p, TElemType value);TElemType Parent(BiTree T, TElemType e);BiTree Point(BiTree T, TElemType s);TElemType LeftChild(BiTree T, TElemType e);TElemType RightChild(BiTree T, TElemType e);TElemType LeftSibling(BiTree T, TElemType e);TElemType RightSibling(BiTree T, TElemType e);Status InsertChild(BiTree p, int LR, BiTree c);Status DeleteChild(BiTree p, int LR);void PreOrderTraverse(BiTree T, Status(*Visit)(TElemType));void InOrderTraverse(BiTree T, Status(*Visit)(TElemType));Status InOrderTraverse1(BiTree T, Status(*Visit)(TElemType));Status InOrderTraverse2(BiTree T, Status(*Visit)(TElemType));void PostOrderTraverse(BiTree T, Status(*Visit)(TElemType));void LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType));

#include "tree.h"#include "linkQueue.h"#include "tree.h"#include "stack.h"static TElemType Nil = ' ';Status InitBiTree(BiTree *T){ /* 操作结果: 构造空二叉树T */*T = NULL;return OK;}void DestroyBiTree(BiTree *T){ /* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */if (*T) /* 非空树 */{if ((*T)->lchild) /* 有左孩子 */DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */if ((*T)->rchild) /* 有右孩子 */DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */free(*T); /* 释放根结点 */*T = NULL; /* 空指针赋0 */}}void CreateBiTree(BiTree *T){ /* 算法6.4:按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中 *//* 定义),构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动 */TElemType ch;#ifdef CHARscanf("%c", &ch);#endif#ifdef INTscanf("%d", &ch);#endifif (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){ /* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */if (T)return FALSE;elsereturn TRUE;}#define ClearBiTree DestroyBiTreeint BiTreeDepth(BiTree T){ /* 初始条件: 二叉树T存在。操作结果: 返回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){ /* 初始条件: 二叉树T存在。操作结果: 返回T的根 */if (BiTreeEmpty(T))return Nil;elsereturn T->data;}TElemType Value(BiTree p){ /* 初始条件: 二叉树T存在,p指向T中某个结点 *//* 操作结果: 返回p所指结点的值 */return p->data;}void Assign(BiTree p, TElemType value){ /* 给p所指结点赋值为value */p->data = value;}TElemType Parent(BiTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */LinkQueue q;QElemType a;if (T) /* 非空树 */{InitQueue(&q); /* 初始化队列 */EnQueue(&q, T); /* 树根入队 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &a); /* 出队,队列元素赋给a */if (a->lchild&&a->lchild->data == e || a->rchild&&a->rchild->data == e)/* 找到e(是其左或右孩子) */return a->data; /* 返回e的双亲的值 */else /* 没找到e,则入队其左右孩子指针(如果非空) */{if (a->lchild)EnQueue(&q, a->lchild);if (a->rchild)EnQueue(&q, a->rchild);}}}return Nil; /* 树空或没找到e */}BiTree Point(BiTree T, TElemType s){ /* 返回二叉树T中指向元素值为s的结点的指针。另加 */LinkQueue q;QElemType a;if (T) /* 非空树 */{InitQueue(&q); /* 初始化队列 */EnQueue(&q, T); /* 根结点入队 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &a); /* 出队,队列元素赋给a */if (a->data == s)return a;if (a->lchild) /* 有左孩子 */EnQueue(&q, a->lchild); /* 入队左孩子 */if (a->rchild) /* 有右孩子 */EnQueue(&q, a->rchild); /* 入队右孩子 */}}return NULL;}TElemType LeftChild(BiTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左孩子。若e无左孩子,则返回"空" */BiTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a->lchild) /* T中存在结点e且e存在左孩子 */return a->lchild->data; /* 返回e的左孩子的值 */}return Nil; /* 其余情况返回空 */}TElemType RightChild(BiTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右孩子。若e无右孩子,则返回"空" */BiTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a->rchild) /* T中存在结点e且e存在右孩子 */return a->rchild->data; /* 返回e的右孩子的值 */}return Nil; /* 其余情况返回空 */}TElemType LeftSibling(BiTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */TElemType a;BiTree p;if (T) /* 非空树 */{a = Parent(T, e); /* a为e的双亲 */p = Point(T, a); /* p为指向结点a的指针 */if (p->lchild&&p->rchild&&p->rchild->data == e) /* p存在左右孩子且右孩子是e */return p->lchild->data; /* 返回p的左孩子(e的左兄弟) */}return Nil; /* 树空或没找到e的左兄弟 */}TElemType RightSibling(BiTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回"空" */TElemType a;BiTree p;if (T) /* 非空树 */{a = Parent(T, e); /* a为e的双亲 */p = Point(T, a); /* p为指向结点a的指针 */if (p->lchild&&p->rchild&&p->lchild->data == e) /* p存在左右孩子且左孩子是e */return p->rchild->data; /* 返回p的右孩子(e的右兄弟) */}return Nil; /* 树空或没找到e的右兄弟 */}Status InsertChild(BiTree p, int LR, BiTree c) /* 形参T无用 */{ /* 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T *//*           不相交且右子树为空 *//* 操作结果: 根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的 *//*           原有左或右子树则成为c的右子树 */if (p) /* p不空 */{if (LR == 0){c->rchild = p->lchild;p->lchild = c;}else /* LR==1 */{c->rchild = p->rchild;p->rchild = c;}return OK;}return ERROR; /* p空 */}Status DeleteChild(BiTree p, int LR) /* 形参T无用 */{ /* 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1 *//* 操作结果: 根据LR为0或1,删除T中p所指结点的左或右子树 */if (p) /* p不空 */{if (LR == 0) /* 删除左子树 */ClearBiTree(&p->lchild);else /* 删除右子树 */ClearBiTree(&p->rchild);return OK;}return ERROR; /* p空 */}void PreOrderTraverse(BiTree T, Status(*Visit)(TElemType)){ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动 *//* 操作结果: 先序递归遍历T,对每个结点调用函数Visit一次且仅一次 */if (T) /* T不空 */{Visit(T->data); /* 先访问根结点 */PreOrderTraverse(T->lchild, Visit); /* 再先序遍历左子树 */PreOrderTraverse(T->rchild, Visit); /* 最后先序遍历右子树 */}}void InOrderTraverse(BiTree T, Status(*Visit)(TElemType)){ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 *//* 操作结果: 中序递归遍历T,对每个结点调用函数Visit一次且仅一次 */if (T){InOrderTraverse(T->lchild, Visit); /* 先中序遍历左子树 */Visit(T->data); /* 再访问根结点 */InOrderTraverse(T->rchild, Visit); /* 最后中序遍历右子树 */}}Status InOrderTraverse1(BiTree T, Status(*Visit)(TElemType)){ /* 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。算法6.3 *//* 中序遍历二叉树T的非递归算法(利用栈),对每个数据元素调用函数Visit */SqStack S;InitStack(&S);while (T || !StackEmpty(S)){if (T){ /* 根指针进栈,遍历左子树 */Push(&S, T);T = T->lchild;}else{ /* 根指针退栈,访问根结点,遍历右子树 */Pop(&S, &T);if (!Visit(T->data))return ERROR;T = T->rchild;}}printf("\n");return OK;}Status InOrderTraverse2(BiTree T, Status(*Visit)(TElemType)){ /* 采用二叉链表存储结构,Visit是对数据元素操作的应用函数。算法6.2 *//* 中序遍历二叉树T的非递归算法(利用栈),对每个数据元素调用函数Visit */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);if (!Visit(p->data))return ERROR;Push(&S, p->rchild);}}printf("\n");return OK;}void PostOrderTraverse(BiTree T, Status(*Visit)(TElemType)){ /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 *//* 操作结果: 后序递归遍历T,对每个结点调用函数Visit一次且仅一次 */if (T) /* T不空 */{PostOrderTraverse(T->lchild, Visit); /* 先后序遍历左子树 */PostOrderTraverse(T->rchild, Visit); /* 再后序遍历右子树 */Visit(T->data); /* 最后访问根结点 */}}void LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType)){ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数 *//* 操作结果:层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次 */LinkQueue q;QElemType a;if (T){InitQueue(&q);EnQueue(&q, T);while (!QueueEmpty(q)){DeQueue(&q, &a);Visit(a->data);if (a->lchild != NULL)EnQueue(&q, a->lchild);if (a->rchild != NULL)EnQueue(&q, a->rchild);}printf("\n");}}

#include "tree.h"static TElemType Nil = ' ';Status visitT(TElemType e){#ifdef CHARprintf("%c ", e);#endif#ifdef INTprintf("%d ", e);#endifreturn OK;}void 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)#ifdef CHARprintf("二叉树的根为: %c\n", e1);#endif#ifdef INTprintf("二叉树的根为: %d\n", e1);#endifelseprintf("树空,无根\n");#ifdef CHARprintf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");#endif#ifdef INTprintf("请先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n");#endifCreateBiTree(&T);printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));e1 = Root(T);if (e1 != Nil)#ifdef CHARprintf("二叉树的根为: %c\n", e1);#endif#ifdef INTprintf("二叉树的根为: %d\n", e1);#endifelseprintf("树空,无根\n");printf("中序递归遍历二叉树:\n");InOrderTraverse(T, visitT);printf("\n中序非递归遍历二叉树:\n");InOrderTraverse1(T, visitT);printf("中序非递归遍历二叉树(另一种方法):\n");InOrderTraverse2(T, visitT);printf("后序递归遍历二叉树:\n");PostOrderTraverse(T, visitT);printf("\n层序遍历二叉树:\n");LevelOrderTraverse(T, visitT);printf("请输入一个结点的值: ");#ifdef CHARscanf("%*c%c", &e1);#endif#ifdef INTscanf("%d", &e1);#endifp = Point(T, e1); /* p为e1的指针 */#ifdef CHARprintf("结点的值为%c\n", Value(p));#endif#ifdef INTprintf("结点的值为%d\n", Value(p));#endifprintf("欲改变此结点的值,请输入新值: ");#ifdef CHARscanf("%*c%c%*c", &e2);#endif#ifdef INTscanf("%d", &e2);#endifAssign(p, e2);printf("层序遍历二叉树:\n");LevelOrderTraverse(T, visitT);e1 = Parent(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的双亲是%c\n", e2, e1);#endif#ifdef INTprintf("%d的双亲是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有双亲\n", e2);#endif#ifdef INTprintf("%d没有双亲\n", e2);#endife1 = LeftChild(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的左孩子是%c\n", e2, e1);#endif#ifdef INTprintf("%d的左孩子是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有左孩子\n", e2);#endif#ifdef INTprintf("%d没有左孩子\n", e2);#endife1 = RightChild(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的右孩子是%c\n", e2, e1);#endif#ifdef INTprintf("%d的右孩子是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有右孩子\n", e2);#endif#ifdef INTprintf("%d没有右孩子\n", e2);#endife1 = LeftSibling(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的左兄弟是%c\n", e2, e1);#endif#ifdef INTprintf("%d的左兄弟是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有左兄弟\n", e2);#endif#ifdef INTprintf("%d没有左兄弟\n", e2);#endife1 = RightSibling(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的右兄弟是%c\n", e2, e1);#endif#ifdef INTprintf("%d的右兄弟是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有右兄弟\n", e2);#endif#ifdef INTprintf("%d没有右兄弟\n", e2);#endifInitBiTree(&c);printf("构造一个右子树为空的二叉树c:\n");#ifdef CHARprintf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");#endif#ifdef INTprintf("请先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n");#endifCreateBiTree(&c);printf("先序递归遍历二叉树c:\n");PreOrderTraverse(c, visitT);printf("\n树c插到树T中,请输入树T中树c的双亲结点 c为左(0)或右(1)子树: ");#ifdef CHARscanf("%*c%c%d", &e1, &i);#endif#ifdef INTscanf("%d%d", &e1, &i);#endifp = Point(T, e1); /* p是T中树c的双亲结点指针 */InsertChild(p, i, c);printf("先序递归遍历二叉树:\n");PreOrderTraverse(T, visitT);printf("\n删除子树,请输入待删除子树的双亲结点  左(0)或右(1)子树: ");#ifdef CHARscanf("%*c%c%d", &e1, &i);#endif#ifdef INTscanf("%d%d", &e1, &i);#endifp = Point(T, e1);DeleteChild(p, i);printf("先序递归遍历二叉树:\n");PreOrderTraverse(T, visitT);printf("\n");DestroyBiTree(&T);}

线索二叉树

#ifndef ELEMTYPE_H#define ELEMTYPE_H#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define CHAR 1/* 字符型 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#ifdef CHARtypedef char TElemType;//TElemType Nil = ' ';#endif#ifdef INTtypedef int TElemType;//TElemType Nil = 0;#endiftypedef enum{ Link, Thread }PointerTag; /* Link(0):指针,Thread(1):线索 */typedef struct BiThrNode{TElemType data;struct BiThrNode *lchild, *rchild; /* 左右孩子指针 */PointerTag LTag, RTag; /* 左右标志 */}BiThrNode, *BiThrTree;Status CreateBiThrTree(BiThrTree *T);void InThreading(BiThrTree p);Status InOrderThreading(BiThrTree *Thrt, BiThrTree T);Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType));#endif

#include "BiThTree.h"TElemType Nil = ' ';Status CreateBiThrTree(BiThrTree *T){ /* 按先序输入二叉线索树中结点的值,构造二叉线索树T *//* 0(整型)/空格(字符型)表示空结点 */TElemType h;#if CHARscanf("%c", &h);#elsescanf("%d", &h);#endifif (h == Nil)*T = NULL;else{*T = (BiThrTree)malloc(sizeof(BiThrNode));if (!*T)exit(OVERFLOW);(*T)->data = h; /* 生成根结点(先序) */CreateBiThrTree(&(*T)->lchild); /* 递归构造左子树 */if ((*T)->lchild) /* 有左孩子 */(*T)->LTag = Link;CreateBiThrTree(&(*T)->rchild); /* 递归构造右子树 */if ((*T)->rchild) /* 有右孩子 */(*T)->RTag = Link;}return OK;}BiThrTree pre; /* 全局变量,始终指向刚刚访问过的结点 */void InThreading(BiThrTree p){ /* 中序遍历进行中序线索化。算法6.7 */if (p){InThreading(p->lchild); /* 递归左子树线索化 */if (!p->lchild) /* 没有左孩子 */{p->LTag = Thread; /* 前驱线索 */p->lchild = pre; /* 左孩子指针指向前驱 */}if (!pre->rchild) /* 前驱没有右孩子 */{pre->RTag = Thread; /* 后继线索 */pre->rchild = p; /* 前驱右孩子指针指向后继(当前结点p) */}pre = p; /* 保持pre指向p的前驱 */InThreading(p->rchild); /* 递归右子树线索化 */}}Status InOrderThreading(BiThrTree *Thrt, BiThrTree T){ /* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点。算法6.6 */*Thrt = (BiThrTree)malloc(sizeof(BiThrNode));if (!*Thrt)exit(OVERFLOW);(*Thrt)->LTag = Link; /* 建头结点 */(*Thrt)->RTag = Thread;(*Thrt)->rchild = *Thrt; /* 右指针回指 */if (!T) /* 若二叉树空,则左指针回指 */(*Thrt)->lchild = *Thrt;else{(*Thrt)->lchild = T;pre = *Thrt;InThreading(T); /* 中序遍历进行中序线索化 */pre->rchild = *Thrt;pre->RTag = Thread; /* 最后一个结点线索化 */(*Thrt)->rchild = pre;}return OK;}Status InOrderTraverse_Thr(BiThrTree T, Status(*Visit)(TElemType)){ /* 中序遍历二叉线索树T(头结点)的非递归算法。算法6.5 */BiThrTree p;p = T->lchild; /* p指向根结点 */while (p != T){ /* 空树或遍历结束时,p==T */while (p->LTag == Link)p = p->lchild;if (!Visit(p->data)) /* 访问其左子树为空的结点 */return ERROR;while (p->RTag == Thread&&p->rchild != T){p = p->rchild;Visit(p->data); /* 访问后继结点 */}p = p->rchild;}return OK;}

#include "BiThTree.h"extern TElemType Nil;Status vi(TElemType c){#if CHARprintf("%c ", c);#elseprintf("%d ", c);#endifreturn OK;}void main(){BiThrTree H, T;#if CHARprintf("请按先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");#elseprintf("请按先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n");#endifCreateBiThrTree(&T); /* 按先序产生二叉树 */InOrderThreading(&H, T); /* 中序遍历,并中序线索化二叉树 */printf("中序遍历(输出)二叉线索树:\n");InOrderTraverse_Thr(H, vi); /* 中序遍历(输出)二叉线索树 */printf("\n");}

孩子兄弟表示法

#ifndef ELEMTYPE_H#define ELEMTYPE_H#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define CHAR 1/* 字符型 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#ifdef CHARtypedef char TElemType;//TElemType Nil = ' ';#endif#ifdef INTtypedef int TElemType;//TElemType Nil = 0;#endif/* c6-5.h 树的二叉链表(孩子-兄弟)存储表示 */typedef struct CSNode{TElemType data;struct CSNode *firstchild, *nextsibling;}CSNode, *CSTree;Status InitTree(CSTree *T);void DestroyTree(CSTree *T);Status CreateTree(CSTree *T);#define ClearTree DestroyTreeStatus TreeEmpty(CSTree T);int TreeDepth(CSTree T);TElemType Value(CSTree p);TElemType Root(CSTree T);CSTree Point(CSTree T, TElemType s);Status Assign(CSTree *T, TElemType cur_e, TElemType value);TElemType Parent(CSTree T, TElemType cur_e);TElemType LeftChild(CSTree T, TElemType cur_e);TElemType RightSibling(CSTree T, TElemType cur_e);Status InsertChild(CSTree *T, CSTree p, int i, CSTree c);Status DeleteChild(CSTree *T, CSTree p, int i);void PreOrderTraverse(CSTree T, void(*Visit)(TElemType));void PostOrderTraverse(CSTree T, void(*Visit)(TElemType));void LevelOrderTraverse(CSTree T, void(*Visit)(TElemType));#endif

#include "CSTree.h"#include "linkQueue.h"static TElemType Nil = ' ';Status InitTree(CSTree *T){ /* 操作结果: 构造空树T */*T = NULL;return OK;}void DestroyTree(CSTree *T){ /* 初始条件: 树T存在。操作结果: 销毁树T */if (*T){if ((*T)->firstchild) /* T有长子 */DestroyTree(&(*T)->firstchild); /* 销毁T的长子为根结点的子树 */if ((*T)->nextsibling) /* T有下一个兄弟 */DestroyTree(&(*T)->nextsibling); /* 销毁T的下一个兄弟为根结点的子树 */free(*T); /* 释放根结点 */*T = NULL;}}Status CreateTree(CSTree *T){ /* 构造树T */char c[20]; /* 临时存放孩子结点(设不超过20个)的值 */CSTree p, p1;LinkQueue q;int i, l;InitQueue(&q);printf("请输入根结点(字符型,空格为空): ");scanf("%c%*c", &c[0]);if (c[0] != Nil) /* 非空树 */{*T = (CSTree)malloc(sizeof(CSNode)); /* 建立根结点 */(*T)->data = c[0];(*T)->nextsibling = NULL;EnQueue(&q, *T); /* 入队根结点的指针 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &p); /* 出队一个结点的指针 */printf("请按长幼顺序输入结点%c的所有孩子: ", p->data);gets(c);l = strlen(c);if (l>0) /* 有孩子 */{p1 = p->firstchild = (CSTree)malloc(sizeof(CSNode)); /* 建立长子结点 */p1->data = c[0];for (i = 1; i<l; i++){p1->nextsibling = (CSTree)malloc(sizeof(CSNode)); /* 建立下一个兄弟结点 */EnQueue(&q, p1); /* 入队上一个结点 */p1 = p1->nextsibling;p1->data = c[i];}p1->nextsibling = NULL;EnQueue(&q, p1); /* 入队最后一个结点 */}elsep->firstchild = NULL;}}else*T = NULL;return OK;}Status TreeEmpty(CSTree T){ /* 初始条件: 树T存在。操作结果: 若T为空树,则返回TURE,否则返回FALSE */if (T) /* T不空 */return FALSE;elsereturn TRUE;}int TreeDepth(CSTree T){ /* 初始条件: 树T存在。操作结果: 返回T的深度 */CSTree p;int depth, max = 0;if (!T) /* 树空 */return 0;if (!T->firstchild) /* 树无长子 */return 1;for (p = T->firstchild; p; p = p->nextsibling){depth = TreeDepth(p);if (depth>max)max = depth;}return max + 1;}TElemType Value(CSTree p){ /* 返回p所指结点的值 */return p->data;}TElemType Root(CSTree T){ /* 初始条件: 树T存在。操作结果: 返回T的根 */if (T)return Value(T);elsereturn Nil;}CSTree Point(CSTree T, TElemType s){ /* 返回二叉链表(孩子-兄弟)树T中指向元素值为s的结点的指针。另加 */LinkQueue q;QElemType a;if (T) /* 非空树 */{InitQueue(&q); /* 初始化队列 */EnQueue(&q, T); /* 根结点入队 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &a); /* 出队,队列元素赋给a */if (a->data == s)return a;if (a->firstchild) /* 有长子 */EnQueue(&q, a->firstchild); /* 入队长子 */if (a->nextsibling) /* 有下一个兄弟 */EnQueue(&q, a->nextsibling); /* 入队下一个兄弟 */}}return NULL;}Status Assign(CSTree *T, TElemType cur_e, TElemType value){ /* 初始条件: 树T存在,cur_e是树T中结点的值。操作结果: 改cur_e为value */CSTree p;if (*T) /* 非空树 */{p = Point(*T, cur_e); /* p为cur_e的指针 */if (p) /* 找到cur_e */{p->data = value; /* 赋新值 */return OK;}}return Nil; /* 树空或没找到 */}TElemType Parent(CSTree T, TElemType cur_e){ /* 初始条件: 树T存在,cur_e是T中某个结点 *//* 操作结果: 若cur_e是T的非根结点,则返回它的双亲,否则函数值为"空" */CSTree p, t;LinkQueue q;InitQueue(&q);if (T) /* 树非空 */{if (Value(T) == cur_e) /* 根结点值为cur_e */return Nil;EnQueue(&q, T); /* 根结点入队 */while (!QueueEmpty(q)){DeQueue(&q, &p);if (p->firstchild) /* p有长子 */{if (p->firstchild->data == cur_e) /* 长子为cur_e */return Value(p); /* 返回双亲 */t = p; /* 双亲指针赋给t */p = p->firstchild; /* p指向长子 */EnQueue(&q, p); /* 入队长子 */while (p->nextsibling) /* 有下一个兄弟 */{p = p->nextsibling; /* p指向下一个兄弟 */if (Value(p) == cur_e) /* 下一个兄弟为cur_e */return Value(t); /* 返回双亲 */EnQueue(&q, p); /* 入队下一个兄弟 */}}}}return Nil; /* 树空或没找到cur_e */}TElemType LeftChild(CSTree T, TElemType cur_e){ /* 初始条件: 树T存在,cur_e是T中某个结点 *//* 操作结果: 若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回"空" */CSTree f;f = Point(T, cur_e); /* f指向结点cur_e */if (f&&f->firstchild) /* 找到结点cur_e且结点cur_e有长子 */return f->firstchild->data;elsereturn Nil;}TElemType RightSibling(CSTree T, TElemType cur_e){ /* 初始条件: 树T存在,cur_e是T中某个结点 *//* 操作结果: 若cur_e有右兄弟,则返回它的右兄弟,否则返回"空" */CSTree f;f = Point(T, cur_e); /* f指向结点cur_e */if (f&&f->nextsibling) /* 找到结点cur_e且结点cur_e有右兄弟 */return f->nextsibling->data;elsereturn Nil; /* 树空 */}Status InsertChild(CSTree *T, CSTree p, int i, CSTree c){ /* 初始条件: 树T存在,p指向T中某个结点,1≤i≤p所指结点的度+1,非空树c与T不相交 *//* 操作结果: 插入c为T中p结点的第i棵子树 *//* 因为p所指结点的地址不会改变,故p不需是引用类型 */int j;if (*T) /* T不空 */{if (i == 1) /* 插入c为p的长子 */{c->nextsibling = p->firstchild; /* p的原长子现是c的下一个兄弟(c本无兄弟) */p->firstchild = c;}else /* 找插入点 */{p = p->firstchild; /* 指向p的长子 */j = 2;while (p&&j<i){p = p->nextsibling;j++;}if (j == i) /* 找到插入位置 */{c->nextsibling = p->nextsibling;p->nextsibling = c;}else /* p原有孩子数小于i-1 */return ERROR;}return OK;}else /* T空 */return ERROR;}Status DeleteChild(CSTree *T, CSTree p, int i){ /* 初始条件: 树T存在,p指向T中某个结点,1≤i≤p所指结点的度 *//* 操作结果: 删除T中p所指结点的第i棵子树 *//* 因为p所指结点的地址不会改变,故p不需是引用类型 */CSTree b;int j;if (*T) /* T不空 */{if (i == 1) /* 删除长子 */{b = p->firstchild;p->firstchild = b->nextsibling; /* p的原次子现是长子 */b->nextsibling = NULL;DestroyTree(&b);}else /* 删除非长子 */{p = p->firstchild; /* p指向长子 */j = 2;while (p&&j<i){p = p->nextsibling;j++;}if (j == i) /* 找到第i棵子树 */{b = p->nextsibling;p->nextsibling = b->nextsibling;b->nextsibling = NULL;DestroyTree(&b);}else /* p原有孩子数小于i */return ERROR;}return OK;}elsereturn ERROR;}void PreOrderTraverse(CSTree T, void(*Visit)(TElemType)){ /* 先根遍历孩子-兄弟二叉链表结构的树T */if (T){Visit(Value(T)); /* 先访问根结点 */PreOrderTraverse(T->firstchild, Visit); /* 再先根遍历长子子树 */PreOrderTraverse(T->nextsibling, Visit); /* 最后先根遍历下一个兄弟子树 */}}void PostOrderTraverse(CSTree T, void(*Visit)(TElemType)){ /* 后根遍历孩子-兄弟二叉链表结构的树T */CSTree p;if (T){if (T->firstchild) /* 有长子 */{PostOrderTraverse(T->firstchild, Visit); /* 后根遍历长子子树 */p = T->firstchild->nextsibling; /* p指向长子的下一个兄弟 */while (p){PostOrderTraverse(p, Visit); /* 后根遍历下一个兄弟子树 */p = p->nextsibling; /* p指向再下一个兄弟 */}}Visit(Value(T)); /* 最后访问根结点 */}}void LevelOrderTraverse(CSTree T, void(*Visit)(TElemType)){ /* 层序遍历孩子-兄弟二叉链表结构的树T */CSTree p;LinkQueue q;InitQueue(&q);if (T){Visit(Value(T)); /* 先访问根结点 */EnQueue(&q, T); /* 入队根结点的指针 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &p); /* 出队一个结点的指针 */if (p->firstchild) /* 有长子 */{p = p->firstchild;Visit(Value(p)); /* 访问长子结点 */EnQueue(&q, p); /* 入队长子结点的指针 */while (p->nextsibling) /* 有下一个兄弟 */{p = p->nextsibling;Visit(Value(p)); /* 访问下一个兄弟 */EnQueue(&q, p); /* 入队兄弟结点的指针 */}}}}}

#include "CSTree.h"static TElemType Nil = ' '; /* 以空格符为空 */void vi(TElemType c){printf("%c ", c);}void main(){int i;CSTree T, p, q;TElemType e, e1;InitTree(&T);printf("构造空树后,树空否? %d(1:是 0:否) 树根为%c 树的深度为%d\n", TreeEmpty(T), Root(T), TreeDepth(T));CreateTree(&T);printf("构造树T后,树空否? %d(1:是 0:否) 树根为%c 树的深度为%d\n", TreeEmpty(T), Root(T), TreeDepth(T));printf("先根遍历树T:\n");PreOrderTraverse(T, vi);printf("\n请输入待修改的结点的值 新值: ");scanf("%c%*c%c%*c", &e, &e1);Assign(&T, e, e1);printf("后根遍历修改后的树T:\n");PostOrderTraverse(T, vi);printf("\n%c的双亲是%c,长子是%c,下一个兄弟是%c\n", e1, Parent(T, e1), LeftChild(T, e1), RightSibling(T, e1));printf("建立树p:\n");InitTree(&p);CreateTree(&p);printf("层序遍历树p:\n");LevelOrderTraverse(p, vi);printf("\n将树p插到树T中,请输入T中p的双亲结点 子树序号: ");scanf("%c%d%*c", &e, &i);q = Point(T, e);InsertChild(&T, q, i, p);printf("层序遍历树T:\n");LevelOrderTraverse(T, vi);printf("\n删除树T中结点e的第i棵子树,请输入e i: ");scanf("%c%d", &e, &i);q = Point(T, e);DeleteChild(&T, q, i);printf("层序遍历树T:\n", e, i);LevelOrderTraverse(T, vi);printf("\n");DestroyTree(&T);}

双亲表示法

#ifndef ELEMTYPE_H#define ELEMTYPE_H#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define CHAR 1/* 字符型 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#ifdef CHARtypedef char TElemType;//TElemType Nil = ' ';#endif#ifdef INTtypedef int TElemType;//TElemType Nil = 0;#endif#define MAX_TREE_SIZE 100typedef struct{TElemType data;int parent; /* 双亲位置域 */} PTNode;typedef struct{PTNode nodes[MAX_TREE_SIZE];int n; /* 结点数 */} PTree;Status InitTree(PTree *T);void DestroyTree();Status CreateTree(PTree *T);#define ClearTree InitTreeStatus TreeEmpty(PTree T);int TreeDepth(PTree T);TElemType Root(PTree T);TElemType Value(PTree T, int i);Status Assign(PTree *T, TElemType cur_e, TElemType value);TElemType Parent(PTree T, TElemType cur_e);TElemType LeftChild(PTree T, TElemType cur_e);TElemType RightSibling(PTree T, TElemType cur_e);Status Print(PTree T);Status InsertChild(PTree *T, TElemType p, int i, PTree c);void DeleteChild(PTree *T, TElemType p, int i);void TraverseTree(PTree T, void(*Visit)(TElemType));#endif

#include "PaTree.h"#include "linkQueue.h"static TElemType Nil = ' ';Status InitTree(PTree *T){ /* 操作结果: 构造空树T */(*T).n = 0;return OK;}void DestroyTree(){ /* 由于PTree是定长类型,无法销毁 */}Status CreateTree(PTree *T){ /* 操作结果: 构造树T */LinkQueue q;QElemType p, qq;int i = 1, j, l;char c[MAX_TREE_SIZE]; /* 临时存放孩子结点数组 */InitQueue(&q); /* 初始化队列 */printf("请输入根结点(字符型,空格为空): ");scanf("%c%*c", &(*T).nodes[0].data); /* 根结点序号为0,%*c吃掉回车符 */if ((*T).nodes[0].data != Nil) /* 非空树 */{(*T).nodes[0].parent = -1; /* 根结点无双亲 */qq.name = (*T).nodes[0].data;qq.num = 0;EnQueue(&q, qq); /* 入队此结点 */while (i<MAX_TREE_SIZE&&!QueueEmpty(q)) /* 数组未满且队不空 */{DeQueue(&q, &qq); /* 出队一个结点 */printf("请按长幼顺序输入结点%c的所有孩子: ", qq.name);gets(c);l = strlen(c);for (j = 0; j<l; j++){(*T).nodes[i].data = c[j];(*T).nodes[i].parent = qq.num;p.name = c[j];p.num = i;EnQueue(&q, p); /* 入队此结点 */i++;}}if (i>MAX_TREE_SIZE){printf("结点数超过数组容量\n");exit(OVERFLOW);}(*T).n = i;}else(*T).n = 0;return OK;}#define ClearTree InitTree /* 二者操作相同 */Status TreeEmpty(PTree T){ /* 初始条件: 树T存在。操作结果: 若T为空树,则返回TRUE,否则返回FALSE */if (T.n)return FALSE;elsereturn TRUE;}int TreeDepth(PTree T){ /* 初始条件: 树T存在。操作结果: 返回T的深度 */int k, m, def, max = 0;for (k = 0; k<T.n; ++k){def = 1; /* 初始化本际点的深度 */m = T.nodes[k].parent;while (m != -1){m = T.nodes[m].parent;def++;}if (max<def)max = def;}return max; /* 最大深度 */}TElemType Root(PTree T){ /* 初始条件: 树T存在。操作结果: 返回T的根 */int i;for (i = 0; i<T.n; i++)if (T.nodes[i].parent<0)return T.nodes[i].data;return Nil;}TElemType Value(PTree T, int i){ /* 初始条件: 树T存在,i是树T中结点的序号。操作结果: 返回第i个结点的值 */if (i<T.n)return T.nodes[i].data;elsereturn Nil;}Status Assign(PTree *T, TElemType cur_e, TElemType value){ /* 初始条件: 树T存在,cur_e是树T中结点的值。操作结果: 改cur_e为value */int j;for (j = 0; j<(*T).n; j++){if ((*T).nodes[j].data == cur_e){(*T).nodes[j].data = value;return OK;}}return ERROR;}TElemType Parent(PTree T, TElemType cur_e){ /* 初始条件: 树T存在,cur_e是T中某个结点 *//* 操作结果: 若cur_e是T的非根结点,则返回它的双亲,否则函数值为"空" */int j;for (j = 1; j<T.n; j++) /* 根结点序号为0 */if (T.nodes[j].data == cur_e)return T.nodes[T.nodes[j].parent].data;return Nil;}TElemType LeftChild(PTree T, TElemType cur_e){ /* 初始条件: 树T存在,cur_e是T中某个结点 *//* 操作结果: 若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回"空" */int i, j;for (i = 0; i<T.n; i++)if (T.nodes[i].data == cur_e) /* 找到cur_e,其序号为i */break;for (j = i + 1; j<T.n; j++) /* 根据树的构造函数,孩子的序号>其双亲的序号 */if (T.nodes[j].parent == i) /* 根据树的构造函数,最左孩子(长子)的序号<其它孩子的序号 */return T.nodes[j].data;return Nil;}TElemType RightSibling(PTree T, TElemType cur_e){ /* 初始条件: 树T存在,cur_e是T中某个结点 *//* 操作结果: 若cur_e有右(下一个)兄弟,则返回它的右兄弟,否则返回"空" */int i;for (i = 0; i<T.n; i++)if (T.nodes[i].data == cur_e) /* 找到cur_e,其序号为i */break;if (T.nodes[i + 1].parent == T.nodes[i].parent)/* 根据树的构造函数,若cur_e有右兄弟的话则右兄弟紧接其后 */return T.nodes[i + 1].data;return Nil;}Status Print(PTree T){ /* 输出树T。加 */int i;printf("结点个数=%d\n", T.n);printf(" 结点 双亲\n");for (i = 0; i<T.n; i++){printf("    %c", Value(T, i)); /* 结点 */if (T.nodes[i].parent >= 0) /* 有双亲 */printf("    %c", Value(T, T.nodes[i].parent)); /* 双亲 */printf("\n");}return OK;}Status InsertChild(PTree *T, TElemType p, int i, PTree c){ /* 初始条件: 树T存在,p是T中某个结点,1≤i≤p所指结点的度+1,非空树c与T不相交 *//* 操作结果: 插入c为T中p结点的第i棵子树 */int j, k, l, f = 1, n = 0; /* 设交换标志f的初值为1,p的孩子数n的初值为0 */PTNode t;if (!TreeEmpty(*T)) /* T不空 */{for (j = 0; j<(*T).n; j++) /* 在T中找p的序号 */if ((*T).nodes[j].data == p) /* p的序号为j */break;l = j + 1; /* 如果c是p的第1棵子树,则插在j+1处 */if (i>1) /* c不是p的第1棵子树 */{for (k = j + 1; k<(*T).n; k++) /* 从j+1开始找p的前i-1个孩子 */if ((*T).nodes[k].parent == j) /* 当前结点是p的孩子 */{n++; /* 孩子数加1 */if (n == i - 1) /* 找到p的第i-1个孩子,其序号为k1 */break;}l = k + 1; /* c插在k+1处 */} /* p的序号为j,c插在l处 */if (l<(*T).n) /* 插入点l不在最后 */for (k = (*T).n - 1; k >= l; k--) /* 依次将序号l以后的结点向后移c.n个位置 */{(*T).nodes[k + c.n] = (*T).nodes[k];if ((*T).nodes[k].parent >= l)(*T).nodes[k + c.n].parent += c.n;}for (k = 0; k<c.n; k++){(*T).nodes[l + k].data = c.nodes[k].data; /* 依次将树c的所有结点插于此处 */(*T).nodes[l + k].parent = c.nodes[k].parent + l;}(*T).nodes[l].parent = j; /* 树c的根结点的双亲为p */(*T).n += c.n; /* 树T的结点数加c.n个 */while (f){ /* 从插入点之后,将结点仍按层序排列 */f = 0; /* 交换标志置0 */for (j = l; j<(*T).n - 1; j++)if ((*T).nodes[j].parent>(*T).nodes[j + 1].parent){/* 如果结点j的双亲排在结点j+1的双亲之后(树没有按层序排列),交换两结点*/t = (*T).nodes[j];(*T).nodes[j] = (*T).nodes[j + 1];(*T).nodes[j + 1] = t;f = 1; /* 交换标志置1 */for (k = j; k<(*T).n; k++) /* 改变双亲序号 */if ((*T).nodes[k].parent == j)(*T).nodes[k].parent++; /* 双亲序号改为j+1 */else if ((*T).nodes[k].parent == j + 1)(*T).nodes[k].parent--; /* 双亲序号改为j */}}return OK;}else /* 树T不存在 */return ERROR;}Status deleted[MAX_TREE_SIZE + 1]; /* 删除标志数组(全局量) */void DeleteChild(PTree *T, TElemType p, int i){ /* 初始条件: 树T存在,p是T中某个结点,1≤i≤p所指结点的度 *//* 操作结果: 删除T中结点p的第i棵子树 */int j, k, n = 0;LinkQueue q;QElemType pq, qq;for (j = 0; j <= (*T).n; j++)deleted[j] = 0; /* 置初值为0(不删除标记) */pq.name = 'a'; /* 此成员不用 */InitQueue(&q); /* 初始化队列 */for (j = 0; j<(*T).n; j++)if ((*T).nodes[j].data == p)break; /* j为结点p的序号 */for (k = j + 1; k<(*T).n; k++){if ((*T).nodes[k].parent == j)n++;if (n == i)break; /* k为p的第i棵子树结点的序号 */}if (k<(*T).n) /* p的第i棵子树结点存在 */{n = 0;pq.num = k;deleted[k] = 1; /* 置删除标记 */n++;EnQueue(&q, pq);while (!QueueEmpty(q)){DeQueue(&q, &qq);for (j = qq.num + 1; j<(*T).n; j++)if ((*T).nodes[j].parent == qq.num){pq.num = j;deleted[j] = 1; /* 置删除标记 */n++;EnQueue(&q, pq);}}for (j = 0; j<(*T).n; j++)if (deleted[j] == 1){for (k = j + 1; k <= (*T).n; k++){deleted[k - 1] = deleted[k];(*T).nodes[k - 1] = (*T).nodes[k];if ((*T).nodes[k].parent>j)(*T).nodes[k - 1].parent--;}j--;}(*T).n -= n; /* n为待删除结点数 */}}void TraverseTree(PTree T, void(*Visit)(TElemType)){ /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数 *//* 操作结果:层序遍历树T,对每个结点调用函数Visit一次且仅一次 */int i;for (i = 0; i<T.n; i++)Visit(T.nodes[i].data);printf("\n");}

#include "PaTree.h"void vi(TElemType c){printf("%c ", c);}void main(){int i;PTree T, p;TElemType e, e1;InitTree(&T);printf("构造空树后,树空否? %d(1:是 0:否) 树根为%c 树的深度为%d\n", TreeEmpty(T), Root(T), TreeDepth(T));CreateTree(&T);printf("构造树T后,树空否? %d(1:是 0:否) 树根为%c 树的深度为%d\n", TreeEmpty(T), Root(T), TreeDepth(T));printf("层序遍历树T:\n");TraverseTree(T, vi);printf("请输入待修改的结点的值 新值: ");scanf("%c%*c%c%*c", &e, &e1);Assign(&T, e, e1);printf("层序遍历修改后的树T:\n");TraverseTree(T, vi);printf("%c的双亲是%c,长子是%c,下一个兄弟是%c\n", e1, Parent(T, e1), LeftChild(T, e1), RightSibling(T, e1));printf("建立树p:\n");InitTree(&p);CreateTree(&p);printf("层序遍历树p:\n");TraverseTree(p, vi);printf("将树p插到树T中,请输入T中p的双亲结点 子树序号: ");scanf("%c%d%*c", &e, &i);InsertChild(&T, e, i, p);Print(T);printf("删除树T中结点e的第i棵子树,请输入e i: ");scanf("%c%d", &e, &i);DeleteChild(&T, e, i);Print(T);}

三叉链表表示形式

#ifndef ELEMTYPE_H#define ELEMTYPE_H#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define CHAR 1/* 字符型 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#ifdef CHARtypedef char TElemType;//TElemType Nil = ' ';#endif#ifdef INTtypedef int TElemType;//TElemType Nil = 0;#endiftypedef struct BiTPNode{TElemType data;struct BiTPNode *parent, *lchild, *rchild; /* 双亲、左右孩子指针 */}BiTPNode, *BiPTree;Status InitBiTree(BiPTree *T);void DestroyBiTree(BiPTree *T);void Create(BiPTree *T);Status CreateBiTree(BiPTree *T);#define ClearBiTree DestroyBiTreeStatus BiTreeEmpty(BiPTree T);int BiTreeDepth(BiPTree T);TElemType Root(BiPTree T);TElemType Value(BiPTree p);void Assign(BiPTree p, TElemType value);BiPTree Point(BiPTree T, TElemType e);TElemType Parent(BiPTree T, TElemType e);TElemType LeftChild(BiPTree T, TElemType e);TElemType RightChild(BiPTree T, TElemType e);TElemType LeftSibling(BiPTree T, TElemType e);TElemType RightSibling(BiPTree T, TElemType e);Status InsertChild(BiPTree p, int LR, BiPTree c);Status DeleteChild(BiPTree p, int LR);void PreOrderTraverse(BiPTree T, Status(*Visit)(BiPTree));void InOrderTraverse(BiPTree T, Status(*Visit)(BiPTree));void PostOrderTraverse(BiPTree T, Status(*Visit)(BiPTree));void LevelOrderTraverse(BiPTree T, Status(*Visit)(BiPTree));#endif

#include "SanTree.h"#include "linkQueue.h"static TElemType Nil = ' ';Status InitBiTree(BiPTree *T){ /* 操作结果: 构造空二叉树T */*T = NULL;return OK;}void DestroyBiTree(BiPTree *T){ /* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */if (*T) /* 非空树 */{if ((*T)->lchild) /* 有左孩子 */DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */if ((*T)->rchild) /* 有右孩子 */DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */free(*T); /* 释放根结点 */*T = NULL; /* 空指针赋0 */}}void Create(BiPTree *T) /* CreateBiTree()调用 */{ /* 按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义), *//* 构造仅缺双亲指针的三叉链表表示的二叉树T。变量Nil表示空(子)树 */TElemType ch;#ifdef CHARscanf("%c", &ch);#endif#ifdef INTscanf("%d", &ch);#endifif (ch == Nil) /* 空 */*T = NULL;else{*T = (BiPTree)malloc(sizeof(BiTPNode));if (!*T)exit(OVERFLOW);(*T)->data = ch; /* 生成根结点 */Create(&(*T)->lchild); /* 构造左子树 */Create(&(*T)->rchild); /* 构造右子树 */}}Status CreateBiTree(BiPTree *T){ /* 按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中定义), *//* 构造三叉链表表示的二叉树T */LinkQueue q;QElemType a;Create(T); /* 构造二叉树(缺双亲指针) */if (*T) /* 非空树 */{(*T)->parent = NULL; /* 根结点的双亲为"空" */InitQueue(&q); /* 初始化队列 */EnQueue(&q, *T); /* 根指针入队 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &a); /* 出队,队列元素赋给a */if (a->lchild) /* 有左孩子 */{a->lchild->parent = a; /* 给左孩子的双亲指针赋值 */EnQueue(&q, a->lchild); /* 左孩子入队 */}if (a->rchild) /* 有右孩子 */{a->rchild->parent = a; /* 给右孩子的双亲指针赋值 */EnQueue(&q, a->rchild); /* 右孩子入队 */}}}return OK;}#define ClearBiTree DestroyBiTreeStatus BiTreeEmpty(BiPTree T){ /* 初始条件: 二叉树T存在。操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */if (T)return FALSE;elsereturn TRUE;}int BiTreeDepth(BiPTree T){ /* 初始条件: 二叉树T存在。操作结果: 返回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(BiPTree T){ /* 初始条件: 二叉树T存在。操作结果: 返回T的根 */if (T)return T->data;elsereturn Nil;}TElemType Value(BiPTree p){ /* 初始条件: 二叉树T存在,p指向T中某个结点 *//* 操作结果: 返回p所指结点的值 */return p->data;}void Assign(BiPTree p, TElemType value){ /* 给p所指结点赋值为value */p->data = value;}BiPTree Point(BiPTree T, TElemType e){ /* 返回二叉树T中指向元素值为e的结点的指针。加 */LinkQueue q;QElemType a;if (T) /* 非空树 */{InitQueue(&q); /* 初始化队列 */EnQueue(&q, T); /* 根结点入队 */while (!QueueEmpty(q)) /* 队不空 */{DeQueue(&q, &a); /* 出队,队列元素赋给a */if (a->data == e)return a;if (a->lchild) /* 有左孩子 */EnQueue(&q, a->lchild); /* 入队左孩子 */if (a->rchild) /* 有右孩子 */EnQueue(&q, a->rchild); /* 入队右孩子 */}}return NULL;}TElemType Parent(BiPTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */BiPTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a != T) /* T中存在结点e且e是非根结点 */return a->parent->data; /* 返回e的双亲的值 */}return Nil; /* 其余情况返回空 */}TElemType LeftChild(BiPTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左孩子。若e无左孩子,则返回"空" */BiPTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a->lchild) /* T中存在结点e且e存在左孩子 */return a->lchild->data; /* 返回e的左孩子的值 */}return Nil; /* 其余情况返回空 */}TElemType RightChild(BiPTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右孩子。若e无右孩子,则返回"空" */BiPTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a->rchild) /* T中存在结点e且e存在右孩子 */return a->rchild->data; /* 返回e的右孩子的值 */}return Nil; /* 其余情况返回空 */}TElemType LeftSibling(BiPTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */BiPTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a != T&&a->parent->lchild&&a->parent->lchild != a) /* T中存在结点e且e存在左兄弟 */return a->parent->lchild->data; /* 返回e的左兄弟的值 */}return Nil; /* 其余情况返回空 */}TElemType RightSibling(BiPTree T, TElemType e){ /* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回"空" */BiPTree a;if (T) /* 非空树 */{a = Point(T, e); /* a是结点e的指针 */if (a&&a != T&&a->parent->rchild&&a->parent->rchild != a) /* T中存在结点e且e存在右兄弟 */return a->parent->rchild->data; /* 返回e的右兄弟的值 */}return Nil; /* 其余情况返回空 */}Status InsertChild(BiPTree p, int LR, BiPTree c) /* 形参T无用 */{ /* 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1,非空二叉树c与T *//*           不相交且右子树为空 *//* 操作结果: 根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点 *//*           的原有左或右子树则成为c的右子树。 */if (p) /* p不空 */{if (LR == 0){c->rchild = p->lchild;if (c->rchild) /* c有右孩子(p原有左孩子) */c->rchild->parent = c;p->lchild = c;c->parent = p;}else /* LR==1 */{c->rchild = p->rchild;if (c->rchild) /* c有右孩子(p原有右孩子) */c->rchild->parent = c;p->rchild = c;c->parent = p;}return OK;}return ERROR; /* p空 */}Status DeleteChild(BiPTree p, int LR) /* 形参T无用 */{ /* 初始条件: 二叉树T存在,p指向T中某个结点,LR为0或1 *//* 操作结果: 根据LR为0或1,删除T中p所指结点的左或右子树 */if (p) /* p不空 */{if (LR == 0) /* 删除左子树 */ClearBiTree(&p->lchild);else /* 删除右子树 */ClearBiTree(&p->rchild);return OK;}return ERROR; /* p空 */}void PreOrderTraverse(BiPTree T, Status(*Visit)(BiPTree)){ /* 先序递归遍历二叉树T */if (T){Visit(T); /* 先访问根结点 */PreOrderTraverse(T->lchild, Visit); /* 再先序遍历左子树 */PreOrderTraverse(T->rchild, Visit); /* 最后先序遍历右子树 */}}void InOrderTraverse(BiPTree T, Status(*Visit)(BiPTree)){ /* 中序递归遍历二叉树T */if (T){InOrderTraverse(T->lchild, Visit); /* 中序遍历左子树 */Visit(T); /* 再访问根结点 */InOrderTraverse(T->rchild, Visit); /* 最后中序遍历右子树 */}}void PostOrderTraverse(BiPTree T, Status(*Visit)(BiPTree)){ /* 后序递归遍历二叉树T */if (T){PostOrderTraverse(T->lchild, Visit); /* 后序遍历左子树 */PostOrderTraverse(T->rchild, Visit); /* 后序遍历右子树 */Visit(T); /* 最后访问根结点 */}}void LevelOrderTraverse(BiPTree T, Status(*Visit)(BiPTree)){ /* 层序遍历二叉树T(利用队列) */LinkQueue q;QElemType a;if (T){InitQueue(&q);EnQueue(&q, T);while (!QueueEmpty(q)){DeQueue(&q, &a);Visit(a);if (a->lchild != NULL)EnQueue(&q, a->lchild);if (a->rchild != NULL)EnQueue(&q, a->rchild);}}}

#include "SanTree.h"static TElemType Nil = ' ';Status visitT(BiPTree T){if (T) /* T非空 */#ifdef CHARprintf("%c是", T->data);if (T->parent) /* T有双亲 */{printf("%c", T->parent->data);#endif#ifdef INTprintf("%d是", T->data);if (T->parent) /* T有双亲 */{printf("%d", T->parent->data);#endifif (T->parent->lchild == T)printf("的左孩子\n");elseprintf("的右孩子\n");}elseprintf("根结点\n");return OK;}void main(){int i;BiPTree T, c, q;TElemType e1, e2;InitBiTree(&T);printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));e1 = Root(T);if (e1 != Nil)#ifdef CHARprintf("二叉树的根为: %c\n", e1);#endif#ifdef INTprintf("二叉树的根为: %d\n", e1);#endifelseprintf("树空,无根\n");#ifdef CHARprintf("请按先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");#endif#ifdef INTprintf("请按先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n");#endifCreateBiTree(&T);printf("建立二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));e1 = Root(T);if (e1 != Nil)#ifdef CHARprintf("二叉树的根为: %c\n", e1);#endif#ifdef INTprintf("二叉树的根为: %d\n", e1);#endifelseprintf("树空,无根\n");printf("中序递归遍历二叉树:\n");InOrderTraverse(T, visitT);printf("后序递归遍历二叉树:\n");PostOrderTraverse(T, visitT);scanf("%*c"); /* 吃掉回车符 */printf("按回车键继续:");getchar(); /* 暂停输出 */printf("层序遍历二叉树:\n");LevelOrderTraverse(T, visitT);printf("请输入一个结点的值: ");#ifdef CHARscanf("%c", &e1);#endif#ifdef INTscanf("%d", &e1);#endifc = Point(T, e1); /* c为e1的指针 */#ifdef CHARprintf("结点的值为%c\n", Value(c));#endif#ifdef INTprintf("结点的值为%d\n", Value(c));#endifprintf("欲改变此结点的值,请输入新值: ");#ifdef CHARscanf("%*c%c%*c", &e2);#endif#ifdef INTscanf("%d", &e2);#endifAssign(c, e2);printf("层序遍历二叉树:\n");LevelOrderTraverse(T, visitT);e1 = Parent(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的双亲是%c\n", e2, e1);#endif#ifdef INTprintf("%d的双亲是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有双亲\n", e2);#endif#ifdef INTprintf("%d没有双亲\n", e2);#endife1 = LeftChild(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的左孩子是%c\n", e2, e1);#endif#ifdef INTprintf("%d的左孩子是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有左孩子\n", e2);#endif#ifdef INTprintf("%d没有左孩子\n", e2);#endife1 = RightChild(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的右孩子是%c\n", e2, e1);#endif#ifdef INTprintf("%d的右孩子是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有右孩子\n", e2);#endif#ifdef INTprintf("%d没有右孩子\n", e2);#endife1 = LeftSibling(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的左兄弟是%c\n", e2, e1);#endif#ifdef INTprintf("%d的左兄弟是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有左兄弟\n", e2);#endif#ifdef INTprintf("%d没有左兄弟\n", e2);#endife1 = RightSibling(T, e2);if (e1 != Nil)#ifdef CHARprintf("%c的右兄弟是%c\n", e2, e1);#endif#ifdef INTprintf("%d的右兄弟是%d\n", e2, e1);#endifelse#ifdef CHARprintf("%c没有右兄弟\n", e2);#endif#ifdef INTprintf("%d没有右兄弟\n", e2);#endif InitBiTree(&c);printf("构造一个右子树为空的二叉树c:\n");#ifdef CHARprintf("请先序输入二叉树(如:ab三个空格表示a为根结点,b为左子树的二叉树)\n");#endif#ifdef INTprintf("请先序输入二叉树(如:1 2 0 0 0表示1为根结点,2为左子树的二叉树)\n");#endifCreateBiTree(&c);printf("先序递归遍历二叉树c:\n");PreOrderTraverse(c, visitT);printf("树c插到树T中,请输入树T中树c的双亲结点 c为左(0)或右(1)子树: ");#ifdef CHARscanf("%*c%c%d", &e1, &i);#endif#ifdef INTscanf("%d%d", &e1, &i);#endifq = Point(T, e1);InsertChild(q, i, c);printf("先序递归遍历二叉树:\n");PreOrderTraverse(T, visitT);printf("删除子树,请输入待删除子树的双亲结点  左(0)或右(1)子树: ");#ifdef CHARscanf("%*c%c%d", &e1, &i);#endif#ifdef INTscanf("%d%d", &e1, &i);#endifq = Point(T, e1);DeleteChild(q, i);printf("先序递归遍历二叉树:\n");PreOrderTraverse(T, visitT);DestroyBiTree(&T);}



0 0
原创粉丝点击