概述
这是2022版王道数据结构的第5章——树与二叉树的算法大题的C语言代码实现,主要分为二叉树,树和树与二叉树的应用三部分。代码基本都经过了简单的测试,应该不会有太大问题。
编译环境为gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
,文件目录结构如下:
ch5
├── 5-3-binaryTree.c
├── 5-4-tree.c
├── 5-5-application.c
├── application_test.c
├── binaryTree_test.c
├── queueAndStack.c
└── tree_test.c
queueAndStack.c
中实现了自定义的队列和栈的结构及其操作集,也定义了二叉树节点类型如下:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define BinTreeElemType char
#define StackElemType BinTree
#define QueueElemType BinTree
#define NOINFO '0'
struct TreeNode {
BinTreeElemType data;
struct TreeNode* left;
struct TreeNode* right;
};
typedef struct TreeNode TreeNode;
typedef struct TreeNode* BinTree;
二叉树
代码实现
#include <string.h>
#include "queueAndStack.c"
void visit(BinTree p) {
printf("%c ", p->data);
}
//3-后序非递归遍历二叉树
void postOrderIteratively(BinTree t) {
if (t != NULL) {
Stack s = CreateStack();
BinTree r = NULL;
BinTree p = t;
while (p || !StackEmpty(s)) {
if (p) {
Push(s, p);
p = p->left;
} else {
Top(s, &p);
if (p->right && p->right != r) {
p = p->right;
} else {
Pop(s, &p);
visit(p);
r = p;
p = NULL;
}
}
}
DestoryStack(s);
}
}
//4-逆序层序遍历
void invertLevelOrder(BinTree t) {
if (t) {
BinTree p = t;
Queue q = CreateQueue();
Stack s = CreateStack();
EnQueue(q, p);
while (!QueueEmpty(q)) {
DeQueue(q, &p);
Push(s, p);
if (p->left)
EnQueue(q, p->left);
if (p->right)
EnQueue(q, p->right);
}
while (!StackEmpty(s)) {
Pop(s, &p);
visit(p);
}
DestoryStack(s);
DestoryQueue(q);
}
}
//5-非递归求二叉树高度
int Height(BinTree t) {
if (t == NULL)
return 0;
int front = -1;
int rear = -1;
int level = 0;
int last = 0;
BinTree p = t;
BinTree q[64];
q[++rear] = t;
while (front < rear) {
p = q[++front];
if (p->left)
q[++rear] = p->left;
if (p->right)
q[++rear] = p->right;
if (front == last) {
level++;
last = rear;
}
}
return level;
}
//6-从先序和中序遍历序列确定一棵二叉树
BinTree PreOrderAndInOrderCreate(BinTreeElemType A[], int la, int ra, BinTreeElemType B[], int lb, int rb) {
int i = 0;
BinTree root = malloc(sizeof(struct TreeNode));
root->data = A[la];
for (i = 0; root->data != B[i]; ++i)
;
int llen = i - lb;
int rlen = rb - i;
if (llen)
root->left = PreOrderAndInOrderCreate(A, la + 1, la + llen, B, lb, lb + llen - 1);
else
root->left = NULL;
if (rlen)
root->right = PreOrderAndInOrderCreate(A, ra - rlen + 1, ra, B, rb - rlen + 1, rb);
else
root->right = NULL;
return root;
}
//7-判断是否是完全二叉树
bool isComplete(BinTree t) {
if (t == NULL)
return true;
Queue q = CreateQueue();
BinTree p = t;
EnQueue(q, p);
while (!QueueEmpty(q)) {
DeQueue(q, &p);
if (p) {
EnQueue(q, p->left);
EnQueue(q, p->right);
} else {
//一旦层序遍历到了一个空节点,则它之后的节点必然全是空的,否则return false
while (!QueueEmpty(q)) {
DeQueue(q, &p);
if (p)
return false;
}
}
}
DestoryQueue(q);
return true;
}
//8-求树中degree==2的节点的数量,纯递归
int DoubleSonNodes(BinTree t) {
if (t == NULL) {
return 0;
} else if (t->left && t->right) {
return 1 + DoubleSonNodes(t->left) + DoubleSonNodes(t->right);
} else {
return DoubleSonNodes(t->left) + DoubleSonNodes(t->right);
}
}
//9-交换左右子树
void swapLeftRight(BinTree t) {
if (t) {
//采用后序遍历的策略,待左右子树都交换完成后,再交换自身
swapLeftRight(t->left);
swapLeftRight(t->right);
BinTree temp = t->left;
t->left = t->right;
t->right = temp;
}
}
//10-寻找先序遍历序列中第N个节点,约定若为空返回'#'
#define NOTFOUND '#'
int i = 1;
BinTreeElemType NthPreNode(BinTree t, int N) {
if (t == NULL)
return NOTFOUND;
if (i == N)
return t->data;
i++;
BinTreeElemType ch = NthPreNode(t->left, N);
if (ch != NOTFOUND)
return ch;
ch = NthPreNode(t->right, N);
return ch;
}
void deleteSubTree(BinTree t) {
if (t) {
deleteSubTree(t->left);
deleteSubTree(t->right);
free(t);
}
}
//11-删除二叉树每个元素值为X的节点
void deleteAllX(BinTree t, BinTreeElemType x) {
if (t == NULL)
return;
if (t->data == x) {
deleteSubTree(t);
return;
}
Queue q = CreateQueue();
BinTree p = t;
EnQueue(q, p);
while (!QueueEmpty(q)) {
DeQueue(q, &p);
if (p->left) {
if (p->left->data == x) {
deleteSubTree(p->left);
p->left = NULL;
} else {
EnQueue(q, p->left);
}
}
if (p->right) {
if (p->right->data == x) {
deleteSubTree(p->right);
p->right = NULL;
} else {
EnQueue(q, p->right);
}
}
}
DestoryQueue(q);
}
//12-打印x的所有祖先
void printXAncestors(BinTree t, BinTreeElemType x) {
if (t == NULL)
return;
BinTree p = t;
BinTree r = NULL;
Stack s = CreateStack();
while (!StackEmpty(s) || p != NULL) {
if (p) {
Push(s, p);
p = p->left;
} else {
Top(s, &p);
if (p->right != NULL && p->right != r) {
p = p->right;
} else {
Pop(s, &p);
//visit
if (p->data == x) {
//当前访问节点为x,则弹空栈中x的所有祖先并打印
while (!StackEmpty(s)) {
Pop(s, &p);
printf("%c\n", p->data);
}
return;
}
r = p;
p = NULL;
}
}
}
DestoryStack(s);
}
//13-寻找p和q的公共祖先,不妨假设p在q的左边
BinTree CommonAncestor(BinTree t, BinTree p, BinTree q) {
if (t == NULL || p == NULL || q == NULL)
return NULL;
int last = -1;
BinTree curr = t;
BinTree r = NULL;
BinTree dump[64]; //转储遇到p时的栈,里面是p的所有祖先
Stack s = CreateStack();
while (!StackEmpty(s) || curr != NULL) {
if (curr) {
Push(s, curr);
curr = curr->left;
} else {
Top(s, &curr);
if (curr->right && curr->right != r) {
curr = curr->right;
} else {
Pop(s, &curr);
//visit
if (curr == p) {
//转储并复原s
BinTree t;
while (!StackEmpty(s)) {
Pop(s, &t);
dump[++last] = t;
}
for (int i = last; i >= 0; --i) {
Push(s, dump[i]);
}
}
if (curr == q) {
BinTree t;
//逐个比对此时栈中的元素和dump中的元素
while (!StackEmpty(s)) {
Pop(s, &t);
for (int i = 0; i <= last; ++i) {
if (dump[i] == t) {
return t;
}
}
}
}
r = curr;
curr = NULL;
}
}
}
//应该是多余的,但是不返回一个值编译器会报警告
//老强迫症了
return t;
DestoryStack(s);
}
//14-求二叉树的宽度
int width(BinTree t) {
if (t == NULL)
return 0;
struct {
BinTree data[128];
int level[128];
int front;
int rear;
} Que;
memset(&Que, 0, sizeof(Que));
Que.front = Que.rear = -1;
BinTree p = t;
int k, max, n;
Que.data[++Que.rear] = p;
Que.level[Que.rear] = 1;
while (Que.front < Que.rear) {
p = Que.data[++Que.front];
k = Que.level[Que.front];
if (p->left) {
Que.data[++Que.rear] = p->left;
Que.level[Que.rear] = k + 1;
}
if (p->right) {
Que.data[++Que.rear] = p->right;
Que.level[Que.rear] = k + 1;
}
}
int i = 0;
while (i <= Que.rear) {
n = 0;
while (i <= Que.rear && Que.level[i] == k) {
n++;
i++;
}
k = Que.level[i];
if (n > max)
max = n;
}
return max;
}
//15-对一棵满二叉树,已知先序序列,求后序序列
void pre2post(BinTreeElemType pre[], int lPre, int rPre, BinTreeElemType post[], int lPost, int rPost) {
int half;
if (rPre >= lPre) {
post[rPost] = pre[lPre];
half = (rPre - lPre) / 2;
pre2post(pre, lPre + 1, lPre + half, post, lPost, lPost + half - 1);
pre2post(pre, lPre + half + 1, rPre, post, lPost + half, rPost - 1);
}
}
//16-将二叉树的叶节点链接成单链表
BinTree head = NULL;
BinTree rear = NULL;
BinTree inOrderLinkLeaves(BinTree bt) {
if (bt) {
inOrderLinkLeaves(bt->left);
if (bt->left == NULL && bt->right == NULL) {
if (head == NULL) {
head = bt;
rear = bt;
} else {
rear->right = bt;
rear = rear->right;
}
}
inOrderLinkLeaves(bt->right);
rear->right = NULL;
}
return head;
}
//17-判断两课树是否相似
bool similar(BinTree t1, BinTree t2) {
bool sLeft, sRight;
if (t1 == NULL && t2 == NULL) {
return true;
} else if (t1 == NULL || t2 == NULL) {
return false;
} else {
sLeft = similar(t1->left, t2->left);
sRight = similar(t1->right, t2->right);
return sLeft && sRight;
}
}
//18-在中序线索二叉树里查找指定节点在后序中的前驱节点
#define ThreadBinTreeElemType char
//线索二叉树节点类型
struct ThreadBinTreeNode {
ThreadBinTreeElemType data;
struct ThreadBinTreeNode* left;
struct ThreadBinTreeNode* right;
int ltag;
int rtag;
};
typedef struct ThreadBinTreeNode ThreadBinTreeNode;
typedef struct ThreadBinTreeNode* ThreadBinTree;
ThreadBinTree findPostPrevInOrderThread(ThreadBinTree t, ThreadBinTree p) {
ThreadBinTree q;
if (p->rtag == 0) {
q = p->right;
} else if (p->ltag == 0) {
q = p->left;
} else if (p->left == NULL) {
q = NULL;
} else {
while (p->ltag == 1 && p->left != NULL) {
p = p->left;
}
if (p->ltag == 0) {
q = p->left;
} else {
q = NULL;
}
}
return q;
}
//19-计算WPL
int WPL_preOrder(BinTree t, int deepth) {
static int wpl = 0;
if (t->left == NULL && t->right == NULL) {
wpl += deepth * (t->data);
}
if (t->left)
WPL_preOrder(t->left, deepth + 1);
if (t->right)
WPL_preOrder(t->right, deepth + 1);
return wpl;
}
int WPL(BinTree bt) {
return WPL_preOrder(bt, 0);
}
//20-将给定的表达式树转化为中缀表达式
void printInOrder(BinTree t, int deep) {
if (t == NULL) {
return;
} else if (t->left == NULL && t->right == NULL) {
printf("%c", t->data);
} else {
if (deep > 1)
printf("(");
printInOrder(t->left, deep + 1);
printf("%c", t->data);
printInOrder(t->right, deep + 1);
if (deep > 1)
printf(")");
}
}
void printExpressionTree(BinTree t) {
printInOrder(t, 1);
}
测试代码
#include <stdio.h>
#include <stdlib.h>
#include "5-3-binaryTree.c"
void PreOrderTraversal_recursively(BinTree t, void (*visit)(BinTree x)) {
if (t != NULL) {
visit(t);
PreOrderTraversal_recursively(t->left, visit);
PreOrderTraversal_recursively(t->right, visit);
}
}
void InOrderTraversal_recursively(BinTree t, void (*visit)(BinTree x)) {
if (t != NULL) {
InOrderTraversal_recursively(t->left, visit);
visit(t);
InOrderTraversal_recursively(t->right, visit);
}
}
void PostOrderTraversal_recursively(BinTree t, void (*visit)(BinTree x)) {
if (t != NULL) {
PostOrderTraversal_recursively(t->left, visit);
PostOrderTraversal_recursively(t->right, visit);
visit(t);
}
}
void LevelOrderTraversal(BinTree t, void (*visit)(BinTree x)) {
if (t == NULL)
return;
Queue q = CreateQueue();
BinTree curr = t;
EnQueue(q, curr);
while (!QueueEmpty(q)) {
DeQueue(q, &curr);
visit(curr);
if (curr->left != NULL)
EnQueue(q, curr->left);
if (curr->right != NULL)
EnQueue(q, curr->right);
}
DestoryQueue(q);
}
BinTree* buildBinTree(int n) {
BinTree* arr = (BinTree*)malloc(sizeof(BinTree) * (n + 1));
arr[0] = NULL;
for (int i = 1; i <= n; ++i) {
arr[i] = malloc(sizeof(struct TreeNode));
arr[i]->data = 'A' + i - 1;
arr[i]->left = arr[i]->right = NULL;
}
for (int i = 1; i <= n / 2; ++i) {
arr[i]->left = arr[2 * i];
arr[i]->right = arr[2 * i + 1];
}
return arr;
}
void DestoryBinTree(BinTree t) {
if (t) {
DestoryBinTree(t->left);
DestoryBinTree(t->right);
free(t);
}
}
void test_postOrderIteratively() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(5);
BinTree root = arr[1];
postOrderIteratively(root);
DestoryBinTree(root);
free(arr);
printf("\n");
}
void test_invertLevelOrder() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(25);
BinTree root = arr[1];
invertLevelOrder(root);
DestoryBinTree(root);
free(arr);
printf("\n");
}
void test_Height() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(25);
BinTree root = arr[1];
int h = Height(root);
printf("\nh=%d\n", h);
DestoryBinTree(root);
free(arr);
}
void test_PreOrderAndInOrderCreate() {
printf("\n%s\n", __func__);
char pre[11] = {'\0', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', '\0'};
char in[11] = {'\0', 'B', 'C', 'A', 'E', 'D', 'G', 'H', 'F', 'I', '\0'};
printf("\npre:%s\n", pre + 1);
printf("\nin:%s\n", in + 1);
BinTree root = PreOrderAndInOrderCreate(pre, 1, 9, in, 1, 9);
PreOrderTraversal_recursively(root, visit);
printf("\n");
InOrderTraversal_recursively(root, visit);
printf("\n");
DestoryBinTree(root);
}
void test_isComplete() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(9);
BinTree root = arr[1];
bool result = isComplete(root);
printf("\nresult=%d\n", result);
DestoryBinTree(arr[3]->left);
arr[3]->left = NULL;
result = isComplete(root);
printf("\nresult=%d\n", result);
DestoryBinTree(root);
free(arr);
}
void test_DoubleSonNodes() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(11);
BinTree root = arr[1];
int result;
result = DoubleSonNodes(root);
printf("\nresult=%d\n", result);
DestoryBinTree(arr[3]->left);
DestoryBinTree(arr[5]->left);
arr[3]->left = NULL;
arr[5]->left = NULL;
result = DoubleSonNodes(root);
printf("\nresult=%d\n", result);
DestoryBinTree(root);
free(arr);
}
void test_swapLetfRight() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(11);
BinTree root = arr[1];
printf("\nbefore:\n");
PreOrderTraversal_recursively(root, visit);
printf("\n\n");
LevelOrderTraversal(root, visit);
printf("\n\n");
swapLeftRight(root);
printf("\nafter:\n");
PreOrderTraversal_recursively(root, visit);
printf("\n\n");
LevelOrderTraversal(root, visit);
printf("\n\n");
DestoryBinTree(root);
free(arr);
}
void test_NthPreNode() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(11);
BinTree root = arr[1];
int N = 6;
PreOrderTraversal_recursively(root, visit);
BinTreeElemType ret = NthPreNode(root, N);
printf("\n%d-%c\n", N, ret);
i = 1;
N = 11;
ret = NthPreNode(root, N);
printf("\n%d-%c\n", N, ret);
i = 1;
N = 12;
ret = NthPreNode(root, N);
printf("\n%d-%c\n", N, ret);
DestoryBinTree(root);
free(arr);
}
void test_deleteAllX() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(11);
BinTree root = arr[1];
arr[5]->data = 'X';
PreOrderTraversal_recursively(root, visit);
printf("\n\n");
deleteAllX(root, 'X');
PreOrderTraversal_recursively(root, visit);
printf("\n\n");
DestoryBinTree(root);
free(arr);
}
void test_printXAncestors() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(11);
BinTree root = arr[1];
printXAncestors(root, 'H');
DestoryBinTree(root);
free(arr);
}
void test_CommonAncestor() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(11);
BinTree root = arr[1];
BinTree p = arr[4];
BinTree q = arr[10];
BinTree ancestor = CommonAncestor(root, p, q);
if (ancestor) {
printf("\np->data=%c,q->data=%c,ancestor->data=%c\n", p->data, q->data, ancestor->data);
}
p = arr[3];
ancestor = CommonAncestor(root, p, q);
if (ancestor) {
printf("\np->data=%c,q->data=%c,ancestor->data=%c\n", p->data, q->data, ancestor->data);
}
}
void test_width() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(15);
BinTree root = arr[1];
int w = width(root);
printf("\nw=%d\n", w);
arr[5]->left = arr[5]->right = NULL;
arr[6]->left = arr[6]->right = NULL;
arr[7]->left = NULL;
w = width(root);
printf("\nw=%d\n", w);
DestoryBinTree(root);
free(arr);
}
void test_pre2post() {
BinTreeElemType pre[] = "ABDECFG";
BinTreeElemType post[8];
pre2post(pre, 0, 6, post, 0, 6);
post[8] = '\0';
printf("\npre:%s\npost:%s\n", pre, post);
}
void test_inOrderLinkLeaves() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(15);
BinTree root = arr[1];
BinTree h = inOrderLinkLeaves(root);
while (h) {
printf("%c ", h->data);
h = h->right;
}
printf("\n\n");
//DestoryBinTree(root);
free(arr);
}
void test_similar() {
printf("\n%s\n", __func__);
BinTree* arr1 = buildBinTree(15);
BinTree root1 = arr1[1];
BinTree* arr2 = buildBinTree(15);
BinTree root2 = arr2[1];
bool result;
result = similar(root1, root2);
printf("\nresult=%d\n", result);
deleteSubTree(arr2[5]->right);
arr2[5]->right = NULL;
result = similar(root1, root2);
printf("\nresult=%d\n", result);
deleteSubTree(root1);
deleteSubTree(root2);
root1 = root2 = NULL;
result = similar(root1, root2);
printf("\nresult=%d\n", result);
free(arr1);
free(arr2);
}
void test_findPostPrevInOrderThread() {
//这个测试不好测,省去了,考的概率不大
}
void test_WPL() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(15);
BinTree root = arr[1];
for (int i = 8; i <= 15; ++i) {
arr[i]->data = i - 7;
}
deleteSubTree(arr[2]->right);
arr[2]->right = NULL;
int wpl = WPL(root);
printf("\nwpl=%d\n", wpl);
DestoryBinTree(root);
free(arr);
}
void test_printExpressionTree() {
printf("\n%s\n", __func__);
BinTree* arr = buildBinTree(15);
BinTree root = arr[1];
deleteSubTree(arr[4]->left);
arr[4]->left = NULL;
deleteSubTree(arr[4]->right);
arr[4]->right = NULL;
deleteSubTree(arr[5]->left);
arr[5]->left = NULL;
deleteSubTree(arr[5]->right);
arr[5]->right = NULL;
deleteSubTree(arr[6]->left);
arr[6]->left = NULL;
deleteSubTree(arr[6]->left);
arr[6]->right = NULL;
deleteSubTree(arr[7]->left);
arr[7]->left = NULL;
arr[1]->data = '*';
arr[2]->data = '+';
arr[3]->data = '*';
arr[4]->data = 'a';
arr[5]->data = 'b';
arr[6]->data = 'c';
arr[7]->data = '-';
arr[15]->data = 'd';
printExpressionTree(root);
printf("\n\n");
DestoryBinTree(root);
free(arr);
}
int main(int argc, char* argv[]) {
#if 0
test_postOrderIteratively();
test_invertLevelOrder();
test_Height();
test_PreOrderAndInOrderCreate();
test_isComplete();
test_DoubleSonNodes();
test_swapLetfRight();
test_NthPreNode();
test_deleteAllX();
test_printXAncestors();
test_CommonAncestor();
test_width();
test_pre2post();
test_inOrderLinkLeaves();
test_similar();
test_findPostPrevInOrderThread();
test_WPL();
#endif
test_printExpressionTree();
return 0;
}
树
代码实现
#include <stdlib.h>
typedef char FCNSTreeElemType;
//5-求以孩子兄弟表示法存储的树的叶子节点总数
struct FCNSTreeNode {
FCNSTreeElemType data;
struct FCNSTreeNode* firstChild;
struct FCNSTreeNode* nextSibling;
};
typedef struct FCNSTreeNode* FCNSTree;
typedef struct FCNSTreeNode FCNSTreeNode;
int countLeaves(FCNSTree t) {
if (t == NULL) {
return 0;
} else if (t->firstChild == NULL) {
//printf("%c ", t->data);
return 1 + countLeaves(t->nextSibling);
} else {
return countLeaves(t->firstChild) + countLeaves(t->nextSibling);
}
}
//6-求树的高度
int height(FCNSTree t) {
if (t == NULL)
return 0;
int h_fc = height(t->firstChild);
int h_ns = height(t->nextSibling);
return ((h_fc + 1) > h_ns) ? (h_fc + 1) : h_ns;
}
//7-已知一颗树的层次序列及每个节点的度,构造此树的孩子-兄弟链表
FCNSTree createTree(FCNSTreeElemType e[], int degree[], int N) {
FCNSTree nodes = (FCNSTree)malloc(sizeof(FCNSTreeNode) * N);
int i, j, d, k = 0;
for (i = 0; i < N; ++i) {
nodes[i].data = e[i];
nodes[i].firstChild = nodes[i].nextSibling = NULL;
}
for (i = 0; i < N; ++i) {
d = degree[i];
if (d) {
k++;
nodes[i].firstChild = &nodes[k];
for (j = 2; j <= d; ++j) {
k++;
nodes[k - 1].nextSibling = &nodes[k];
}
}
}
return nodes;
}
测试代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "5-4-tree.c"
void preOrderPrint(FCNSTree t) {
if (t) {
printf("%c ", t->data);
preOrderPrint(t->firstChild);
preOrderPrint(t->nextSibling);
}
}
void test_countLeaves() {
FCNSTreeNode nodes[10];
/*
A
|
B----C----D
| | |
E-F G H----I----J
*/
for (int i = 0; i < 10; ++i) {
nodes[i].data = 'A' + i;
nodes[i].firstChild = nodes[i].nextSibling = NULL;
}
nodes[0].firstChild = &nodes[1];
nodes[1].firstChild = &nodes[4];
nodes[1].nextSibling = &nodes[2];
nodes[2].firstChild = &nodes[6];
nodes[2].nextSibling = &nodes[3];
nodes[3].firstChild = &nodes[7];
nodes[7].nextSibling = &nodes[8];
nodes[8].nextSibling = &nodes[9];
nodes[4].nextSibling = &nodes[5];
int l = countLeaves(&nodes[0]);
printf("\nl=%d\n", l);
}
void test_height() {
/*
A
|
B----C----D
| | |
E-F G H----I----J
*/
FCNSTreeNode nodes[10];
for (int i = 0; i < 10; ++i) {
nodes[i].data = 'A' + i;
nodes[i].firstChild = nodes[i].nextSibling = NULL;
}
nodes[0].firstChild = &nodes[1];
nodes[1].firstChild = &nodes[4];
nodes[1].nextSibling = &nodes[2];
nodes[2].firstChild = &nodes[6];
nodes[2].nextSibling = &nodes[3];
nodes[3].firstChild = &nodes[7];
nodes[7].nextSibling = &nodes[8];
nodes[8].nextSibling = &nodes[9];
nodes[4].nextSibling = &nodes[5];
int h;
h = height(&nodes[0]);
printf("\nh=%d\n", h);
/*
再加上两个节点
A
|
B----C----D
| | |
E-F G H----I----J
|
K
|
L
*/
FCNSTreeNode* n10 = (FCNSTreeNode*)malloc(sizeof(FCNSTreeNode));
nodes[6].firstChild = n10;
n10->data = 'K';
n10->nextSibling = NULL;
FCNSTreeNode* n11 = (FCNSTreeNode*)malloc(sizeof(FCNSTreeNode));
n11->data = 'L';
n10->firstChild = n11;
n11->firstChild = NULL;
n11->nextSibling = NULL;
//countLeaves(nodes);
h = height(&nodes[0]);
printf("\nh=%d\n", h);
free(n10);
free(n11);
}
void test_createTree() {
/*
A
|
B----C----D
| | |
E-F G H----I----J
*/
int degree[10] = {3, 2, 1, 3, 0, 0, 0, 0, 0, 0};
FCNSTreeElemType e[10];
for (int i = 0; i < 10; ++i) {
e[i] = 'A' + i;
}
FCNSTree root = createTree(e, degree, 10);
preOrderPrint(root);
printf("\n\n");
}
int main(int argc, char* argv[]) {
#if 0
test_countLeaves();
test_height();
#endif
test_createTree();
return 0;
}
树与二叉树的应用
代码实现
#include "queueAndStack.c"
//6-判断给定的二叉树是否是二叉排序树
BinTreeElemType prev = -1;
bool judgeIsBST(BinTree t) {
if (t == NULL) {
return true;
} else {
bool bl = judgeIsBST(t->left);
if (bl == false || prev >= t->data) {
return false;
}
prev = t->data;
bool br = judgeIsBST(t->right);
return br;
}
}
//7-求指定节点值在给定BST中的层次
int level(BinTree t, BinTreeElemType x) {
BinTree p = t;
int n = 0;
if (p) {
n++;
while (p != NULL && p->data != x) {
if (x > p->data)
p = p->right;
else
p = p->left;
n++;
}
}
return (p == NULL) ? -1 : n;
}
int abs(int a) {
if (a > 0)
return a;
else
return -a;
}
//8-利用二叉树遍历的思想判断一棵树是否是平衡二叉树
void judgeAVL(BinTree t, bool* balance, int* h) {
bool bl = false;
bool br = false;
int hl = 0;
int hr = 0;
if (t == NULL) {
*h = 0;
*balance = true;
} else if (t->left == NULL && t->right == NULL) {
*h = 1;
*balance = 1;
} else {
judgeAVL(t->left, &bl, &hl);
judgeAVL(t->right, &br, &hr);
*h = (hl > hr ? hl : hr) + 1;
if (abs(hl - hr) < 2) {
*balance = bl && br;
} else {
*balance = false;
}
}
}
//9-求出给定BST中的最小和最大关键字
BinTreeElemType maxElemInBST(BinTree bt) {
if (bt == NULL)
return 0;
while (bt->left)
bt = bt->left;
return bt->data;
}
BinTreeElemType minElemInBST(BinTree bt) {
if (bt == NULL)
return 0;
while (bt->right)
bt = bt->right;
return bt->data;
}
//10-从大到小输出BST中所有值>=k的关键字
void printDescendingGEk(BinTree bt, int k) {
if (bt == NULL)
return;
if (bt->right)
printDescendingGEk(bt->right, k);
if (bt->data >= k)
printf("%d ", bt->data);
if (bt->left)
printDescendingGEk(bt->left, k);
}
//12-求BST中第k小的元素,其中BST的节点增设count域,保存以该节点为跟的子树上的节点个数
struct TreeNode_count {
BinTreeElemType data;
int count;
struct TreeNode_count* left;
struct TreeNode_count* right;
};
typedef struct TreeNode_count* BinTree_count;
BinTree_count findKthSamllest(BinTree_count bt, int k) {
if (k < 1 || k > bt->count)
return NULL;
if (bt->left == NULL) {
if (bt->right == NULL && k == 1) {
return bt;
} else {
return findKthSamllest(bt->right, k - 1);
}
} else {
if (bt->left->count == k - 1) {
return bt;
} else if (bt->left->count > k - 1) {
return findKthSamllest(bt->left, k);
} else {
return findKthSamllest(bt->right, k - bt->left->count - 1);
}
}
}
测试代码
#include <stdio.h>
#include <stdlib.h>
#include "5-5-application.c"
BinTree insertBST(BinTree root, int x) {
if (root == NULL) {
BinTree new = (BinTree)malloc(sizeof(struct TreeNode));
new->data = x;
new->left = new->right = NULL;
return new;
} else if (x > root->data) {
root->right = insertBST(root->right, x);
} else if (x < root->data) {
root->left = insertBST(root->left, x);
}
return root;
}
void inOrderTraversal(BinTree t) {
if (t) {
inOrderTraversal(t->left);
printf("%d ", t->data);
inOrderTraversal(t->right);
}
}
void test_judgeIsBST() {
printf("\n%s\n", __func__);
bool result;
TreeNode n[8];
n[0].data = -1;
for (int i = 0; i < 8; ++i) {
n[i].left = n[i].right = NULL;
}
for (int i = 1; i <= 3; ++i) {
n[i].left = &n[2 * i];
n[i].right = &n[2 * i + 1];
}
n[1].data = 34;
n[2].data = 23;
n[3].data = 107;
n[4].data = 15;
n[5].data = 28;
n[6].data = 98;
n[7].data = 115;
BinTree root = n + 1;
//inOrderTraversal(root);
result = judgeIsBST(root);
printf("\nresult=%d\n", result);
prev = -1;
n[6].data = 121;
result = judgeIsBST(root);
printf("\nresult=%d\n", result);
prev = -1;
n[3].left = NULL;
result = judgeIsBST(root);
printf("\nresult=%d\n", result);
}
void test_level() {
printf("\n%s\n", __func__);
TreeNode n[8];
n[0].data = -1;
for (int i = 0; i < 8; ++i) {
n[i].left = n[i].right = NULL;
}
for (int i = 1; i <= 3; ++i) {
n[i].left = &n[2 * i];
n[i].right = &n[2 * i + 1];
}
n[1].data = 34;
n[2].data = 23;
n[3].data = 107;
n[4].data = 15;
n[5].data = 28;
n[6].data = 98;
n[7].data = 115;
BinTree root = n + 1;
int l;
l = level(root, 34);
printf("\nl=%d\n", l);
l = level(root, 107);
printf("\nl=%d\n", l);
l = level(root, 98);
printf("\nl=%d\n", l);
l = level(root, 15);
l = level(root, 1);
printf("\nl=%d\n", l);
}
void test_judgeAVL() {
printf("\n%s\n", __func__);
TreeNode n[8];
n[0].data = -1;
for (int i = 0; i < 8; ++i) {
n[i].left = n[i].right = NULL;
}
for (int i = 1; i <= 3; ++i) {
n[i].left = &n[2 * i];
n[i].right = &n[2 * i + 1];
}
n[1].data = 34;
n[2].data = 23;
n[3].data = 107;
n[4].data = 15;
n[5].data = 28;
n[6].data = 98;
n[7].data = 115;
BinTree root = n + 1;
bool b = false;
int h;
judgeAVL(root, &b, &h);
printf("\nb=%d\n", b);
}
void test_maxElemInBST_minElemInBST() {
printf("\n%s\n", __func__);
TreeNode n[8];
n[0].data = -1;
for (int i = 0; i < 8; ++i) {
n[i].left = n[i].right = NULL;
}
for (int i = 1; i <= 3; ++i) {
n[i].left = &n[2 * i];
n[i].right = &n[2 * i + 1];
}
n[1].data = 34;
n[2].data = 23;
n[3].data = 107;
n[4].data = 15;
n[5].data = 28;
n[6].data = 98;
n[7].data = 115;
BinTree root = n + 1;
int result;
result = maxElemInBST(root);
printf("\nmaxElem=%d\n", result);
result = minElemInBST(root);
printf("\nminElem=%d\n", result);
}
void test_printDescendingGEk() {
printf("\n%s\n", __func__);
TreeNode n[8];
n[0].data = -1;
for (int i = 0; i < 8; ++i) {
n[i].left = n[i].right = NULL;
}
for (int i = 1; i <= 3; ++i) {
n[i].left = &n[2 * i];
n[i].right = &n[2 * i + 1];
}
n[1].data = 34;
n[2].data = 23;
n[3].data = 107;
n[4].data = 15;
n[5].data = 28;
n[6].data = 98;
n[7].data = 115;
BinTree root = n + 1;
printDescendingGEk(root, 43);
printf("\n\n");
}
void test_findKthSamllest() {
//不好测,算了
}
int main(int argc, char* argv[]) {
#if 0
test_judgeIsBST();
test_level();
test_judgeAVL();
test_maxElemInBST_minElemInBST();
#endif
test_printDescendingGEk();
return 0;
}