数据结构-树

来源:互联网 发布:如何申请农村淘宝 编辑:程序博客网 时间:2024/06/15 19:36

1、顺序二叉树的实现

#include "stdio.h"    #include "stdlib.h"   //#include "io.h"  #include "math.h"  //#include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */#define MAX_TREE_SIZE 100 /* 二叉树的最大结点数 */typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int TElemType;  /* 树结点的数据类型,目前暂定为整型 */typedef TElemType SqBiTree[MAX_TREE_SIZE]; /* 0号单元存储根结点  */typedef struct{int level, order; /* 结点的层,本层序号(按满二叉树计算) */}Position;TElemType Nil = 0; /*  设整型以0为空 */Status visit(TElemType c){printf("%d ", c);return OK;}/* 构造空二叉树T。因为T是固定数组,不会改变,故不需要& */Status InitBiTree(SqBiTree T){int i;for (i = 0; i<MAX_TREE_SIZE; i++)T[i] = Nil; /* 初值为空 */return OK;}/* 按层序次序输入二叉树中结点的值(字符型或整型), 构造顺序存储的二叉树T */Status CreateBiTree(SqBiTree T){int i = 0;printf("请按层序输入结点的值(整型),0表示空结点,输999结束。结点数≤%d:\n", MAX_TREE_SIZE);while (i<10){T[i] = i + 1;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++;}return OK;}#define ClearBiTree InitBiTree /* 在顺序存储结构中,两函数完全一样 *//* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */Status BiTreeEmpty(SqBiTree T){if (T[0] == Nil) /* 根结点为空,则树空 */return TRUE;elsereturn FALSE;}/* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */int BiTreeDepth(SqBiTree T){int i, j = -1;for (i = MAX_TREE_SIZE - 1; i >= 0; i--) /* 找到最后一个结点 */if (T[i] != Nil)break;i++;doj++;while (i >= powl(2, j));/* 计算2的j次幂。 */return j;}/* 初始条件: 二叉树T存在 *//* 操作结果:  当T不空,用e返回T的根,返回OK;否则返回ERROR,e无定义 */Status Root(SqBiTree T, TElemType *e){if (BiTreeEmpty(T)) /* T空 */return ERROR;else{*e = T[0];return OK;}}/* 初始条件: 二叉树T存在,e是T中某个结点(的位置) *//* 操作结果: 返回处于位置e(层,本层序号)的结点的值 */TElemType Value(SqBiTree T, Position e){return T[(int)powl(2, e.level - 1) + e.order - 2];}/* 初始条件: 二叉树T存在,e是T中某个结点(的位置) *//* 操作结果: 给处于位置e(层,本层序号)的结点赋新值value */Status Assign(SqBiTree T, Position e, TElemType value){int i = (int)powl(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;}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 若e是T的非根结点,则返回它的双亲,否则返回"空" */TElemType Parent(SqBiTree T, TElemType e){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 */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左孩子。若e无左孩子,则返回"空" */TElemType LeftChild(SqBiTree T, TElemType 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 */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右孩子。若e无右孩子,则返回"空" */TElemType RightChild(SqBiTree T, TElemType 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 */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的左兄弟。若e是T的左孩子或无左兄弟,则返回"空" */TElemType LeftSibling(SqBiTree T, TElemType e){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 */}/* 初始条件: 二叉树T存在,e是T中某个结点 *//* 操作结果: 返回e的右兄弟。若e是T的右孩子或无右兄弟,则返回"空" */TElemType RightSibling(SqBiTree T, TElemType e){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 */}/* PreOrderTraverse()调用 */void PreTraverse(SqBiTree T, int e){visit(T[e]);if (T[2 * e + 1] != Nil) /* 左子树不空 */PreTraverse(T, 2 * e + 1);if (T[2 * e + 2] != Nil) /* 右子树不空 */PreTraverse(T, 2 * e + 2);}/* 初始条件: 二叉树存在 *//* 操作结果: 先序遍历T。 */Status PreOrderTraverse(SqBiTree T){if (!BiTreeEmpty(T)) /* 树不空 */PreTraverse(T, 0);printf("\n");return OK;}/* InOrderTraverse()调用 */void InTraverse(SqBiTree T, int e){if (T[2 * e + 1] != Nil) /* 左子树不空 */InTraverse(T, 2 * e + 1);visit(T[e]);if (T[2 * e + 2] != Nil) /* 右子树不空 */InTraverse(T, 2 * e + 2);}/* 初始条件: 二叉树存在 *//* 操作结果: 中序遍历T。 */Status InOrderTraverse(SqBiTree T){if (!BiTreeEmpty(T)) /* 树不空 */InTraverse(T, 0);printf("\n");return OK;}/* PostOrderTraverse()调用 */void PostTraverse(SqBiTree T, int e){if (T[2 * e + 1] != Nil) /* 左子树不空 */PostTraverse(T, 2 * e + 1);if (T[2 * e + 2] != Nil) /* 右子树不空 */PostTraverse(T, 2 * e + 2);visit(T[e]);}/* 初始条件: 二叉树T存在 *//* 操作结果: 后序遍历T。 */Status PostOrderTraverse(SqBiTree T){if (!BiTreeEmpty(T)) /* 树不空 */PostTraverse(T, 0);printf("\n");return OK;}/* 层序遍历二叉树 */void LevelOrderTraverse(SqBiTree T){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;TElemType e;for (j = 1; j <= BiTreeDepth(T); j++){printf("第%d层: ", j);for (k = 1; k <= powl(2, j - 1); k++){p.level = j;p.order = k;e = Value(T, p);if (e != Nil)printf("%d:%d ", k, e);}printf("\n");}}int main(){Status i;Position p;TElemType e;SqBiTree T;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);printf("前序遍历二叉树:\n");PreOrderTraverse(T);printf("中序遍历二叉树:\n");InOrderTraverse(T);printf("后序遍历二叉树:\n");PostOrderTraverse(T);printf("修改结点的层号3本层序号2。");p.level = 3;p.order = 2;e = Value(T, p);printf("待修改结点的原值为%d请输入新值:50 ", e);e = 50;Assign(T, p, e);printf("前序遍历二叉树:\n");PreOrderTraverse(T);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));ClearBiTree(T);printf("清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));i = Root(T, &e);if (i)printf("二叉树的根为:%d\n", e);elseprintf("树空,无根\n");return 0;}

