这是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二叉树 代码实现#include #include #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测试代码#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("%cn", 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树 代码实现#include #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%sn", __func__); BinTree* arr = buildBinTree(5); BinTree root = arr[1]; postOrderIteratively(root); DestoryBinTree(root); free(arr); printf("n"); } void test_invertLevelOrder() { printf("n%sn", __func__); BinTree* arr = buildBinTree(25); BinTree root = arr[1]; invertLevelOrder(root); DestoryBinTree(root); free(arr); printf("n"); } void test_Height() { printf("n%sn", __func__); BinTree* arr = buildBinTree(25); BinTree root = arr[1]; int h = Height(root); printf("nh=%dn", h); DestoryBinTree(root); free(arr); } void test_PreOrderAndInOrderCreate() { printf("n%sn", __func__); char pre[11] = {' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', ' '}; char in[11] = {' ', 'B', 'C', 'A', 'E', 'D', 'G', 'H', 'F', 'I', ' '}; printf("npre:%sn", pre + 1); printf("nin:%sn", 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%sn", __func__); BinTree* arr = buildBinTree(9); BinTree root = arr[1]; bool result = isComplete(root); printf("nresult=%dn", result); DestoryBinTree(arr[3]->left); arr[3]->left = NULL; result = isComplete(root); printf("nresult=%dn", result); DestoryBinTree(root); free(arr); } void test_DoubleSonNodes() { printf("n%sn", __func__); BinTree* arr = buildBinTree(11); BinTree root = arr[1]; int result; result = DoubleSonNodes(root); printf("nresult=%dn", result); DestoryBinTree(arr[3]->left); DestoryBinTree(arr[5]->left); arr[3]->left = NULL; arr[5]->left = NULL; result = DoubleSonNodes(root); printf("nresult=%dn", result); DestoryBinTree(root); free(arr); } void test_swapLetfRight() { printf("n%sn", __func__); BinTree* arr = buildBinTree(11); BinTree root = arr[1]; printf("nbefore:n"); PreOrderTraversal_recursively(root, visit); printf("nn"); LevelOrderTraversal(root, visit); printf("nn"); swapLeftRight(root); printf("nafter:n"); PreOrderTraversal_recursively(root, visit); printf("nn"); LevelOrderTraversal(root, visit); printf("nn"); DestoryBinTree(root); free(arr); } void test_NthPreNode() { printf("n%sn", __func__); BinTree* arr = buildBinTree(11); BinTree root = arr[1]; int N = 6; PreOrderTraversal_recursively(root, visit); BinTreeElemType ret = NthPreNode(root, N); printf("n%d-%cn", N, ret); i = 1; N = 11; ret = NthPreNode(root, N); printf("n%d-%cn", N, ret); i = 1; N = 12; ret = NthPreNode(root, N); printf("n%d-%cn", N, ret); DestoryBinTree(root); free(arr); } void test_deleteAllX() { printf("n%sn", __func__); BinTree* arr = buildBinTree(11); BinTree root = arr[1]; arr[5]->data = 'X'; PreOrderTraversal_recursively(root, visit); printf("nn"); deleteAllX(root, 'X'); PreOrderTraversal_recursively(root, visit); printf("nn"); DestoryBinTree(root); free(arr); } void test_printXAncestors() { printf("n%sn", __func__); BinTree* arr = buildBinTree(11); BinTree root = arr[1]; printXAncestors(root, 'H'); DestoryBinTree(root); free(arr); } void test_CommonAncestor() { printf("n%sn", __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=%cn", 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=%cn", p->data, q->data, ancestor->data); } } void test_width() { printf("n%sn", __func__); BinTree* arr = buildBinTree(15); BinTree root = arr[1]; int w = width(root); printf("nw=%dn", w); arr[5]->left = arr[5]->right = NULL; arr[6]->left = arr[6]->right = NULL; arr[7]->left = NULL; w = width(root); printf("nw=%dn", w); DestoryBinTree(root); free(arr); } void test_pre2post() { BinTreeElemType pre[] = "ABDECFG"; BinTreeElemType post[8]; pre2post(pre, 0, 6, post, 0, 6); post[8] = ' '; printf("npre:%snpost:%sn", pre, post); } void test_inOrderlinkLeaves() { printf("n%sn", __func__); BinTree* arr = buildBinTree(15); BinTree root = arr[1]; BinTree h = inOrderlinkLeaves(root); while (h) { printf("%c ", h->data); h = h->right; } printf("nn"); //DestoryBinTree(root); free(arr); } void test_similar() { printf("n%sn", __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=%dn", result); deleteSubTree(arr2[5]->right); arr2[5]->right = NULL; result = similar(root1, root2); printf("nresult=%dn", result); deleteSubTree(root1); deleteSubTree(root2); root1 = root2 = NULL; result = similar(root1, root2); printf("nresult=%dn", result); free(arr1); free(arr2); } void test_findPostPrevInOrderThread() { //这个测试不好测,省去了,考的概率不大 } void test_WPL() { printf("n%sn", __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=%dn", wpl); DestoryBinTree(root); free(arr); } void test_printexpressionTree() { printf("n%sn", __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("nn"); 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测试代码typedef char FCNSTreeElemType; //1-求以孩子兄弟表示法存储的树的叶子节点总数 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); } } //2-求树的高度 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; } //3-已知一颗树的层次序列及每个节点的度,构造此树的孩子-兄弟链表 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树与二叉树的应用 代码实现#include #include #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]; 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=%dn", l); } void test_height() { 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=%dn", h); 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=%dn", h); free(n10); free(n11); } void test_createTree() { 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("nn"); } 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#include #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%sn", __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=%dn", result); prev = -1; n[6].data = 121; result = judgeIsBST(root); printf("nresult=%dn", result); prev = -1; n[3].left = NULL; result = judgeIsBST(root); printf("nresult=%dn", result); } void test_level() { printf("n%sn", __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=%dn", l); l = level(root, 107); printf("nl=%dn", l); l = level(root, 98); printf("nl=%dn", l); l = level(root, 15); l = level(root, 1); printf("nl=%dn", l); } void test_judgeAVL() { printf("n%sn", __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=%dn", b); } void test_maxElemInBST_minElemInBST() { printf("n%sn", __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=%dn", result); result = minElemInBST(root); printf("nminElem=%dn", result); } void test_printDescendingGEk() { printf("n%sn", __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("nn"); } 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; }



