1.实现二又树各种基本运算的算法:
#include<stdlib.h>
#include<stdio.h>
#define Maxsize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
//创建二叉树
void CreateBTree(BTNode** b, ElemType* str)
{
BTNode* St[Maxsize];
BTNode* p = NULL;
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 DestroyBtree(BTNode** b)
{
while ((*b) != NULL)
{
DestroyBtree(&((*b)->lchild));
DestroyBtree(&((*b)->rchild));
free(*b);
}
}
//返回值为x的结点
BTNode* FindNode(BTNode* b, ElemType 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(")");
}
}
}
int main()
{
BTNode* b, * p, * lp, * rp;
CreateBTree(&b, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf("二叉树的基本运算如下:\n");
printf(" (1)输出二叉树:"); DispBTree(b); printf("\n");
printf(" (2)H节点:");
p = FindNode(b, 'H');
if (p != NULL)
{
lp = LchildNode(p);
if (lp != NULL)
printf("左孩子为%c ", lp->data);
else
printf("无左孩子 ");
rp = RchildNode(p);
if (rp != NULL)
printf("右孩子为%c", rp->data);
else
printf("无右孩子 ");
}
printf("\n");
printf(" (3)二叉树b的深度:%d\n", BTHeight(b));
DestroyBtree(&b);
return 0;
}
2.实现二叉树各种遍历运算:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
/*********************二叉树的定义和各种运算部分**********************/
#define Maxsize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
void CreateBTree(BTNode** b, char* str) //创造二叉树
{
BTNode* St[Maxsize];
BTNode* p = NULL;
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 DestroyBtree(BTNode** b) //销毁二叉树
{
if ((*b) != NULL)
{
DestroyBtree(&((*b)->lchild));
DestroyBtree(&((*b)->rchild));
free(*b);
}
}
BTNode* FindNode(BTNode* b, ElemType 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(")");
}
}
}
/*****************队列定义和各种算法部分********************/
#define MaxSize2 50
typedef struct {
BTNode* data[MaxSize2];
int front, rear;
}SqQueue;
void InitQueue(SqQueue** q)
{
*q = (SqQueue*)malloc(sizeof(SqQueue));
(*q)->front = (*q)->rear = 0;
}
void DestroyQueue(SqQueue** q)
{
free(*q);
}
bool QueueEmpty(SqQueue* q)
{
return (q->front == q->rear);
}
bool enQueue(SqQueue** q, BTNode* e)
{
if (((*q)->rear + 1) % MaxSize2 == (*q)->front)
{
return false;
}
(*q)->rear = ((*q)->rear + 1) % MaxSize2;
(*q)->data[(*q)->rear] = e;
return true;
}
bool deQueue(SqQueue** q, BTNode** e)
{
if ((*q)->front == (*q)->rear)
{
return false;
}
(*q)->front = ((*q)->front + 1) % MaxSize2;
*e = (*q)->data[(*q)->front];
return true;
}
/**********************栈定义部分**********************/
/****************************************************/
#define Maxsize3 50
typedef struct
{
BTNode* data[Maxsize3];
int top;
}SqStack;
void InitStack(SqStack** s)
{
*s = (SqStack*)malloc(sizeof(SqStack));
(*s)->top = -1;
}
void DestroyStack(SqStack** s)
{
free(*s);
}
bool StackEmpty(SqStack* s)
{
return (s->top == -1);
}
bool Push(SqStack** s, BTNode* e)
{
if ((*s)->top == Maxsize3 - 1) {
return false;
}
(*s)->top++;
(*s)->data[(*s)->top] = e;
return true;
}
bool Pop(SqStack** s, BTNode** e)
{
if ((*s)->top == -1)
return false;
*e = (*s)->data[(*s)->top];
(*s)->top--;
return true;
}
bool GetTop(SqStack* s, BTNode** e)
{
if (s->top == -1)
return false;
*e = s->data[s->top];
return true;
}
/*********************遍历算法部分*********************/
void PreOrder_recursion(BTNode* b) //递归先序遍历
{
if (b != NULL)
{
printf("%c ",b->data);
PreOrder_recursion(b->lchild);
PreOrder_recursion(b->rchild);
}
}
void PreOrder_not_recursion(BTNode* b) //非递归先序遍历
{
BTNode* p;
SqStack* st;
InitStack(&st);
if (b != NULL)
{
Push(&st, b);
while (!StackEmpty(st))
{
Pop(&st, &p);
printf("%c ", p->data);
if (p->rchild != NULL)
{
Push(&st, p->rchild);
}
if (p->lchild != NULL)
{
Push(&st, p->lchild);
}
}
printf("\n");
}
DestroyStack(&st);
}
void InOrder_recursion(BTNode* b) //递归中序遍历
{
if (b != NULL)
{
InOrder_recursion(b->lchild);
printf("%c ", b->data);
InOrder_recursion(b->rchild);
}
}
void InOrder_not_recursion(BTNode* b) //非递归中序遍历
{
BTNode* p;
SqStack* st;
InitStack(&st);
p = b;
while (!StackEmpty(st) || p != NULL)
{
while (p != NULL)
{
Push(&st, p);
p = p->lchild;
}
if (!StackEmpty(st))
{
Pop(&st, &p);
printf("%c ", p->data);
p = p->rchild;
}
}
printf("\n");
DestroyStack(&st);
}
void PostOrder_recursion(BTNode* b) //递归后序遍历
{
if (b != NULL)
{
PostOrder_recursion(b->lchild);
PostOrder_recursion(b->rchild);
printf("%c ", b->data);
}
}
void PostOrder_not_recursion(BTNode* b) //非递归后序遍历
{
BTNode* p, * r;
bool flag;
SqStack* st;
InitStack(&st);
p = b;
do {
while (p != NULL)
{
Push(&st, p);
p = p->lchild;
}
r = NULL;
flag = true;
while (!StackEmpty(st) && flag)
{
GetTop(st, &p);
if (p->rchild == r)
{
printf("%c ", p->data);
Pop(&st, &p);
r = p;
}
else
{
p = p->rchild;
flag = false;
}
}
} while (!StackEmpty(st));
printf("\n");
DestroyStack(&st);
}
void LevelOrder(BTNode* b)
{
BTNode* p;
SqQueue* qu;
InitQueue(&qu);
if (b != NULL)
{
enQueue(&qu, b);
while (!QueueEmpty(qu))
{
deQueue(&qu, &p);
printf("%c ", p->data);
if (p->lchild != NULL)
enQueue(&qu, p->lchild);
if (p->rchild != NULL)
enQueue(&qu, p->rchild);
}
}
}
int main()
{
BTNode* b;
char str[] = "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))";
CreateBTree(&b, str);
printf("初始化二叉树为:\n" );
DispBTree(b);
printf("\n");
printf( "递归先序遍历:\n"); PreOrder_recursion(b);
printf("\n");
printf ("非递归先序遍历:\n"); PreOrder_not_recursion(b);
printf("递归中序遍历:\n"); InOrder_recursion(b);
printf("\n");
printf("非递归中序遍历:\n"); InOrder_not_recursion(b);
printf("递归后序遍历:\n"); PostOrder_recursion(b);
printf("\n");
printf ("非递归后序遍历:\n"); PostOrder_not_recursion(b);
printf ("层次遍历:\n"); LevelOrder(b);
return 0;
}
3.由遍历序列构造二叉树:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
#define MaxWidth 40
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
//输出二叉树(括号法)
void DispBTNode(BTNode* b)
{
if (b != NULL)
{
printf("%c", b->data);
if (b->lchild != NULL || b->rchild != NULL)
{
printf("(");
DispBTNode(b->lchild);
if (b->rchild != NULL)
printf(",");
DispBTNode(b->rchild);
printf(")");
}
}
}
void DestroyBTNode(BTNode** b) //销毁二叉树
{
if ((*b) != NULL)
{
DestroyBTNode(&((*b)->lchild));
DestroyBTNode(&((*b)->rchild));
free(*b);
}
}
//先序+中序构造
BTNode* CreateBT1(char* pre, char* in, int n) //pre表示先序,in表示中序, n 为结点数
{
BTNode* s;
char* p;
int k;
if (n <= 0)
return NULL;
s = (BTNode*)malloc(sizeof(BTNode));//创建二叉树节点*s
s->data = *pre;
for (p = in; p < in + n; p++)//在中序序列中找等于*ppos的位置k
if (*p == *pre)
break;
k = p - in;
s->lchild = CreateBT1(pre + 1, in, k);
s->rchild = CreateBT1(pre + k + 1, p + 1, n - k - 1);
return s;
}
BTNode* CreateBT2(char* post, char* in, int n, int m) // n 为节点数, m 为序列长度
{
BTNode* s;
char* p, * q;
char* maxp = NULL;
int maxpost, maxin, k;
if (n <= 0)
return NULL;
maxpost = -1;
for (p = in; p < in + n; p++)
{ //求in中全部字符中在post中最右边的那个字符
for (q = post; q < post + m; q++)//在in中用maxp指向这个字符,用maxin标识它在in中的下标
{
if (*p == *q)
{
k = q - post;
if (k > maxpost)
{
maxpost = k;
maxp = p;
maxin = p - in;
}
}
}
}
s = (BTNode*)malloc(sizeof(BTNode));//创建二叉树节点*s
s->data = post[maxpost];
s->lchild = CreateBT2(post, in, maxin, m);
s->rchild = CreateBT2(post, maxp + 1, n - maxin - 1, m);
return s;
}
void DispBTNode1(BTNode* b)//以凹入表表示法输出一棵二叉树
{
BTNode* St[MaxSize], * p;
int level[MaxSize][2], top = -1, n, i, width = 4;
char type;
if (b != NULL)
{
top++;
St[top] = b;//根节点入栈
level[top][0] = width;
level[top][1] = 2;//2表示是根
while (top > -1)
{
p = St[top];//退栈并凹入显示该节点值
n = level[top][0];
switch (level[top][1])
{
case 0:type = 'L'; break;//左节点之后输出(L)
case 1:type = 'R'; break;//右节点之后输出(R)
case 2:type = 'B'; break;//根节点之后前输出(B)
}
for (i = 1; i <= n; i++)//其中n为显示场宽,字符以右对齐显示
printf(" ");
printf("%c(%c)", p->data, type);
for (i = n + 1; i <= MaxWidth; i += 2)
printf("--");
printf("\n");
top--;
if (p->rchild != NULL)
{//将右子树根节点入栈
top++;
St[top] = p->rchild;
level[top][0] = n + width;//显示场宽增width
level[top][1] = 1;//1表示是右子树
}
if (p->lchild != NULL)
{//将左子树根节点入栈
top++;
St[top] = p->lchild;
level[top][0] = n + width;//显示场宽增width
level[top][1] = 0;//0表示是左子树
}
}
}
}
int main()
{
BTNode* b;
ElemType pre[] = "ABDEHJKLMNCFGI";
ElemType in[] = "DBJHLKMNEAFCGI";
ElemType post[] = "DJLNMKHEBFIGCA";
b = CreateBT1(pre, in, 14);
printf("先序序列:%s\n", pre);
printf("中序序列:%s\n", in);
printf("构造一棵二叉树b:\n");
printf(" 括号表示法:");
DispBTNode(b);
printf("\n");
printf(" 凹入表示法:\n");
DispBTNode1(b); printf("\n\n");
printf("中序序列:%s\n", in);
printf("后序序列:%s\n", post);
b = CreateBT2(post, in, 14, 14);
printf("构造一棵二叉树b:\n");
printf(" 括号表示法:");
DispBTNode(b);
printf("\n");
printf(" 凹入表示法:\n");
DispBTNode1(b);
printf("\n");
DestroyBTNode(b);
}
4.中序线索化二叉树:
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
int ltag, rtag; //增加的线索标记
struct node* lchild;
struct node* rchild;
} TBTNode;
//创建二叉树
void CreateTBTree(TBTNode** b, ElemType* str)
{
TBTNode* St[MaxSize];
TBTNode* p = NULL;
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 = (TBTNode*)malloc(sizeof(TBTNode));
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 DispTBTree(TBTNode* b)
{
if (b != NULL)
{
printf("%c", b->data);
if (b->lchild != NULL || b->rchild != NULL)
{
printf("(");
DispTBTree(b->lchild);
if (b->rchild != NULL)
printf(",");
DispTBTree(b->rchild);
printf(")");
}
}
}
TBTNode* pre = NULL; //全局变量
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 != NULL && pre->rchild == NULL) { // 后继线索
pre->rchild = p; // 建立前驱节点的后继线索
pre->rtag = 1;
}
else if (pre != NULL) {
pre->rtag = 0;
}
pre = p;
Thread(p->rchild); // 右子树线索化
}
}
TBTNode* CreateThread(TBTNode* b) //中序线索化二叉树
{
TBTNode* root;
root = (TBTNode*)malloc(sizeof(TBTNode)); //创建根节点
root->ltag = 0; root->rtag = 1;
root->rchild = b;
if (b == NULL) //空二叉树
root->lchild = root;
else
{
root->lchild = b;
pre = root; //pre是*p的前驱节点,供加线索用
Thread(b); //中序遍历线索化二叉树
pre->rchild = root; //最后处理,加入指向根节点的线索
pre->rtag = 1;
root->rchild = pre; //根节点右线索化
}
return root;
}
void DestroyTBTree1(TBTNode** b) //销毁
{
if ((*b)->ltag == 0) //节点b有左孩子,释放左子树
DestroyTBTree1(&(*b)->lchild);
if ((*b)->rtag == 0) //节点b有右孩子,释放右子树
DestroyTBTree1(&(*b)->rchild);
free(*b);
}
void DestroyTBTree(TBTNode** tb) //销毁一棵带头结点的中序线索树tb
{
DestroyTBTree1(&(*tb)->lchild); //释放以tb->lchild为根节点的树
free(*tb); //释放头节点
}
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;
}
}
int main()
{
TBTNode* b, * tb;
CreateTBTree(&b, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf(" 二叉树:");
DispTBTree(b);
printf("\n");
tb = CreateThread(b);
printf(" 线索中序序列:");
ThInOrder(tb);
printf("\n");
DestroyTBTree(&tb);
return 0;
}
5.构造哈夫曼树和哈弗曼编码:
#include <stdio.h>
#include <string.h>
#define N 50 //叶子结点数
#define M 2*N-1 //树中结点总数
typedef struct
{
char data[5]; //结点值
double weight; //权重
int parent; //双亲结点
int lchild; //左孩子结点
int rchild; //右孩子结点
} HTNode;
typedef struct
{
char cd[N]; //存放哈夫曼码
int start;
} HCode;
void CreateHT(HTNode ht[], int n0) //构造哈夫曼树
{
int i, k, lnode, rnode;
double min1, min2;
for (i = 0; i < 2 * n0 - 1; i++) //所有节点的相关域置初值-1
ht[i].parent = ht[i].lchild = ht[i].rchild = -1;
for (i = n0; i <= 2 * n0 - 2; i++) //构造哈夫曼树的n0-1个节点
{
min1 = min2 = 32767; //lnode和rnode为最小权重的两个节点位置
lnode = rnode = -1;
for (k = 0; k <= i - 1; k++) //在ht[0..i-1]中找权值最小的两个节点
if (ht[k].parent == -1) //只在尚未构造二叉树的节点中查找
{
if (ht[k].weight < min1)
{
min2 = min1; rnode = lnode;
min1 = ht[k].weight; lnode = k;
}
else if (ht[k].weight < min2)
{
min2 = ht[k].weight; rnode = k;
}
}
ht[i].weight = ht[lnode].weight + ht[rnode].weight;
ht[i].lchild = lnode; ht[i].rchild = rnode; //ht[i]作为双亲节点
ht[lnode].parent = i; ht[rnode].parent = i;
}
}
void CreateHCode(HTNode ht[], HCode hcd[], int n0) //构造哈夫曼树编码
{
int i, f, c;
HCode hc;
for (i = 0; i < n0; i++) //根据哈夫曼树求哈夫曼编码
{
hc.start = n0; c = i;
f = ht[i].parent;
while (f != -1) //循环直到无双亲节点即到达树根节点
{
if (ht[f].lchild == c) //当前节点是双亲节点的左孩子
hc.cd[hc.start--] = '0';
else //当前节点是双亲节点的右孩子
hc.cd[hc.start--] = '1';
c = f; f = ht[f].parent; //再对双亲节点进行同样的操作
}
hc.start++; //start指向哈夫曼编码最开始字符
hcd[i] = hc;
}
}
void DispHCode(HTNode ht[], HCode hcd[], int n0) //输出哈夫曼树编码
{
int i, k;
double sum = 0, m = 0;
int j;
printf(" 输出哈夫曼编码:\n"); //输出哈夫曼编码
for (i = 0; i < n0; i++)
{
j = 0;
printf(" %s:\t", ht[i].data);
for (k = hcd[i].start; k <= n0; k++)
{
printf("%c", hcd[i].cd[k]);
j++;
}
m += ht[i].weight;
sum += ht[i].weight * j;
printf("\n");
}
printf("\n 平均长度=%g\n", 1.0 * sum / m);
}
int main()
{
int n = 8, i; //n表示初始字符串的个数
char* str[] = { "a","b","c","d","e","f","g","h" };
double fnum[] = { 0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.1 };
HTNode ht[M];
HCode hcd[N];
for (i = 0; i < n; i++)
{
strcpy_s(ht[i].data, sizeof(ht[i].data), str[i]);
ht[i].weight = fnum[i];
}
printf("\n");
CreateHT(ht, n);
CreateHCode(ht, hcd, n);
DispHCode(ht, hcd, n);
printf("\n");
return 1;
}
6.求二又树结点个数、叶子节点个数等算法:
#include<stdlib.h>
#include<stdio.h>
#define Maxsize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
//创建二叉树
void CreateBTree(BTNode** b, ElemType* str)
{
BTNode* St[Maxsize];
BTNode* p = NULL;
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 DestroyBtree(BTNode** b) {
if (*b != NULL) {
DestroyBtree(&((*b)->lchild));
DestroyBtree(&((*b)->rchild));
free(*b);
*b = NULL; // 将指针设置为NULL
}
}
//返回值为x的结点
BTNode* FindNode(BTNode* b, ElemType 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(")");
}
}
}
//二叉树的节点个数
int Nodes(BTNode* b)
{
int num1, num2;
if (b == NULL)
return 0;
else if (b->lchild == NULL && b->rchild == NULL)
return 1;
else
{
num1 = Nodes(b->lchild);
num2 = Nodes(b->rchild);
return (num1 + num2 + 1);
}
}
//叶子结点个数
int LeafNodes(BTNode* b)
{
int num1, num2;
if (b == NULL)
return 0;
else if (b->lchild == NULL && b->rchild == NULL)
return 1;
else
{
num1 = LeafNodes(b->lchild);
num2 = LeafNodes(b->rchild);
return (num1 + num2);
}
}
//求层数
int Level(BTNode* b, ElemType x, int h)
{
int l;
if (b == NULL)
return 0;
else if (b->data == x)
return h;
else
{
l = Level(b->lchild, x, h + 1);
if (l != 0)return l;
else return(Level(b->rchild, x, h + 1));
}
}
//一层当中的个数,使用层次遍历
int BTWidth(BTNode* b)
{
struct
{
int lno;
BTNode* p;
}Qu[Maxsize];
//队列
int front, rear;
int lnum, max, i, n;
front = rear = 0;
if (b != NULL)
{
rear++; Qu[rear].p = b;
Qu[rear].lno = 1;
while (rear != front)
{
front++; b = Qu[front].p;
lnum = Qu[front].lno;
if (b->lchild != NULL)
{
rear++; Qu[rear].p = b->lchild;
Qu[rear].lno = lnum + 1;
}
if (b->rchild != NULL)
{
rear++; Qu[rear].p = b->rchild;
Qu[rear].lno = lnum + 1;
}
}
max = 0; lnum = 1; i = 1;
while (i <= rear)
{
n = 0;
while (i <= rear && Qu[i].lno == lnum)
{
n++;
i++;
}
lnum = Qu[i].lno;
if (n > max)max = n;
}
return max;
}
else return 0;
}
int main()
{
ElemType x = 'K';
BTNode* b, * p, * lp, * rp;
CreateBTree(&b, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf("输出二叉树b:");
DispBTree(b);
printf("\n");
printf("二叉树b的结点个数:%d\n", Nodes(b));
printf("二叉树的叶子结点个数:%d\n", LeafNodes(b));
printf("二叉树b中值为%c结点的层次:%d\n", x, Level(b, x, 1));
printf("二叉树b的宽度:%d\n", BTWidth(b));
DestroyBtree(&b);
return 0;
}
7.根到叶子的路径:
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>
#define Maxsize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
//创建二叉树
void CreateBTree(BTNode** b, ElemType* str)
{
BTNode* St[Maxsize];
BTNode* p = NULL;
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 DestroyBtree(BTNode** b) {
if (*b != NULL) {
DestroyBtree(&((*b)->lchild));
DestroyBtree(&((*b)->rchild));
free(*b);
*b = NULL; // 将指针设置为NULL
}
}
//返回值为x的结点
BTNode* FindNode(BTNode* b, ElemType 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(")");
}
}
}
int i = 0;
void AllPath1(BTNode* b, ElemType path[], int pathlen)
{
if (b != NULL)
{
if (b->lchild == NULL && b->rchild == NULL)
{
printf("%c到根结点逆路径:%c->", b->data, b->data);
for (i = pathlen - 1; i > 0; i--)
printf("%c->", path[i]);
printf("%c\n", path[0]);
}
else
{
path[pathlen] = b->data;
pathlen++;
AllPath1(b->lchild, path, pathlen);
AllPath1(b->rchild, path, pathlen);
}
}
}
void LongPath1(BTNode* b, ElemType path[], int pathlen, ElemType longpath[], int* longpathlen)
{
if (b == NULL)
{
if (pathlen > *longpathlen)
{
for (i = pathlen - 1; i >= 0; i--)
longpath[i] = path[i];
*longpathlen = pathlen;
}
}
else
{
path[pathlen] = b->data;
pathlen++;
LongPath1(b->lchild, path, pathlen, longpath, longpathlen);
LongPath1(b->rchild, path, pathlen, longpath, longpathlen);
}
}
void AllPath2(BTNode* b)
{
BTNode* st[Maxsize];
int top = -1;
BTNode* p, * r;
bool flag;
p = b;
do {
while (p != NULL)
{
top++;
st[top] = p;
p = p->lchild;
}
r = NULL;
flag = true;
while (top != -1 && flag)
{
p = st[top];
if (p->rchild == r)
{
if (p->lchild == NULL && p->rchild == NULL)
{
printf("%c到根结点逆路径:", p->data);
for (i = top; i > 0; i--)
printf("%c->", st[i]->data);
printf("%c\n", st[0]->data);
}
top--;
r = p; // 更新r为刚刚访问过的节点
}
else
{
p = p->rchild;
flag = false;
}
}
} while (top != -1);
}
void AllPath3(BTNode* b)
{
struct snode
{
BTNode* node;
int parent;
}Qu[Maxsize];
int front, rear, p;
front = rear = -1;
rear++;
Qu[rear].node = b;
Qu[rear].parent = -1;
while (front < rear)
{
front++;
b = Qu[front].node;
if (b->lchild == NULL && b->rchild == NULL)
{
printf("%c到根结点逆路径:", b->data);
p = front;
while (Qu[p].parent != -1)
{
printf("%c->", Qu[p].node->data);
p = Qu[p].parent;
}
printf("%c\n", Qu[p].node->data);
}
if (b->lchild != NULL)
{
rear++;
Qu[rear].node = b->lchild;
Qu[rear].parent = front;
}
if (b->rchild != NULL)
{
rear++;
Qu[rear].node = b->rchild;
Qu[rear].parent = front;
}
}
}
int main()
{
BTNode* b;
ElemType path[Maxsize], longpath[Maxsize];
int i, longpathlen = 0;
CreateBTree(&b, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");
printf("二叉树b:"); DispBTree(b); printf("\n");
printf("先序遍历方法:\n"); AllPath1(b, path, 0);
LongPath1(b, path, 0, longpath, &longpathlen);
printf("第一条最长逆路径长度:%d\n", longpathlen);
printf("第一条最长逆路径:");
for (i = longpathlen - 1; i >= 0; i--)
printf("%c ", longpath[i]);
printf("\n");
printf("后序非递归遍历方法:\n"); AllPath2(b);
printf("层次遍历方法:\n"); AllPath3(b);
DestroyBtree(&b);
return 0;
}
8.算术表达式用树求解:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Maxsize 100
typedef char ElemType;
typedef struct node
{
ElemType data;
struct node* lchild;
struct node* rchild;
}BTNode;
//创建二叉树
void CreateBTree(BTNode** b, ElemType* str)
{
BTNode* St[Maxsize];
BTNode* p = NULL;
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 DestroyBtree(BTNode** b)
{
while ((*b) != NULL)
{
DestroyBtree(&((*b)->lchild));
DestroyBtree(&((*b)->rchild));
free(*b);
*b = NULL;
}
}
//返回值为x的结点
BTNode* FindNode(BTNode* b, ElemType 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(")");
}
}
}
//表达式对应的二叉树
BTNode* CRTree(char s[], int i, int j)
{
BTNode* p;
int k, posi = -1, plus = 0;
if (i == j)
{
p = (BTNode*)malloc(sizeof(BTNode));
p->data = s[i];
p->lchild = p->rchild = NULL;
return p;
}
for (k = i; k <= j; k++)
{
if (s[k] == '+' || s[k] == '-')
{
plus++;
posi = k;
}
}
if (plus == 0)
{
for (k = i; k <= j; k++)
{
if (s[k] == '*' || s[k] == '/')
{
plus++;
posi = k;
}
}
}
if (plus != 0)
{
p = (BTNode*)malloc(sizeof(BTNode));
p->data = s[posi];
p->lchild = CRTree(s, i, posi - 1);
p->rchild = CRTree(s, posi + 1, j);
return p;
}
else
{
return NULL;
}
}
//计算
double Comp(BTNode* b)
{
double v1, v2;
if (b == NULL)
return 0;
if (b->lchild == NULL && b->rchild == NULL)
return b->data - '0';
v1 = Comp(b->lchild);
v2 = Comp(b->rchild);
switch (b->data)
{
case'+':
return v1 + v2;
case'-':
return v1 - v2;
case'*':
return v1 * v2;
case'/':
if (v2 != 0)
return v1 / v2;
else
return 0; // 或者返回一个错误值,或者抛出异常
default:
return 0; // 默认情况下返回一个合适的默认值
}
}
int main()
{
BTNode* b;
ElemType s[Maxsize] = "1+2*3-4/5";
printf("算术表达式%s\n", s);
b = CRTree(s, 0, strlen(s) - 1);
printf("对应二叉树括号表示法");
DispBTree(b);
printf("\n算术表达式的值:%g\n", Comp(b));
DestroyBtree(&b);
return 0;
}