2、链式二叉树的实现

#include "string.h"#include "stdio.h"    #include "stdlib.h"   //#include "io.h"  #include "math.h"  //#include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 *//* 用于构造二叉树********************************** */int index = 1;typedef char String[24]; /*  0号单元存放串的长度 */String str;Status StrAssign(String T, char *chars){int i;if (strlen(chars)>MAXSIZE)return ERROR;else{T[0] = strlen(chars);for (i = 1; i <= T[0]; i++)T[i] = *(chars + i - 1);return OK;}}/* ************************************************ */typedef char TElemType;TElemType Nil = ' '; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ", e);return OK;}typedef struct BiTNode  /* 结点结构 */{TElemType data;/* 结点数据 */struct BiTNode *lchild, *rchild; /* 左右孩子指针 */}BiTNode, *BiTree;/* 构造空二叉树T */Status InitBiTree(BiTree *T){*T = NULL;return OK;}/* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */void DestroyBiTree(BiTree *T){if (*T){if ((*T)->lchild) /* 有左孩子 */DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */if ((*T)->rchild) /* 有右孩子 */DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */free(*T); /* 释放根结点 */*T = NULL; /* 空指针赋0 */}}/* 按前序输入二叉树中结点的值(一个字符) *//* #表示空树,构造二叉链表表示二叉树T。 */void CreateBiTree(BiTree *T){TElemType ch;/* scanf("%c",&ch); */ch = str[index++];if (ch == '#')*T = NULL;else{*T = (BiTree)malloc(sizeof(BiTNode));if (!*T)exit(OVERFLOW);(*T)->data = ch; /* 生成根结点 */CreateBiTree(&(*T)->lchild); /* 构造左子树 */CreateBiTree(&(*T)->rchild); /* 构造右子树 */}}/* 初始条件: 二叉树T存在 *//* 操作结果: 若T为空二叉树,则返回TRUE,否则FALSE */Status BiTreeEmpty(BiTree T){if (T)return FALSE;elsereturn TRUE;}#define ClearBiTree DestroyBiTree/* 初始条件: 二叉树T存在。操作结果: 返回T的深度 */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;}/* 初始条件: 二叉树T存在。操作结果: 返回T的根 */TElemType Root(BiTree T){if (BiTreeEmpty(T))return Nil;elsereturn T->data;}/* 初始条件: 二叉树T存在,p指向T中某个结点 *//* 操作结果: 返回p所指结点的值 */TElemType Value(BiTree p){return p->data;}/* 给p所指结点赋值为value */void Assign(BiTree p, TElemType value){p->data = value;}/* 初始条件: 二叉树T存在 *//* 操作结果: 前序递归遍历T */void PreOrderTraverse(BiTree T){if (T == NULL)return;printf("%c", T->data);/* 显示结点数据,可以更改为其它对结点操作 */PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */}/* 初始条件: 二叉树T存在 *//* 操作结果: 中序递归遍历T */void InOrderTraverse(BiTree T){if (T == NULL)return;InOrderTraverse(T->lchild); /* 中序遍历左子树 */printf("%c", T->data);/* 显示结点数据,可以更改为其它对结点操作 */InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */}/* 初始条件: 二叉树T存在 *//* 操作结果: 后序递归遍历T */void PostOrderTraverse(BiTree T){if (T == NULL)return;PostOrderTraverse(T->lchild); /* 先后序遍历左子树  */PostOrderTraverse(T->rchild); /* 再后序遍历右子树  */printf("%c", T->data);/* 显示结点数据,可以更改为其它对结点操作 */}int main(){int i;BiTree T;TElemType e1;InitBiTree(&T);StrAssign(str, "ABDH#K###E##CFI###G#J##");CreateBiTree(&T);printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));e1 = Root(T);printf("二叉树的根为: %c\n", e1);printf("\n前序遍历二叉树:");PreOrderTraverse(T);printf("\n中序遍历二叉树:");InOrderTraverse(T);printf("\n后序遍历二叉树:");PostOrderTraverse(T);ClearBiTree(&T);printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));i = Root(T);if (!i)printf("树空,无根\n");return 0;}
<pre name="code" class="cpp">#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>#include<math.h>typedef char ElemType;ElemType Nil = ' ';typedef char String[24];String str;int index = 1;typedef struct Node{ElemType data;struct Node *lchild, *rchild;}Node, BiTree;bool InitBiTree(BiTree *&T);void StrAssign(String T, char *chars);void CreateBiTree(BiTree *&T);void DestroyBiTree(BiTree *&T);bool BiTreeEmpty(BiTree *T);int BiTreeDepth(BiTree *T);ElemType Root(BiTree *T);ElemType Value(BiTree *p);void Assign(BiTree *p, ElemType value);void PreOrderTraverse(BiTree *T);void InOrderTraverse(BiTree *T);void PostOrderTraverse(BiTree *T);int main(){int i;BiTree *T;ElemType e1;InitBiTree(T);StrAssign(str, "ABDH#K###E##CFI###G#J##");CreateBiTree(T);printf("构造空二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));e1 = Root(T);printf("二叉树的根为: %c\n", e1);printf("\n前序遍历二叉树:");PreOrderTraverse(T);printf("\n中序遍历二叉树:");InOrderTraverse(T);printf("\n后序遍历二叉树:");PostOrderTraverse(T);DestroyBiTree(T);printf("\n清除二叉树后,树空否?%d(1:是 0:否) 树的深度=%d\n", BiTreeEmpty(T), BiTreeDepth(T));i = Root(T);if (!i)printf("树空,无根\n");return 0;}bool InitBiTree(BiTree *&T){T = NULL;return true;}void StrAssign(String T, char *chars){T[0] = strlen(chars);for (int i = 1; i <=T[0]; ++i){T[i] = chars[i - 1];}}void DestroyBiTree(BiTree *&T){if (T){if (T->lchild)DestroyBiTree(T->lchild);if (T->rchild)DestroyBiTree(T->rchild);free(T);T = NULL;}}void CreateBiTree(BiTree *&T){ElemType ch;ch = str[index++];if (ch == '#')T = NULL;else{T = (BiTree*)malloc(sizeof(Node));if (!T)exit(OVERFLOW); T->data = ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); }}bool BiTreeEmpty(BiTree *T){if (T == NULL)return true;elsereturn false;}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;}ElemType Root(BiTree *T){if (BiTreeEmpty(T))return Nil;elsereturn T->data;}ElemType Value(BiTree *p){return p->data;}void Assign(BiTree *p, ElemType value){p->data = value;}void PreOrderTraverse(BiTree *T){if (T == NULL)return;printf("%c", T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}void InOrderTraverse(BiTree *T){if (T == NULL)return;PreOrderTraverse(T->lchild);printf("%c", T->data);PreOrderTraverse(T->rchild);}void PostOrderTraverse(BiTree *T){if (T == NULL)return;PreOrderTraverse(T->lchild);printf("%c", T->data);PreOrderTraverse(T->rchild);}



