カプセル化された二分木アルゴリズム
文字列ツールは、数値文字列string.hの不正確な比較のバグを回避します。
#プラグマ ワンス #ifdef __cplusplus 外部 "C" { #endif #ifndef STRING_H #定義 STRING_H int stringCompare( char * first , char * Second ); #endif #ifdef __cplusplus } #endif |
文字列.c
#define _CRT_SECURE_NO_WARNINGS //C4996 警告を回避する #include "string.h" #include < string.h > int stringCompare( char * first , char * Second ) { if (strspn( first , "0123456789" ) >= strlen( first ) && strspn(秒, "0123456789" ) >= strlen(秒)) { int 1 = atoi(最初)、2 = atoi( 2 番目); (1 > 2)の場合は 1を返します。 if (1 == 2) は 0を返します。 (1 < 2)の場合は -1を返します。 } それ以外 { return strcmp( first , Second ); } } |
binaryTree .h ヘッダー ファイル:
#プラグマ ワンス #ifdef __cplusplus extern "C" { #endif #ifndef BINARY_TREE_H #define BINARY_TREE_H #include "serialStack.h" #include "dynamicArray.h" #include "sequenceQueue.h" #include "forest.h" #include "string.h" #include "serialStack.h" enum Sequence { preorder = 1, inorder = 2, subsequent = 3 }; struct BinaryTree { struct BinaryNode* root; int depth; void (*draw)(struct BinaryTree* binaryTree); void (*insert)(char* data,struct BinaryTree* binaryTree); struct BinaryNode* (*find)(char* data, struct BinaryTree* binaryTree); int (*remove)(char* data, struct BinaryTree* binaryTree); void (*foreachUseRecursion)(struct BinaryTree* binaryTree, enum Sequence sequence); void (*foreachUseStack)(struct BinaryTree* binaryTree, enum Sequence sequence); void (*foreachTier)(struct BinaryTree* binaryTree); struct Forest* (*convertForest)(struct BinaryTree* binaryTree); }; struct BinaryNode { char* data; int depth; struct BinaryNode* parent; struct BinaryNode* left; struct BinaryNode* right; }; struct BinaryTree* initEmtpyBinaryTree(); enum ListOrArray { generalizedList = 0, arrayUseRecursion = 1, arrayUseQueue = 2}; struct BinaryTree* initBinaryTree(char* arrayOrList, enum ListOrArray listOrArray); struct BinaryTree* initTreeByForestArray(struct ArrayList* forestArray); enum ForeOrHind { fore = 0, hind = 1}; struct BinaryTree* initTreeBySequenceAndInorder(char* sequenceArray, char* inorderArray, enum ForeOrHind foreOrHind); struct ThreadedBinaryTree { struct ThreadedBinaryNode* root; int depth; struct ThreadedBinaryNode* (*getSuccessorNode)(struct ThreadedBinaryNode* binaryNode, enum Sequence sequence); void (*foreach)(struct ThreadedBinaryTree* binaryTree, enum Sequence sequence); }; struct ThreadedBinaryNode { char* data; int leftTag; struct ThreadedBinaryNode* left; int rightTag; struct ThreadedBinaryNode* right; }; struct ThreadedBinaryTree* convertThreadedBinaryTree(struct BinaryTree* binaryTree, enum Sequence sequence); struct HuffmanTree { int leafCount; int capacity; struct HuffmanNode* root; struct HuffmanCode* huffmanCode; struct BinaryTree* huffmanBinaryTree; void (*compile)(struct HuffmanTree* huffmanTree); char* (*encode)(char* soundCode, struct HuffmanTree* huffmanTree); void (*convert)(struct HuffmanTree* huffmanTree); char* (*decode)(char* ciphertext, struct HuffmanTree* huffmanTree); void (*foreach)(struct HuffmanTree* huffmanTree); }; struct HuffmanTree* initHuffmanTreeArray(int leafCount); #endif #ifdef __cplusplus } #endif |
实现头文件逻辑binaryTree.c:
#define _CRT_SECURE_NO_WARNINGS //规避C4996告警 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <Windows.h> #include "binaryTree.h" #define PRINT 1 #define EMPTY_NODE '*' /* * void linkChangeArray(struct BinaryNode*, struct TreeArray*, int index) * void markTreeIndex(struct TreeList*, int index) 标记树元素在二维画面中的坐标 * void printBinaryTree(struct TreeList*) */ void drawBinaryTree(struct BinaryTree* binaryTree); struct BinaryTree* createListBinaryTree(char* list); /*struct BinaryNode* createBinaryNodeByArray(struct ArrayList*, struct BinaryNode**)*/ struct BinaryTree* createArrayBinaryTree(char* array); struct BinaryTree* createArrayTreeUseQueue(char* array); /* * struct SequenceStack* examineBalancedTree(struct BinaryNode* node, int depth, struct SequenceStack* queue); * void revolveTree(struct BinaryTree* binaryTree, struct SequenceStack* queue); * void revolveTreeLL(struct BinaryTree* binaryTree, struct BinaryNode* node); * void revolveTreeRR(struct BinaryTree* binaryTree, struct BinaryNode* node); * void revolveTreeLR(struct BinaryTree* binaryTree, struct BinaryNode* node); * void revolveTreeRL(struct BinaryTree* binaryTree, struct BinaryNode* node); */ void insertBinaryTree(char* data, struct BinaryTree* binaryTree); /* * struct BinaryNode* recursionFindData(struct BinaryNode*, char*, struct BinaryNode**) */ struct BinaryNode* findTreeData(char* data, struct BinaryTree* binaryTree); /* * int removeTreeNode(struct BinaryNode* parent, struct BinaryNode* removeNode); * int getTreeDepth(struct BinaryNode* root, int depth); * void moveDepthMark(struct BinaryNode* root, int depth); */ int removeTreeData(char* data, struct BinaryTree* binaryTree); /* * recursionPreorderTraversal(binaryNode) * recursionInorderTraversal(binaryNode) * recursionSubsequentTraversal(binaryNode) */ void foreachRecursionBinaryTree(struct BinaryTree* binaryTree, enum Sequence sequence); /* * recursionStackBinaryTree(binaryTree, sequence); * recursionStackBinaryTree(binaryTree, sequence); * recursionStackBinaryTree(binaryTree, sequence); */ void foreachStackBinaryTree(struct BinaryTree* binaryTree, enum Sequence sequence); void foreachBinaryTreeTier(struct BinaryTree* binaryTree); struct Forest* convertForest(struct BinaryTree* binaryTree); void setBinaryTreeFunction(struct BinaryTree* binaryTree) { binaryTree->draw = drawBinaryTree; binaryTree->insert = insertBinaryTree; binaryTree->find = findTreeData; binaryTree->remove = removeTreeData; binaryTree->foreachUseRecursion = foreachRecursionBinaryTree; binaryTree->foreachUseStack = foreachStackBinaryTree; binaryTree->foreachTier = foreachBinaryTreeTier; binaryTree->convertForest = convertForest; } struct BinaryTree* initEmtpyBinaryTree() { struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); if (binaryTree == NULL) { #if PRINT printf("创建空二叉树失败,内存空间不足!\n"); #endif return NULL; } binaryTree->root = NULL; binaryTree->depth = 0; setBinaryTreeFunction(binaryTree); return binaryTree; } struct BinaryTree* initBinaryTree(char* arrayOrList, enum ListOrArray listOrArray) { struct BinaryTree* binaryTree = NULL; if (listOrArray == 2) { binaryTree = createArrayTreeUseQueue(arrayOrList); } else if (listOrArray == 0) { binaryTree = createListBinaryTree(arrayOrList); } else { binaryTree = createArrayBinaryTree(arrayOrList); } setBinaryTreeFunction(binaryTree); return binaryTree; } struct TreeArray { int seat; // 绘画时在二维矩阵中的位置 struct BinaryNode* node; }; struct TreeList { int size; struct TreeArray* treeArray; }; void linkChangeArray(struct BinaryNode* binaryNode, struct TreeArray* treeArray, int index) { if (binaryNode == NULL) { return; } treeArray[index].node = binaryNode; linkChangeArray(binaryNode->left, treeArray, (index << 1) + 1); linkChangeArray(binaryNode->right, treeArray, (index << 1) + 2); } int leftGetParent(int index) { return (index - 1) >> 1; } int rightGetParent(int index) { return (index - 2) >> 1; } int getLeftTree(int index) { return (index << 1) + 1; } int getRightTree(int index) { return (index << 1) + 2; } void markLeftIndex(struct TreeList* treeList, int index, int counter); void markRightIndex(struct TreeList* treeList, int index, int counter); void markParentIndex(struct TreeList* treeList, int index, int counter) { if (index < treeList->size && index >= 0) { if (treeList->treeArray[index].seat == -1) { treeList->treeArray[index].seat = counter; markRightIndex(treeList, getRightTree(index), ++counter); } else { markParentIndex(treeList, leftGetParent(index), counter); } } } void markLeftIndex(struct TreeList* treeList, int index, int counter) { if (index < treeList->size && index >= 0 && treeList->treeArray[index].seat == -1) { if (getLeftTree(index) <= treeList->size) { markLeftIndex(treeList, getLeftTree(index), counter); return; } treeList->treeArray[index].seat = counter; markParentIndex(treeList, leftGetParent(index), ++counter); } } void markRightIndex(struct TreeList* treeList, int index, int counter) { if (index < treeList->size && index >= 0 && treeList->treeArray[index].seat == -1) { if (getLeftTree(index) <= treeList->size) { markLeftIndex(treeList, getLeftTree(index), counter); return; } treeList->treeArray[index].seat = counter; markParentIndex(treeList, rightGetParent(index), ++counter); } } void markTreeIndex(struct TreeList* treeList, int index) { int counter = 1; treeList->treeArray[index].seat = counter; markParentIndex(treeList, leftGetParent(index), ++counter); } void printBinaryTree(struct TreeList* treeList) { int seat, size = treeList->size, front = 0, jump = 1, add = 2; for (int i = 0; i < size; i++) { seat = treeList->treeArray[i].seat - front; for (int j = 0; j < seat; j++) { printf(" "); front++; } if (treeList->treeArray[i].node == NULL || treeList->treeArray[i].node->data[0] == '\0') { printf("%c", EMPTY_NODE); } else { printf("%s", treeList->treeArray[i].node->data); //printf("%s|", treeList->treeArray[i].node->data); //printf("%d|", treeList->treeArray[i].node->depth); //printf("%s", treeList->treeArray[i].node->parent == NULL ? "#" : treeList->treeArray[i].node->parent->data); } CONSOLE_SCREEN_BUFFER_INFO ipBuffer; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ipBuffer); COORD coord = { 0 }; coord.X = ipBuffer.dwCursorPosition.X; coord.Y = ipBuffer.dwCursorPosition.Y + 1; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); printf("\\"); coord.X = ipBuffer.dwCursorPosition.X - 2; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); printf("/"); coord.X = ipBuffer.dwCursorPosition.X; coord.Y = ipBuffer.dwCursorPosition.Y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); front++; if ((i + 1) % jump == 0) { CONSOLE_SCREEN_BUFFER_INFO ipBuffer; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ipBuffer); COORD coord = { 0 }; coord.X = ipBuffer.dwCursorPosition.X; coord.Y = ipBuffer.dwCursorPosition.Y + 1; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); printf("\n"); jump = jump + add; add = add * 2; front = 0; } } } void drawBinaryTree(struct BinaryTree* binaryTree) { int depth = binaryTree->depth; if (depth <= 0) { #if PRINT printf("空二叉树无法绘制!\n"); #endif return; } double size = floor(pow(2, depth)) - 1; struct TreeArray* treeArray = malloc(sizeof(struct TreeArray) * size); struct TreeList* treeList = malloc(sizeof(struct TreeList)); if (treeArray == NULL || treeList == NULL) { #if PRINT printf("绘制二叉树时。内存空间不足!\n"); #endif return; } for (int i = 0; i < size; i++) { treeArray[i].seat = -1; treeArray[i].node = NULL; } treeList->size = size; treeList->treeArray = treeArray; linkChangeArray(binaryTree->root, treeArray, 0); markTreeIndex(treeList, (int)size >> 1); printBinaryTree(treeList); free(treeArray); treeArray = NULL; free(treeList); treeList = NULL; } void stockpileBinaryNodeData(struct BinaryNode* currentNode, struct ArrayList* arrayList, char pointer) { if (currentNode != NULL && currentNode->data == NULL && arrayList != NULL) { currentNode->data = arrayList->toString(arrayList); arrayList->ruin(arrayList); arrayList = NULL; currentNode = NULL; } } int setBinaryNodeData(struct BinaryNode* currentNode, struct ArrayList* arrayList, char pointer) { if (currentNode != NULL && currentNode->data == NULL && arrayList != NULL) { char* data = malloc(sizeof(char)); if (data == NULL || arrayList == NULL) { #if PRINT printf("创建二叉树结点赋值失败,内存空间不足!\n"); #endif return 0; } arrayList->insert(arrayList->size(arrayList), data, arrayList); *data = pointer; return 1; } return 0; } struct BinaryTree* createListBinaryTree(char* list) { int index = 0, left = 1, probe = 0, depth = probe; char pointer = list[index]; struct SequenceStack* stack = initSequenceStack(); struct BinaryNode* currentNode = NULL; struct BinaryNode* stackTopNode = NULL; struct BinaryNode* treeRoot = NULL; struct ArrayList* arrayList = NULL; while (pointer != '\0') { if (pointer == ' ') { index++; pointer = list[index]; continue; } switch (pointer) { case '(': left = 1; probe++; stack->push(currentNode, stack); stockpileBinaryNodeData(currentNode, arrayList, pointer); arrayList = NULL; currentNode = NULL; break; case ',': stockpileBinaryNodeData(currentNode, arrayList, pointer); left = 0; break; case ')': stockpileBinaryNodeData(currentNode, arrayList, pointer); stack->pop(stack); if (depth < probe)depth = probe; probe--; break; default: if (setBinaryNodeData(currentNode, arrayList, pointer)) break; currentNode = malloc(sizeof(struct BinaryNode)); if (currentNode == NULL) { #if PRINT printf("创建二叉树结点失败,内存空间不足!\n"); #endif return NULL; } currentNode->data = NULL; currentNode->left = NULL; currentNode->right = NULL; setBinaryNodeData(currentNode, arrayList = initArrayList(5), pointer); if (treeRoot == NULL) { treeRoot = currentNode; } else { stackTopNode = (struct BinaryNode*)stack->top(stack); switch (left) { case 1: stackTopNode->left = currentNode; break; case 0: stackTopNode->right = currentNode; break; } } break; } index++; pointer = list[index]; } stack->destroy(stack); struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); if (binaryTree == NULL) { #if PRINT printf("创建二叉树失败,内存空间不足!\n"); #endif return NULL; } binaryTree->root = treeRoot; binaryTree->depth = depth; return binaryTree; } struct ArrayList* createArrayByBinaryTree(char* array) { int index = 0; char pointer = array[index]; struct ArrayList* arrayList = NULL; struct ArrayList* dataList = initArrayList(5); while (pointer != '\0') { arrayList = initArrayList(5); while (pointer != ' ' && pointer != '\0') { char* data = malloc(sizeof(char)); if (data == NULL || arrayList == NULL) { #if PRINT printf("创建二叉树结点赋值失败,内存空间不足!\n"); #endif return NULL; } arrayList->insert(arrayList->size(arrayList), data, arrayList); *data = pointer; index++; pointer = array[index]; } char* data = arrayList->toString(arrayList); arrayList->ruin(arrayList); arrayList = NULL; dataList->insert(dataList->size(dataList), data, dataList); index++; pointer = array[index]; } return dataList; } struct BinaryNode* createBinaryNodeByArray(struct ArrayList* dataList, int size, int index, struct BinaryNode** binaryNode) { if (index < size && index >= 0 && *binaryNode == NULL) { *binaryNode = malloc(sizeof(struct BinaryNode)); if (*binaryNode == NULL) { #if PRINT printf("创建二叉树结点失败,内存空间不足!\n"); #endif return NULL; } (*binaryNode)->data = dataList->get(index, dataList); (*binaryNode)->left = NULL; (*binaryNode)->right = NULL; createBinaryNodeByArray(dataList, size, getLeftTree(index), &(*binaryNode)->left); createBinaryNodeByArray(dataList, size, getRightTree(index), &(*binaryNode)->right); } } struct BinaryTree* createArrayBinaryTree(char* array) { struct ArrayList* dataList = createArrayByBinaryTree(array); struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); if (binaryTree == NULL) { #if PRINT printf("创建二叉树失败,内存空间不足!\n"); #endif return NULL; } binaryTree->root = NULL; createBinaryNodeByArray(dataList, dataList->size(dataList), 0, &binaryTree->root); binaryTree->depth = log2(dataList->size(dataList) + 1); dataList->destroy(dataList); return binaryTree; } struct BinaryTree* createArrayTreeUseQueue(char* array) { struct ArrayList* dataList = createArrayByBinaryTree(array); struct BinaryNode* rootNode = malloc(sizeof(struct BinaryNode)); if (rootNode == NULL) { #if PRINT printf("创建二叉树根结点失败,内存空间不足!\n"); #endif return NULL; } rootNode->data = NULL; rootNode->left = NULL; rootNode->right = NULL; int size = dataList->size(dataList); if (size > 0) { struct SequenceQueue* queue = initSequenceQueue(); rootNode->data = dataList->get(0, dataList); queue->push(rootNode, queue); char* emptyNode = malloc(sizeof(char) * 2); if (emptyNode == NULL) { #if PRINT printf("创建二叉树空结点失败,内存空间不足!\n"); #endif return NULL; } emptyNode[0] = EMPTY_NODE; emptyNode[1] = '\0'; for (int i = 1; i < size; i++) { char* data = dataList->get(i, dataList); if (stringCompare(data, emptyNode) != 0) { struct BinaryNode* binaryNode = malloc(sizeof(struct BinaryNode)); if (binaryNode == NULL) { #if PRINT printf("创建二叉树结点失败,内存空间不足!\n"); #endif return NULL; } binaryNode->data = data; binaryNode->left = NULL; binaryNode->right = NULL; queue->push(binaryNode, queue); struct BinaryNode* front = queue->front(queue); if (i % 2 == 0) { front->right = binaryNode; } else { front->left = binaryNode; } } else { queue->push(emptyNode, queue); } if (i % 2 == 0) { queue->pop(queue); } } free(emptyNode); emptyNode = NULL; queue->destroy(queue); } struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); if (binaryTree == NULL) { #if PRINT printf("创建二叉树失败,内存空间不足!\n"); #endif return NULL; } binaryTree->root = rootNode; binaryTree->depth = log2(size + 1); return binaryTree; } int getTreeDepth(struct BinaryNode* root, int depth); // removeTreeData::getTreeDepth struct SequenceStack* examineBalancedTree(struct BinaryNode* node, int depth, struct SequenceStack* queue); void revolveTree(struct BinaryTree* binaryTree, struct SequenceStack* queue); void revolveTreeLL(struct BinaryTree* binaryTree, struct BinaryNode* node); void revolveTreeRR(struct BinaryTree* binaryTree, struct BinaryNode* node); void revolveTreeLR(struct BinaryTree* binaryTree, struct BinaryNode* node); void revolveTreeRL(struct BinaryTree* binaryTree, struct BinaryNode* node); void insertBinaryTree(char* data, struct BinaryTree* binaryTree) { if (binaryTree == NULL) { #if PRINT printf("二叉树不存在!\n"); #endif return; } if (data == NULL) { #if PRINT printf("插入二叉树数值为空!\n"); #endif return; } struct BinaryNode* binaryNode = malloc(sizeof(struct BinaryNode)); if (binaryNode == NULL) { #if PRINT printf("创建二叉树结点失败,内存空间不足!\n"); #endif return; } binaryNode->data = data; binaryNode->left = NULL; binaryNode->right = NULL; if (binaryTree->root == NULL) { binaryNode->depth = 1; binaryNode->parent = NULL; binaryTree->root = binaryNode; return; } struct BinaryNode* pointer = binaryTree->root; struct BinaryNode* front = NULL; int depth = 1; while (pointer != NULL) { front = pointer; depth++; if (stringCompare(data, pointer->data) > 0) { pointer = pointer->right; } else if (stringCompare(data, pointer->data) == 0) { #if PRINT printf("插入二叉树数据%s已存在!\n", data); #endif return; } else { pointer = pointer->left; } } binaryTree->depth = binaryTree->depth > depth ? binaryTree->depth : depth; binaryNode->depth = depth; binaryNode->parent = front; if (stringCompare(data, front->data) > 0) { front->right = binaryNode; } else { front->left = binaryNode; } struct SequenceStack* stack = initSequenceStack(); stack = examineBalancedTree(binaryTree->root, 1, stack); while (stack->size(stack) > 0) { revolveTree(binaryTree, stack); stack = examineBalancedTree(binaryTree->root, 1, stack); } stack->destroy(stack); binaryTree->depth = getTreeDepth(binaryTree->root, 1); } struct StackBinaryNode { int isLeftDepth; struct BinaryNode* node; }; int getTreeDepth(struct BinaryNode* root, int depth); // removeTreeData::getTreeDepth struct SequenceStack* examineBalancedTree(struct BinaryNode* node, int depth, struct SequenceStack* stack) { if (node == NULL) { return stack; } int left = getTreeDepth(node->left, depth + 1); int right = getTreeDepth(node->right, depth + 1); if (abs(left - right) > 1) { struct StackBinaryNode* stackNode = malloc(sizeof(struct StackBinaryNode)); stackNode->node = node; if (left > right) { stackNode->isLeftDepth = 1; } else { stackNode->isLeftDepth = 0; } stack->push(stackNode, stack); } examineBalancedTree(node->left, depth, stack); examineBalancedTree(node->right, depth, stack); return stack; } void revolveTree(struct BinaryTree* binaryTree, struct SequenceStack* stack) { if (stack != NULL && stack->size(stack) > 0) { struct StackBinaryNode* stackNode = stack->top(stack); stack->pop(stack); int size = stack->size(stack); struct StackBinaryNode** stackArray = stack->clear(stack); for (int i = 0; i < size; i++) { free(stackArray[i]); stackArray[i] = NULL; } struct BinaryNode* node = stackNode->node; int isLeftDepth = stackNode->isLeftDepth; free(stackNode); stackNode = NULL; if (isLeftDepth) { if (node->left->left != NULL) { node = node->left->left; revolveTreeLL(binaryTree, node); return; } else if (node->left->right != NULL) { node = node->left->right; revolveTreeLR(binaryTree, node); return; } } else { if (node->right->left != NULL) { node = node->right->left; revolveTreeRL(binaryTree, node); return; } else if (node->right->right != NULL) { node = node->right->right; revolveTreeRR(binaryTree, node); return; } } } } void moveDepthMark(struct BinaryNode* root, int depth); // removeTreeData::moveDepthMark void revolveTreeLL(struct BinaryTree* binaryTree, struct BinaryNode* node) { struct BinaryNode* parent = node->parent->parent->parent; struct BinaryNode* right = node->parent->parent; struct BinaryNode* root = node->parent; if (root->right != NULL) { root->right->parent = right; right->left = root->right; } else { right->left = NULL; } root->right = right; right->parent = root; moveDepthMark(root, root->depth - 1); if (parent == NULL) { binaryTree->root = root; root->parent = NULL; return; } root->parent = parent; if (parent->left == right) { parent->left = root; } else { parent->right = root; } } void revolveTreeRR(struct BinaryTree* binaryTree, struct BinaryNode* node) { struct BinaryNode* parent = node->parent->parent->parent; struct BinaryNode* left = node->parent->parent; struct BinaryNode* root = node->parent; if (root->left != NULL) { root->left->parent = left; left->right = root->left; } else { left->right = NULL; } root->left = left; left->parent = root; moveDepthMark(root, root->depth - 1); if (parent == NULL) { binaryTree->root = root; root->parent = NULL; return; } root->parent = parent; if (parent->left == left) { parent->left = root; } else { parent->right = root; } } void revolveTreeLR(struct BinaryTree* binaryTree, struct BinaryNode* node) { struct BinaryNode* parent = node->parent->parent->parent; struct BinaryNode* right = node->parent->parent; struct BinaryNode* left = node->parent; if (node->left != NULL) { left->right = node->left; right->left = NULL; } else { right->left = node->right; left->right = NULL; } node->left = left; left->parent = node; node->right = right; moveDepthMark(node, node->depth - 2); if (parent == NULL) { binaryTree->root = node; node->parent = NULL; return; } node->parent = parent; if (parent->left == right) { parent->left = node; } else { parent->right = node; } } void revolveTreeRL(struct BinaryTree* binaryTree, struct BinaryNode* node) { struct BinaryNode* parent = node->parent->parent->parent; struct BinaryNode* left = node->parent->parent; struct BinaryNode* right = node->parent; if (node->left != NULL) { left->right = node->left; right->left = NULL; } else { right->left = node->right; left->right = NULL; } node->left = left; left->parent = node; node->right = right; right->parent = node; moveDepthMark(node, node->depth - 2); if (parent == NULL) { binaryTree->root = node; node->parent = NULL; return; } node->parent = parent; if (parent->left == left) { parent->left = node; } else { parent->right = node; } } struct BinaryNode* findTreeData(char* data, struct BinaryTree* binaryTree) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("二叉树不存在!\n"); #endif return; } struct BinaryNode* recursionFindData(struct BinaryNode* root, char* data, struct BinaryNode** parent); return recursionFindData(binaryTree->root, data, NULL); } struct BinaryNode* recursionFindData(struct BinaryNode* root, char* data, struct BinaryNode** parent) { if (root == NULL || stringCompare(root->data, data) == 0) { return root; } if (parent != NULL) *parent = root; if (stringCompare(data, root->data) > 0) { recursionFindData(root->right, data, parent); } else { recursionFindData(root->left, data, parent); } } int removeTreeNode(struct BinaryNode* parent, struct BinaryNode* removeNode); int getTreeDepth(struct BinaryNode* root, int depth); void moveDepthMark(struct BinaryNode* root, int depth); int removeTreeData(char* data, struct BinaryTree* binaryTree) { struct BinaryNode* parent = NULL; struct BinaryNode* removeNode = recursionFindData(binaryTree->root, data, &parent); if (removeNode == NULL) { printf("删除元素%s不存在!", data); return 0; } if (parent == NULL) { if (removeNode->left != NULL && removeNode->right == NULL) { binaryTree->root = removeNode->left; removeNode->left->parent = NULL; moveDepthMark(removeNode->left, 1); } else if (removeNode->left == NULL && removeNode->right != NULL) { binaryTree->root = removeNode->right; removeNode->right->parent = NULL; moveDepthMark(removeNode->right, 1); } else { struct BinaryNode* node = removeNode->right; moveDepthMark(removeNode->right, removeNode->depth); while (node->left != NULL) { node = node->left; } node->left = removeNode->left; removeNode->left->parent = node; binaryTree->root = removeNode->right; removeNode->right->parent = NULL; moveDepthMark(node, node->depth); } free(removeNode); removeNode = NULL; } else { removeTreeNode(parent, removeNode); } struct SequenceStack* stack = initSequenceStack(); stack = examineBalancedTree(binaryTree->root, 1, stack); while (stack->size(stack) > 0) { revolveTree(binaryTree, stack); stack = examineBalancedTree(binaryTree->root, 1, stack); } stack->destroy(stack); binaryTree->depth = getTreeDepth(binaryTree->root, 1); return 1; } int removeTreeNode(struct BinaryNode* parent, struct BinaryNode* removeNode) { int flag = -1; if (parent->left == removeNode) { flag = 1; } else { flag = 0; } if (removeNode->left == NULL && removeNode->right == NULL) { if (flag) { parent->left = NULL; } else { parent->right = NULL; } } else if (removeNode->left == NULL && removeNode->right != NULL) { if (flag) { parent->left = removeNode->right; } else { parent->right = removeNode->right; } removeNode->right->parent = parent; moveDepthMark(removeNode->right, removeNode->depth); } else if (removeNode->left != NULL && removeNode->right == NULL) { if (flag) { parent->left = removeNode->left; } else { parent->right = removeNode->left; } removeNode->left->parent = parent; moveDepthMark(removeNode->left, removeNode->depth); } else { struct BinaryNode* node = removeNode->left; struct BinaryNode* front = removeNode; while (node->right != NULL) { front = node; node = node->right; } removeNode->data = node->data; return removeTreeNode(front, node); } free(removeNode); removeNode = NULL; return 1; } void moveDepthMark(struct BinaryNode* root, int depth) { if (root == NULL) { return; } root->depth = depth; moveDepthMark(root->left, depth + 1); moveDepthMark(root->right, depth + 1); } int getTreeDepth(struct BinaryNode* root, int depth) { if (root == NULL) { return --depth; } int left = getTreeDepth(root->left, depth + 1); int right = getTreeDepth(root->right, depth + 1); return left > right ? left : right; } void recursionPreorderTraversal(struct BinaryNode* binaryNode) { if (binaryNode == NULL) { return; } printf("%s ", binaryNode->data); recursionPreorderTraversal(binaryNode->left); recursionPreorderTraversal(binaryNode->right); } void recursionInorderTraversal(struct BinaryNode* binaryNode) { if (binaryNode == NULL) { return; } recursionInorderTraversal(binaryNode->left); printf("%s ", binaryNode->data); recursionInorderTraversal(binaryNode->right); } void recursionSubsequentTraversal(struct BinaryNode* binaryNode) { if (binaryNode == NULL) { return; } recursionSubsequentTraversal(binaryNode->left); recursionSubsequentTraversal(binaryNode->right); printf("%s ", binaryNode->data); } void foreachRecursionBinaryTree(struct BinaryTree* binaryTree, enum Sequence sequence) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("二叉树不存在!\n"); #endif return; } struct BinaryNode* binaryNode = binaryTree->root; if (sequence == 1) { printf("前序:"); recursionPreorderTraversal(binaryNode); printf("\n"); } else if (sequence == 2) { printf("中序:"); recursionInorderTraversal(binaryNode); printf("\n"); } else if (sequence == 3) { printf("后序:"); recursionSubsequentTraversal(binaryNode); printf("\n"); } else { printf("未知遍历顺序!\n"); } } struct BinaryNodeStack { char* data; struct BinaryNodeStack* left; struct BinaryNodeStack* right; int flag; }; struct BinaryNodeStack* convertBinaryNode(struct BinaryNode* node) { if (node == NULL) { return NULL; } struct BinaryNodeStack* left = convertBinaryNode(node->left); struct BinaryNodeStack* right = convertBinaryNode(node->right); struct BinaryNodeStack* treeNode = malloc(sizeof(struct BinaryNodeStack)); if (treeNode == NULL) { return NULL; } treeNode->data = node->data; treeNode->left = left; treeNode->right = right; treeNode->flag = 0; return treeNode; } void preorderTraversal(struct BinaryNodeStack* binaryNode, struct SequenceStack* stack) { if (binaryNode->right != NULL) { stack->push(binaryNode->right, stack); } if (binaryNode->left != NULL) { stack->push(binaryNode->left, stack); } stack->push(binaryNode, stack); } void inorderTraversal(struct BinaryNodeStack* binaryNode, struct SequenceStack* stack) { if (binaryNode->right != NULL) { stack->push(binaryNode->right, stack); } stack->push(binaryNode, stack); if (binaryNode->left != NULL) { stack->push(binaryNode->left, stack); } } void subsequentTraversal(struct BinaryNodeStack* binaryNode, struct SequenceStack* stack) { stack->push(binaryNode, stack); if (binaryNode->right != NULL) { stack->push(binaryNode->right, stack); } if (binaryNode->left != NULL) { stack->push(binaryNode->left, stack); } } void recursionStackBinaryTree(struct BinaryTree* binaryTree, int sequence) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("二叉树不存在!\n"); #endif return; } struct BinaryNodeStack* binaryNode = convertBinaryNode(binaryTree->root); struct SequenceStack* stack = initSequenceStack(); stack->push(binaryNode, stack); while (stack->size(stack) > 0) { struct BinaryNodeStack* currentNode = stack->top(stack); stack->pop(stack); if (currentNode->flag == 0) { currentNode->flag = 1; if (sequence == 1) { preorderTraversal(currentNode, stack); } else if (sequence == 2) { inorderTraversal(currentNode, stack); } else if (sequence == 3) { subsequentTraversal(currentNode, stack); } continue; } printf("%s ", currentNode->data); } stack->destroy(stack); } void foreachStackBinaryTree(struct BinaryTree* binaryTree, enum Sequence sequence) { if (sequence == 1) { printf("前序:"); recursionStackBinaryTree(binaryTree, sequence); printf("\n"); } else if (sequence == 2) { printf("中序:"); recursionStackBinaryTree(binaryTree, sequence); printf("\n"); } else if (sequence == 3) { printf("后序:"); recursionStackBinaryTree(binaryTree, sequence); printf("\n"); } else { printf("未知遍历顺序!\n"); } } void foreachBinaryTreeTier(struct BinaryTree* binaryTree) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("二叉树不存在!\n"); #endif return; } struct BinaryNode* binaryNode = binaryTree->root; printf("层序遍历:"); struct SequenceQueue* queue = initSequenceQueue(); queue->push(binaryNode, queue); while (queue->isNotEmpty(queue)) { struct BinaryNode* currentNode = queue->front(queue); printf("%s ", currentNode->data); if (currentNode->left != NULL) queue->push(currentNode->left, queue); if (currentNode->right != NULL) queue->push(currentNode->right, queue); queue->pop(queue); } queue->destroy(queue); printf("\n"); } struct Forest* convertForest(struct BinaryTree* binaryTree) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("二叉树不存在!\n"); #endif return NULL; } return initForestByBinaryTree(binaryTree); } //=======↑↑↑=init Tree by array or list=↑↑↑====== //========↓↓↓=init Tree by ForestArray=↓↓↓======= int isNextsibling(struct ArrayList* forestArray, struct ForestNode* forest, int index) { struct ForestNode* parent = forestArray->get(forest->parent, forestArray); struct ChildNode* child = parent->firstChild; while (child != NULL) { if (child->index == index) { if (child->next == NULL) { return 0; } else { return 1; } } child = child->next; } } struct BinaryNode* createNodeByForestArray(struct ArrayList* forestArray, int* index, int* depth, int probe) { int currentIndex = *index; struct ForestNode* forest = forestArray->get((*index)++, forestArray); struct BinaryNode* binaryNode = malloc(sizeof(struct BinaryNode)); if (binaryNode == NULL) { #if PRINT printf("创建二叉树根结点失败,内存空间不足!\n"); #endif return NULL; } binaryNode->data = forest->data; binaryNode->left = NULL; if (forest->firstChild != NULL) { binaryNode->left = createNodeByForestArray(forestArray, index, depth, ++probe); probe--; } binaryNode->right = NULL; if (*index < forestArray->size(forestArray) && forest->parent >= 0 && isNextsibling(forestArray, forest, currentIndex)) { binaryNode->right = createNodeByForestArray(forestArray, index, depth, ++probe); probe--; } if (*depth < probe) *depth = probe; return binaryNode; } struct BinaryTree* initTreeByForestArray(struct ArrayList* forestArray) { if (forestArray == NULL) { #if PRINT printf("创建二叉树失败,数据源森林数组不存在!\n"); #endif return NULL; } struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); int* index = malloc(sizeof(int)), * depth = malloc(sizeof(int)); if (index == NULL || depth == NULL || binaryTree == NULL) { #if PRINT printf("创建二叉树失败,内存空间不足!\n"); #endif return NULL; } binaryTree->root = NULL; *index = 0; *depth = 0; int probe = 0; do { probe++; struct BinaryNode* binaryNode = createNodeByForestArray(forestArray, index, depth, probe); if (binaryTree->root == NULL) { binaryTree->root = binaryNode; } else { struct BinaryNode* rightNode = binaryTree->root; while (rightNode->right != NULL) { rightNode = rightNode->right; } rightNode->right = binaryNode; } } while (*index < forestArray->size(forestArray)); if (forestArray->size(forestArray) <= 0) { *depth = 0; } binaryTree->depth = *depth; setBinaryTreeFunction(binaryTree); free(index); index = NULL; free(depth); depth = NULL; return binaryTree; } //========↑↑↑=init Tree by ForestArray=↑↑↑======= //=========↓↓↓=init Tree by traversal=↓↓↓======== static struct SortArray { char* data; int index; }; // 冒泡排序算法 想剥离出来 暂时没有好的剥离方案 void sortPreorderOrSubsequentArray(struct SortArray* array, int size) { int flag = 0; struct SortArray* temp = malloc(sizeof(struct SortArray)); for (int i = 0; i < size; i++) { for (int j = 0; j < size - 1 - i; j++) { if (array[j].index > array[j + 1].index) { flag = 0; temp->data = array[j].data; temp->index = array[j].index; array[j].data = array[j + 1].data; array[j].index = array[j + 1].index; array[j + 1].data = temp->data; array[j + 1].index = temp->index; } else { flag++; } } if (flag == (size - 1 - i)) { break; } flag = 0; } free(temp); temp = NULL; } // Use Preorder And Inorder create BinaryTree. struct ArrayList* convertPreorderOrSubsequent(struct ArrayList* preorderOrSubsequent, struct ArrayList* referTo) { int preorderOrSubsequentSize = preorderOrSubsequent->size(preorderOrSubsequent); int referToSize = referTo->size(referTo); struct SortArray* array = malloc(sizeof(struct SortArray) * referToSize); if (array == NULL) { #if PRINT printf("创建二叉树获取子树前序遍历顺序失败,内存空间不足!\n"); #endif return NULL; } for (int i = 0; i < referToSize; i++) { for (int j = 0; j < preorderOrSubsequentSize; j++) { if (stringCompare(referTo->get(i, referTo), preorderOrSubsequent->get(j, preorderOrSubsequent)) == 0) { array[i].data = preorderOrSubsequent->get(j, preorderOrSubsequent); array[i].index = j; continue; } } } sortPreorderOrSubsequentArray(array, referToSize); struct ArrayList* resultList = initArrayList(5); for (int i = 0; i < referToSize; i++) { resultList->insert(i, array[i].data, resultList); } free(array); array = NULL; return resultList; } struct BinaryNode* createNodeBySequenceAndInorder(struct ArrayList* sequence, struct ArrayList* inorder, enum ForeOrHind foreOrHind, int* depth, int probe) { if (sequence->size(sequence) <= 0 || inorder->size(inorder) <= 0) { return NULL; } char* parentData = NULL; if (foreOrHind == 0) { parentData = sequence->get(0, sequence); } else { parentData = sequence->get(sequence->size(sequence) - 1, sequence); } struct BinaryNode* binaryNode = malloc(sizeof(struct BinaryNode)); if (binaryNode == NULL) { #if PRINT printf("创建二叉树结点失败,内存空间不足!\n"); #endif return NULL; } binaryNode->data = parentData; binaryNode->left = NULL; binaryNode->right = NULL; if (sequence->size(sequence) == 1 || inorder->size(inorder) == 1) { if (*depth < probe) *depth = probe; return binaryNode; } // find parent node index by inorder. int size = inorder->size(inorder), index = 0; for (int i = 0; i < size; i++) { if (stringCompare(inorder->get(i, inorder), parentData) == 0) { index = i; break; } } struct ArrayList* leftInorder = initArrayList(5); inorder->copy(inorder, leftInorder, 0, index); binaryNode->left = createNodeBySequenceAndInorder(convertPreorderOrSubsequent(sequence, leftInorder), leftInorder, foreOrHind, depth, ++probe); leftInorder->destroy(leftInorder); probe--; struct ArrayList* rightInorder = initArrayList(5); inorder->copy(inorder, rightInorder, index + 1, -1); binaryNode->right = createNodeBySequenceAndInorder(convertPreorderOrSubsequent(sequence, rightInorder), rightInorder, foreOrHind, depth, ++probe); rightInorder->destroy(rightInorder); return binaryNode; } struct BinaryTree* initTreeBySequenceAndInorder(char* sequenceArray, char* inorderArray, enum ForeOrHind foreOrHind) { struct ArrayList* sequence = createArrayByBinaryTree(sequenceArray); struct ArrayList* inorder = createArrayByBinaryTree(inorderArray); int* depth = malloc(sizeof(int)); if (depth == NULL) { #if PRINT printf("创建二叉树计算深度失败,内存空间不足!\n"); #endif return NULL; } *depth = 0; struct BinaryNode* binaryNode = createNodeBySequenceAndInorder(sequence, inorder, foreOrHind, depth, 1); sequence->destroy(sequence); inorder->destroy(inorder); struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); if (binaryTree == NULL) { #if PRINT printf("创建二叉树失败,内存空间不足!\n"); #endif return NULL; } binaryTree->root = binaryNode; binaryTree->depth = *depth; if (*depth == 0) { #if PRINT printf("空二叉树!\n"); #endif } free(depth); depth = NULL; setBinaryTreeFunction(binaryTree); return binaryTree; } //=========↑↑↑=init Tree by traversal=↑↑↑======== //==========↓↓↓=Threaded Binary Tree=↓↓↓========= struct ThreadedBinaryNode* convertThreadedBinaryNode(struct BinaryNode* node); void preorderThreadedBinaryNode(struct ThreadedBinaryNode* current); void inorderThreadedBinaryNode(struct ThreadedBinaryNode* current); void subsequentThreadedBinaryNode(struct ThreadedBinaryNode* current); struct ThreadedBinaryNode* getSuccessorNode(struct ThreadedBinaryNode* binaryNode, enum Sequence sequence); void foreachThreadedBinaryNode(struct ThreadedBinaryTree* binaryTree, enum Sequence sequence); void freeThreadedBinaryNode(struct ThreadedBinaryNode* binaryNode) { if (binaryNode == NULL) return; freeThreadedBinaryNode(binaryNode->left); freeThreadedBinaryNode(binaryNode->right); free(binaryNode); binaryNode = NULL; } struct ThreadedBinaryTree* convertThreadedBinaryTree(struct BinaryTree* binaryTree, enum Sequence sequence) { struct ThreadedBinaryNode* threadedBinaryNode = convertThreadedBinaryNode(binaryTree->root); struct ThreadedBinaryTree* threadedBinaryTree = malloc(sizeof(struct ThreadedBinaryTree)); if (threadedBinaryTree == NULL) { #if PRINT printf("转换线索二叉树失败,没有足够的内存空间!\n"); #endif return NULL; } threadedBinaryTree->depth = binaryTree->depth; threadedBinaryTree->root = threadedBinaryNode; if (sequence == 1) { printf("二叉树前序线索化!\n"); preorderThreadedBinaryNode(threadedBinaryNode); } else if (sequence == 2) { printf("二叉树中序线索化!\n"); inorderThreadedBinaryNode(threadedBinaryNode); } else if (sequence == 3) { printf("二叉树后序线索化!\n"); subsequentThreadedBinaryNode(threadedBinaryNode); } else { printf("未知二叉树序列线索化!\n"); threadedBinaryTree->depth = 0; threadedBinaryTree->root = NULL; freeThreadedBinaryNode(threadedBinaryNode); } threadedBinaryTree->getSuccessorNode = getSuccessorNode; threadedBinaryTree->foreach = foreachThreadedBinaryNode; return threadedBinaryTree; } struct ThreadedBinaryNode* convertThreadedBinaryNode(struct BinaryNode* node) { if (node == NULL) { return NULL; } struct ThreadedBinaryNode* left = convertThreadedBinaryNode(node->left); struct ThreadedBinaryNode* right = convertThreadedBinaryNode(node->right); struct ThreadedBinaryNode* treeNode = malloc(sizeof(struct ThreadedBinaryNode)); if (treeNode == NULL) { return NULL; } treeNode->data = node->data; treeNode->leftTag = 0; treeNode->left = left; treeNode->rightTag = 0; treeNode->right = right; return treeNode; } void preorderThreadedBinaryNode(struct ThreadedBinaryNode* current) { static struct ThreadedBinaryNode* prior = NULL; if (current != NULL) { if (current->left == NULL) { current->leftTag = 1; } if (current->right == NULL) { current->rightTag = 1; } if (prior) { if (prior->rightTag == 1) prior->right = current; if (current->leftTag == 1) current->left = prior; } prior = current; if (current->leftTag != 1) { preorderThreadedBinaryNode(current->left); } if (current->rightTag != 1) { preorderThreadedBinaryNode(current->right); } } } void inorderThreadedBinaryNode(struct ThreadedBinaryNode* current) { static struct ThreadedBinaryNode* prior = NULL; if (current != NULL) { inorderThreadedBinaryNode(current->left); if (current->left == NULL) { current->leftTag = 1; } if (current->right == NULL) { current->rightTag = 1; } if (prior) { if (prior->rightTag == 1) prior->right = current; if (current->leftTag == 1) current->left = prior; } prior = current; inorderThreadedBinaryNode(current->right); } } void subsequentThreadedBinaryNode(struct ThreadedBinaryNode* current) { static struct ThreadedBinaryNode* prior = NULL; if (current != NULL) { subsequentThreadedBinaryNode(current->left); subsequentThreadedBinaryNode(current->right); if (current->left == NULL) { current->leftTag = 1; } if (current->right == NULL) { current->rightTag = 1; } if (prior) { if (prior->rightTag == 1) prior->right = current; if (current->leftTag == 1) current->left = prior; } prior = current; } } struct ThreadedBinaryNode* getPreorderSuccessorNode(struct ThreadedBinaryNode* binaryNode) { if (binaryNode == NULL) { #if PRINT printf("空线索二叉树结点!\n"); #endif return NULL; } if (binaryNode->rightTag == 1 || binaryNode->leftTag == 1) { return binaryNode->right; } else { return binaryNode->left; } } struct ThreadedBinaryNode* getInorderSuccessorNode(struct ThreadedBinaryNode* binaryNode) { if (binaryNode == NULL) { #if PRINT printf("空线索二叉树结点!\n"); #endif return NULL; } if (binaryNode->rightTag == 1) { return binaryNode->right; } else { binaryNode = binaryNode->right; while (binaryNode->leftTag == 0) { binaryNode = binaryNode->left; } return binaryNode; } } struct ThreadedBinaryNode* getSuccessorNode(struct ThreadedBinaryNode* binaryNode, enum Sequence sequence) { if (sequence == 1) { binaryNode = getPreorderSuccessorNode(binaryNode); } else if (sequence == 2) { binaryNode = getInorderSuccessorNode(binaryNode); } else if (sequence == 3) { printf("后序线索二叉树非叶子结点无法找到它的后继!"); } else { printf("未知线索二叉树!\n"); } } void foreachPreorderThreadedBinaryNode(struct ThreadedBinaryTree* binaryTree) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("线索二叉树不存在!\n"); #endif return; } struct ThreadedBinaryNode* binaryNode = binaryTree->root; do { printf("%s ", binaryNode->data); binaryNode = getPreorderSuccessorNode(binaryNode); } while (binaryNode != NULL); } void foreachInorderThreadedBinaryNode(struct ThreadedBinaryTree* binaryTree) { if (binaryTree == NULL || binaryTree->root == NULL) { #if PRINT printf("线索二叉树不存在!\n"); #endif return; } struct ThreadedBinaryNode* binaryNode = binaryTree->root; // find the first node. while (binaryNode->leftTag == 0) { binaryNode = binaryNode->left; } do { printf("%s ", binaryNode->data); binaryNode = getInorderSuccessorNode(binaryNode); } while (binaryNode != NULL); } void foreachThreadedBinaryNode(struct ThreadedBinaryTree* binaryTree, enum Sequence sequence) { if (sequence == 1) { printf("前序遍历二叉线索树:"); foreachPreorderThreadedBinaryNode(binaryTree); printf("\n"); } else if (sequence == 2) { printf("中序遍历二叉线索树:"); foreachInorderThreadedBinaryNode(binaryTree); printf("\n"); } else if (sequence == 3) { printf("后序线索二叉树非叶子结点无法找到它的后继!"); printf("\n"); } else { printf("未知线索二叉树!\n"); } } //==========↑↑↑=Threaded Binary Tree=↑↑↑========= //==============↓↓↓=Huffman Tree=↓↓↓============= struct HuffmanNode* inithuffmanArrayNode(int leafCount); void compileHuffmanCode(struct HuffmanTree* huffmanTree); char* encodeHuffmanCode(char* soundCode, struct HuffmanTree* huffmanTree); void convertHuffmanBinaryTree(struct HuffmanTree* huffmanTree); char* decodeHuffmanCode(char* ciphertext, struct HuffmanTree* huffmanTree); void foreachHuffmanTree(struct HuffmanTree* huffmanTree); struct HuffmanNode { int weight; int parent; int leftChild; int rightChild; }; struct HuffmanCode { char* code; char* bits; }; struct HuffmanTree* initHuffmanTreeArray(int leafCount) { struct HuffmanTree* huffmanTree = malloc(sizeof(struct HuffmanTree)); if (huffmanTree == NULL) { #if PRINT printf("创建顺序表哈夫曼树失败,内存空间不足!\n"); #endif return NULL; } huffmanTree->leafCount = leafCount; huffmanTree->capacity = 2 * leafCount - 1; huffmanTree->root = inithuffmanArrayNode(leafCount); huffmanTree->huffmanCode = NULL; huffmanTree->huffmanBinaryTree = NULL; huffmanTree->compile = compileHuffmanCode; huffmanTree->encode = encodeHuffmanCode; huffmanTree->convert = convertHuffmanBinaryTree; huffmanTree->decode = decodeHuffmanCode; huffmanTree->foreach = foreachHuffmanTree; return huffmanTree; } void selectMinNodeIndex(struct HuffmanNode* huffmanNode, int size, int* minOneIndex, int* minTwoIndex) { int min = INT_MAX; for (int i = 0; i < size; i++) { if (huffmanNode[i].weight < min && huffmanNode[i].parent == -1) { *minOneIndex = i; min = huffmanNode[i].weight; } } min = INT_MAX; for (int i = 0; i < size; i++) { if (huffmanNode[i].weight < min && huffmanNode[i].parent == -1 && i != *minOneIndex) { *minTwoIndex = i; min = huffmanNode[i].weight; } } } struct HuffmanNode* inithuffmanArrayNode(int leafCount) { struct HuffmanNode* huffmanNode = malloc(sizeof(struct HuffmanNode) * 2 * leafCount - 1); if (huffmanNode == NULL) { #if PRINT printf("构建哈夫曼结点,内存空间不足!\n"); #endif return NULL; } int size = leafCount, capacity = 2 * size - 1; for (int i = 0; i < capacity; i++) { huffmanNode[i].weight = 0; huffmanNode[i].parent = -1; huffmanNode[i].leftChild = -1; huffmanNode[i].rightChild = -1; } printf("请输入构建顺序哈夫曼树的%d个权值:\n", leafCount); for (int i = 0; i < size; i++) { scanf("%d", &huffmanNode[i].weight); } int* minOneIndex = malloc(sizeof(int)); int* minTwoIndex = malloc(sizeof(int)); if (minOneIndex == NULL || minTwoIndex == NULL) { #if PRINT printf("构建哈夫曼结点,内存空间不足!\n"); #endif return NULL; } for (int i = size; i < capacity; i++) { selectMinNodeIndex(huffmanNode, i, minOneIndex, minTwoIndex); huffmanNode[*minOneIndex].parent = i; huffmanNode[*minTwoIndex].parent = i; huffmanNode[i].leftChild = *minOneIndex; huffmanNode[i].rightChild = *minTwoIndex; huffmanNode[i].weight = huffmanNode[*minOneIndex].weight + huffmanNode[*minTwoIndex].weight; } free(minOneIndex); minOneIndex = NULL; free(minTwoIndex); minTwoIndex = NULL; return huffmanNode; } void initHuffmanCode(struct HuffmanCode* huffmanCode, int leafCount) { printf("请按权值顺序输入%d个编码值:\n", leafCount); char ch; scanf("%c", &ch); for (int i = 0; i < leafCount; i++) { while (ch == ' ' || ch == '\n') { scanf("%c", &ch); } char* chr = malloc(sizeof(char) * 2); chr[0] = ch; chr[1] = '\0'; huffmanCode[i].code = chr; huffmanCode[i].bits = NULL; scanf("%c", &ch); } } void huffmanEncoding(struct HuffmanTree* huffmanTree, struct HuffmanCode* huffmanCode) { struct HuffmanNode* huffmanNode = huffmanTree->root; int index = 0, parentIndex = 0; for (int i = 0; i < huffmanTree->leafCount; i++) { index = parentIndex = i; struct ArrayList* list = initArrayList(5); do { parentIndex = huffmanNode[index].parent; if (huffmanNode[parentIndex].leftChild == index) { char* zero = malloc(sizeof(char)); if (zero == NULL) return; *zero = 48; list->insert(0, zero, list); } else { char* zero = malloc(sizeof(char)); if (zero == NULL) return; *zero = 49; list->insert(0, zero, list); } index = parentIndex; } while (huffmanNode[index].parent != -1); huffmanCode[i].bits = list->toString(list); list->ruin(list); } } void compileHuffmanCode(struct HuffmanTree* huffmanTree) { if (huffmanTree == NULL || huffmanTree->root == NULL) { #if PRINT printf("哈夫曼树为空不存在!\n"); #endif return; } huffmanTree->huffmanCode = malloc(sizeof(struct HuffmanCode) * huffmanTree->leafCount); if (huffmanTree->huffmanCode == NULL) { #if PRINT printf("构建哈夫曼编码失败,内存空间不足!\n"); #endif return; } initHuffmanCode(huffmanTree->huffmanCode, huffmanTree->leafCount); huffmanEncoding(huffmanTree, huffmanTree->huffmanCode); } char* encodeHuffmanCode(char* soundCode, struct HuffmanTree* huffmanTree) { if (huffmanTree == NULL || huffmanTree->root == NULL || huffmanTree->huffmanCode == NULL) { #if PRINT printf("哈夫曼树为空不存在或者哈夫曼树未编译编码!\n"); #endif return NULL; } struct ArrayList* binaryCode = initArrayList(5); struct HuffmanCode* huffmanCode = huffmanTree->huffmanCode; int size = huffmanTree->leafCount; while (*soundCode != '\0') { for (int i = 0; i < size; i++) { if (*soundCode == *huffmanCode[i].code) { char* bits = huffmanCode[i].bits; while (*bits != '\0') { char* ch = malloc(sizeof(char) * 2); if (ch == NULL) { } ch[0] = bits[0]; ch[1] = '\0'; binaryCode->insert(binaryCode->size(binaryCode), ch, binaryCode); bits++; } break; } } soundCode++; } char* ciphertext = binaryCode->toString(binaryCode); binaryCode->ruin(binaryCode); return ciphertext; } struct HuffmanArrayNode { char* data; int weight; struct BinaryNode* binaryNode; }; int sortHuffmanNode(void* data, void* ArrayData) { struct HuffmanArrayNode* front = data; struct HuffmanArrayNode* array = ArrayData; if (front->weight < array->weight) { return 1; } return 0; } struct ArrayList* createHuffmanArrayNode(struct HuffmanTree* huffmanTree) { int size = huffmanTree->leafCount; struct HuffmanNode* root = huffmanTree->root; struct HuffmanCode* huffmanCode = huffmanTree->huffmanCode; struct ArrayList* arrayList = initArrayList(5); for (int i = 0; i < size; i++) { struct HuffmanArrayNode* huffmanNode = malloc(sizeof(struct HuffmanArrayNode)); if (huffmanNode == NULL) { #if PRINT printf("初始化哈夫曼,内存空间不足!\n"); #endif return NULL; } huffmanNode->data = huffmanCode[i].code; huffmanNode->weight = root[i].weight; huffmanNode->binaryNode = NULL; arrayList->addSort(huffmanNode, sortHuffmanNode, arrayList); } return arrayList; } int compareHuffmanNode(void* firstData, void* secondData) { if (firstData == secondData) { return 1; } return 0; } struct BinaryNode* createHuffmanTree(struct ArrayList* huffmanArrayList) { int size = huffmanArrayList->size(huffmanArrayList); struct BinaryNode* root = NULL; for (int i = 0; i < size - 1; i++) { struct HuffmanArrayNode* leftWeight = huffmanArrayList->get(0, huffmanArrayList); if (leftWeight->binaryNode == NULL) { // char* leftData = malloc(sizeof(char) * 10); struct BinaryNode* leftNode = malloc(sizeof(struct BinaryNode)); if (leftNode == NULL) { #if PRINT printf("构建哈夫曼结点,内存空间不足!\n"); #endif return NULL; } // sprintf(leftData, "%d", leftWeight->weight); leftNode->data = leftWeight->data; leftNode->left = NULL; leftNode->right = NULL; leftWeight->binaryNode = leftNode; } struct HuffmanArrayNode* rightWeight = huffmanArrayList->get(1, huffmanArrayList); if (rightWeight->binaryNode == NULL) { // char* rightData = malloc(sizeof(char) * 10); struct BinaryNode* rightNode = malloc(sizeof(struct BinaryNode)); if (rightNode == NULL) { #if PRINT printf("构建哈夫曼结点,内存空间不足!\n"); #endif return NULL; } // sprintf(rightData, "%d", rightWeight->weight); rightNode->data = rightWeight->data; rightNode->left = NULL; rightNode->right = NULL; rightWeight->binaryNode = rightNode; } int weight = leftWeight->weight + rightWeight->weight; char* data = malloc(sizeof(char) * 10); root = malloc(sizeof(struct BinaryNode)); if (root == NULL) { #if PRINT printf("构建哈夫曼结点,内存空间不足!\n"); #endif return NULL; } sprintf(data, "%d", weight); root->data = data; root->left = leftWeight->binaryNode; root->right = rightWeight->binaryNode; huffmanArrayList->removeByData(leftWeight, compareHuffmanNode, huffmanArrayList); free(leftWeight); leftWeight = NULL; huffmanArrayList->removeByData(rightWeight, compareHuffmanNode, huffmanArrayList); free(rightWeight); rightWeight = NULL; struct HuffmanArrayNode* huffmanNode = malloc(sizeof(struct HuffmanArrayNode)); if (huffmanNode == NULL) { #if PRINT printf("添加构建的哈夫曼,内存空间不足!\n"); #endif return NULL; } huffmanNode->data = NULL; huffmanNode->weight = weight; huffmanNode->binaryNode = root; huffmanArrayList->addSort(huffmanNode, sortHuffmanNode, huffmanArrayList); } huffmanArrayList->ruin(huffmanArrayList); return root; } int depthHuffmanTree(struct BinaryNode* node) { if (node == NULL) { return 0; } int left = depthHuffmanTree(node->left); int right = depthHuffmanTree(node->right); return left > right ? left + 1 : right + 1; } void convertHuffmanBinaryTree(struct HuffmanTree* huffmanTree) { if (huffmanTree == NULL || huffmanTree->root == NULL) { #if PRINT printf("哈夫曼树为空不存在!\n"); #endif return; } if (huffmanTree->huffmanCode == NULL) { #if PRINT printf("哈夫曼树未编译编码,跳转编译!\n"); #endif compileHuffmanCode(huffmanTree); } struct BinaryTree* binaryTree = malloc(sizeof(struct BinaryTree)); if (binaryTree == NULL) { #if PRINT printf("创建二叉树失败,内存空间不足!\n"); #endif return; } binaryTree->root = createHuffmanTree(createHuffmanArrayNode(huffmanTree)); binaryTree->depth = depthHuffmanTree(binaryTree->root); setBinaryTreeFunction(binaryTree); huffmanTree->huffmanBinaryTree = binaryTree; } char recursionDecodeCiphertext(char** ciphertext, struct BinaryNode* huffmanBinaryNode) { if (huffmanBinaryNode->left == NULL && huffmanBinaryNode->right == NULL) { // 这里二叉链表存储的是字符串 而这里只取第一个字符是没有问题的 因为哈夫曼编码字符是单个的! return huffmanBinaryNode->data[0]; } if (**ciphertext == 48) { (*ciphertext)++; return recursionDecodeCiphertext(ciphertext, huffmanBinaryNode->left); } else { (*ciphertext)++; return recursionDecodeCiphertext(ciphertext, huffmanBinaryNode->right); } } char* decodeHuffmanCode(char* ciphertext, struct HuffmanTree* huffmanTree) { if (huffmanTree == NULL || huffmanTree->root == NULL || huffmanTree->huffmanBinaryTree == NULL) { #if PRINT printf("哈夫曼树为空不存在或者哈夫曼树未编译译码!\n"); #endif return NULL; } struct ArrayList* soundArray = initArrayList(5); struct BinaryNode* huffmanBinaryNode = huffmanTree->huffmanBinaryTree->root; while (*ciphertext != '\0') { char* charCode = malloc(sizeof(char)); if (charCode == NULL) { #if PRINT printf("破译哈夫曼编码内存空间不足!\n"); #endif return NULL; } *charCode = recursionDecodeCiphertext(&ciphertext, huffmanBinaryNode); soundArray->insert(soundArray->size(soundArray), charCode, soundArray); } char* sourceCode = soundArray->toString(soundArray); soundArray->ruin(soundArray); return sourceCode; } void foreachHuffmanTree(struct HuffmanTree* huffmanTree) { if (huffmanTree == NULL || huffmanTree->root == NULL) { #if PRINT printf("哈夫曼树为空不存在!\n"); #endif return; } struct HuffmanNode* huffmanNode = huffmanTree->root; for (int i = 0; i < huffmanTree->capacity; i++) { printf("index=%d ", i); printf("权值%d ", huffmanNode[i].weight); printf("父结点%d ", huffmanNode[i].parent); printf("左子树%d ", huffmanNode[i].leftChild); printf("右子树%d", huffmanNode[i].rightChild); printf("\n"); } if (huffmanTree->huffmanCode != NULL) { printf("哈夫曼编码表:\n"); struct HuffmanCode* huffmanCode = huffmanTree->huffmanCode; for (int i = 0; i < huffmanTree->leafCount; i++) { printf("index=%d ", i); printf("字符编码:%s ", huffmanCode[i].code); printf("二进制编码:%s", huffmanCode[i].bits); printf("\n"); } } } //==============↑↑↑=Huffman Tree=↑↑↑============ |
测试:
#define _CRT_SECURE_NO_WARNINGS //规避C4996告警 #include <stdio.h> #include <stdlib.h> #include <string.h> #include "binaryTree.h" int main() { char preorder[19] = "A B D E G H C F I"; char inorder[19] = "D B G E H A C I F"; struct BinaryTree* binaryTree = initTreeBySequenceAndInorder(preorder, inorder, 0); binaryTree->draw(binaryTree); struct ThreadedBinaryTree* preorderTree = convertThreadedBinaryTree(binaryTree, 1); preorderTree->foreach(preorderTree, 1); struct ThreadedBinaryTree* inorderTree = convertThreadedBinaryTree(binaryTree, 2); inorderTree->foreach(inorderTree, 2); return 0; } |
运行结果:
A / \ B C / \ / \ D E * F / \ / \ / \ / \ * * G H * * I * / / / / / / / / \ 二叉树前序线索化! 前序遍历二叉线索树:A B D E G H C F I 二叉树中序线索化! 中序遍历二叉线索树:D B G E H A C I F |