二叉链的基本操作
【目的】
1. 领会二叉链存储结构;掌握二叉树的各种基本运算和构造二叉树的算法设计。
2. 领会线索二叉树的构造过程以及构造线索二叉树的算法设计。
【内容及要求】编写程序实现两种方式建立二叉树:
编写一个程序btree.cpp,实现二叉树的基本运算,并在此基础上设计一个程序完成以下功能:(见教材P247,实验题1)
(1)由图7.33所示的二叉树创建对应的二叉链存储结构b,该二叉树的括号表示串为“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”。
(2)输出二叉树b。(采用凹入表示法)
(3)输出’H’结点的左、右孩子结点值。
(4)输出二叉树b的高度。
(5)释放二叉树b。
(6)利用先序序列和中序序列重新构造该
二叉树(执行(5)的操作后再执行这一功能),
并以括号表示法输出该二叉树。
(7)对该二叉树进行中序线索化。
#include <stdio.h> #include <stdlib.h> #include <iostream> #define ElemType char #define BTNode TBTNode #define MaxSize 100 #define maxsize 100 typedef struct node { ElemType data; int ltag, rtag; //线索的标记 struct node *lchild; struct node *rchild; } BTNode; BTNode *pre; //全局变量的指针类型 char Pre[100]; char In[100]; int i = 0; void CreateBTree(BTNode *&b, char *str) //创建二叉树 { BTNode *St[MaxSize], *p; int top = -1, k, j = 0; char ch; b = NULL; ch = str[j]; while (ch != '\0') { switch (ch) { case '(': top++; St[top] = p; k = 1; break; case ')': top--; break; case ',': k = 2; break; default: p = (BTNode *)malloc(sizeof(BTNode)); p->data = ch; p->lchild = p->rchild = NULL; if (b == NULL) b = p; else { switch (k) { case 1: St[top]->lchild = p; break; case 2: St[top]->rchild = p; break; } } } j++; ch = str[j]; } } void DestoryBTree(BTNode *&b) //摧毁二叉树 { if (b != NULL) { DestoryBTree(b->lchild); DestoryBTree(b->rchild); free(b); } } BTNode *FindNode(BTNode *b, ElemType x) //寻找值为x的结点 { BTNode *p; if (b == NULL) return NULL; else if (b->data == x) return b; else { p = FindNode(b->lchild, x); if (p != NULL) return p; else return FindNode(b->rchild, x); } } BTNode *LchildNode(BTNode *p) //返回左孩子结点 { return p->lchild; } BTNode *RchildNode(BTNode *p) //返回右孩子结点 { return p->rchild; } int BTHeight(BTNode *b) //输出高度 { int lchildh, rchildh; if (b == NULL) return 0; else { lchildh = BTHeight(b->lchild); rchildh = BTHeight(b->rchild); return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1); } } void DispBTree(BTNode *b) //输出二叉树 { if (b != NULL) { printf("%c", b->data); if (b->lchild != NULL || b->rchild != NULL) { printf("("); DispBTree(b->lchild); if (b->rchild != NULL) printf(","); DispBTree(b->rchild); printf(")"); } } } void PreOrder(BTNode *b) //先序遍历的递归形式 { if (b != NULL) { printf("%c ", b->data); Pre[i] = b->data; i++; PreOrder(b->lchild); PreOrder(b->rchild); } } void InOrder(BTNode *b) //中序遍历的递归算法 { if (b != NULL) { InOrder(b->lchild); In[i] = b->data; i++; printf("%c ", b->data); InOrder(b->rchild); } } BTNode *CreateBTree1(char *pre, char *in, int n) //根据前序和中序推出二叉树序列 { BTNode *b; char *p; int k; if (n <= 0) return NULL; b = (BTNode *)malloc(sizeof(BTNode)); b->data = *pre; for (p = in; p < in + n; p++) if (*p == *pre) break; k = p - in; b->lchild = CreateBTree1(pre + 1, in, k); b->rchild = CreateBTree1(pre + k + 1, p + 1, n - k - 1); return b; } void Thread(TBTNode *&p) //生成二叉树的线索 { if (p != NULL) { Thread(p->lchild); if (p->lchild == NULL) //节点左孩子为空时就直接指向前驱的节点线索 { p->lchild = pre; p->ltag = 1; } else p->ltag = 0; if (pre->rchild == NULL) //右孩子为空时则指向后继的结点线索位置 { pre->rchild = p; pre->rtag = 1; } else pre->rtag = 0; pre = p; Thread(p->rchild); } } TBTNode *CreateThread(TBTNode *b) //把二叉链转换成线索的形式 { TBTNode *root; root = (BTNode *)malloc(sizeof(BTNode)); root->ltag = 0; root->rtag = 1; root->rchild = b; if (b == NULL) root->lchild = root; //原二叉链为空,则指针指回自己root else { root->lchild = b; pre = root; Thread(b); pre->rchild = root; pre->rtag = 1; root->rchild = pre; } return root; } void ThInOrder(TBTNode *tb) { TBTNode *p = tb->lchild; while (p != tb) { while (p->ltag == 0) p = p->lchild; //找到中序的第一个节点 printf("%c ", p->data); //如果无左孩子说明是已经到达了树梢的叶子节点,直接输出 while (p->rtag == 1 && p->rchild != tb) //输出在中序中的下一个节点值 { p = p->rchild; printf("%c ", p->data); } p = p->rchild; //回溯到p的前一个节点或者是直接找下一个的右孩子节点 } } void PreOrder2(BTNode *b, int n, int k) //凹入法输出二叉链 { if (b != NULL) { for (int j = 0; j < k; j++) printf(" "); printf("%c ", b->data); for (int j = 0; j < n; j++) printf("-"); printf("\n"); PreOrder2(b->lchild, n - 1, k + 1); PreOrder2(b->rchild, n - 1, k + 1); } } int main() { char a[] = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))"; int n = 14; BTNode *t, *b; CreateBTree(t, a); b = FindNode(t, 'H'); printf("括号法输出二叉树:\n"); DispBTree(t); putchar(10); printf("凹入表示法输出二叉树:\n"); PreOrder2(t, 14, 1); putchar(10); printf("该结点的左孩子是 %c , 该孩子的右孩子是 %c \n", b->lchild->data, b->rchild->data); printf("该二叉树的高度是 %d .\n", BTHeight(t)); printf("先序遍历的结果:"); PreOrder(t); i = 0; printf("\n中序遍历的结果:"); InOrder(t); DestoryBTree(t); printf("\n成功销毁二叉树\n"); printf("\n由先序序列和中序序列生成二叉树:"); b = CreateBTree1(Pre, In, n); putchar(10); DispBTree(b); putchar(10); printf("二叉树的线索化\n"); TBTNode *g; g = CreateThread(b); printf("成功创建线索化的二叉树\n"); printf("中序线索化遍历二叉树:"); ThInOrder(g); putchar(10); putchar(10); system("pause"); return 0; }
喜欢的话,记得支持关注哦。 关注我或者我的csdn博客:https://blog.csdn.net/horizon08/article/details/106254585