3、线索二叉树

#include "string.h"#include "stdio.h"    #include "stdlib.h"   //#include "io.h"  #include "math.h"  //#include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 100 /* 存储空间初始分配量 */typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef char TElemType;typedef enum { Link, Thread } PointerTag;/* Link==0表示指向左右孩子指针, *//* Thread==1表示指向前驱或后继的线索 */typedef  struct BiThrNode/* 二叉线索存储结点结构 */{TElemType data;/* 结点数据 */struct BiThrNode *lchild, *rchild;/* 左右孩子指针 */PointerTag LTag;PointerTag RTag;/* 左右标志 */} BiThrNode, *BiThrTree;TElemType Nil = '#'; /* 字符型以空格符为空 */Status visit(TElemType e){printf("%c ", e);return OK;}/* 按前序输入二叉线索树中结点的值,构造二叉线索树T *//* 0(整型)/空格(字符型)表示空结点 */Status CreateBiThrTree(BiThrTree *T){TElemType h;scanf("%c", &h);if (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){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); /* 递归右子树线索化 */}}/* 中序遍历二叉树T,并将其中序线索化,Thrt指向头结点 */Status InOrderThreading(BiThrTree *Thrt, BiThrTree T){*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;}/* 中序遍历二叉线索树T(头结点)的非递归算法 */Status InOrderTraverse_Thr(BiThrTree T){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;}int main(){BiThrTree H, T;printf("请按前序输入二叉树(如:'ABDH##I##EJ###CF##G##')\n");CreateBiThrTree(&T); /* 按前序产生二叉树 */InOrderThreading(&H, T); /* 中序遍历,并中序线索化二叉树 */printf("中序遍历(输出)二叉线索树:\n");InOrderTraverse_Thr(H); /* 中序遍历(输出)二叉线索树 */printf("\n");return 0;}











0 0
原创粉丝点击