C语言数据结构【手抄版】第八章 查找【尾篇】B树实现

字符串工具,规避了了数字类型字符串比较不准确的BUG,string.h:

#pragma once

#ifdef __cplusplus

extern "C" {

#endif

#ifndef STRING_H

#define STRING_H

int stringCompare(char* first, char* second);

#endif

#ifdef __cplusplus

}

#endif

string.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(second, "0123456789") >= strlen(second))

      {

            int one = atoi(first), two = atoi(second);

            if (one > two) return 1;

            if (one == two) return 0;

            if (one < two) return -1;

      }

      else

      {

            return strcmp(first, second);

      }

}

balanceTree.h​​​​​​​

#pragma once

#ifdef __cplusplus

extern "C" {

#endif

#ifndef BALANCE_TREE_H

#define BALANCE_TREE_H

#include <Windows.h>

#include "string.h"

#include "sequenceQueue.h"

struct BalanceTree

{

      int size;

      int nodeSize;

      struct BalanceNode* root;

      struct ResultBalanceInfo* (*find)(char* data, struct BalanceTree* balanceTree);

      int (*insert)(char* data, struct BalanceTree* balanceTree);

      int (*remove)(char* data, struct BalanceTree* balanceTree);

      void (*draw)(struct BalanceTree* balanceTree);

};

struct BalanceNode

{

      int keyNum;

      char** keys;

      int poNum;

      struct BalanceNode** pointers;

      struct BalanceNode* parent;

};

struct ResultBalanceInfo

{

      struct BalanceNode* balanceNode;

      int index;

      int tag;

};

struct BalanceTree* initBalanceTree(int nodeSize);

#endif

#ifdef __cplusplus

}

#endif

balanceTree.c

#define _CRT_SECURE_NO_WARNINGS //规避C4996告警

#include <stdio.h>

#include <stdlib.h>

#include "balanceTree.h"

#define PRINT 1

#define DRAW_BALANCE_NODE 1

void drawBalanceTree(struct BalanceTree* balanceTree);

/*

* struct BalanceNode* initBalanceNode(int nodeSize);

* void setBalanceNode(struct BalanceNode** root, char* data, struct BalanceNode* balanceNode, int index, int nodeSize);

*/

int insertBalanceNode(char* data, struct BalanceTree* balanceTree);

/*

* int searchBalanceIndex(struct BalanceNode* balanceNode, char* data);

*/

struct ResultBalanceInfo* findBalanceNode(char* data, struct BalanceTree* balanceTree);

/*

* void moveBalanceNode(struct BalanceNode* removeNode, struct BalanceTree* balanceTree);

*/

int removeBalanceNode(char* data, struct BalanceTree* balanceTree);

struct BalanceTree* initBalanceTree(int nodeSize)

{

      struct BalanceTree* tree = malloc(sizeof(struct BalanceTree));

      if (tree == NULL)

      {

#ifdef PRINT

            printf("创建平衡多路查找树失败,内存空间不足!");

#endif

            return NULL;

      }

      tree->size = 0;

      tree->size = 0;

      tree->nodeSize = nodeSize;

      tree->root = NULL;

      tree->find = findBalanceNode;

      tree->draw = drawBalanceTree;

      tree->insert = insertBalanceNode;

      tree->remove = removeBalanceNode;

      return tree;

}

void printBalanceNode(struct BalanceNode* balanceNode, int nodeSize);

int getBalanceNodeDepth(struct BalanceNode* balanceNode, int depth);

void drawBalanceTree(struct BalanceTree* balanceTree)

{

      if (balanceTree == NULL || balanceTree->root == NULL)

      {

#ifdef PRINT

            printf("平衡多路查找树为空或不存在!\n");

#endif

            return;

      }

#ifdef DRAW_BALANCE_NODE

      struct BalanceNode* balanceNode = balanceTree->root;

      printBalanceNode(balanceTree->root, balanceTree->nodeSize);

      int depth = getBalanceNodeDepth(balanceNode, 1);

      CONSOLE_SCREEN_BUFFER_INFO ipBuffer;

      GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ipBuffer);

      COORD coord = { 0 };

      coord.X = 0;

      coord.Y = ipBuffer.dwCursorPosition.Y + depth * 2;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

#endif

}

void printBalanceNode(struct BalanceNode* balanceNode, int nodeSize)

{

      int depth = getBalanceNodeDepth(balanceNode, 0);

      int blank = depth * (nodeSize + 2) * 4;

      if (depth == 0)

      {

            blank = 0;

      }

      while (blank)

      {

            printf(" ");

            blank--;

      }

      int entity = nodeSize + 1;

      int pointer = 0;

      if (balanceNode->parent == NULL)

      {

            printf("%s↓", "#");

      }

      else

      {

            printf("%s↓", balanceNode->parent->keys[0]);

      }

      printf("%d↓", balanceNode->keyNum);

      while (entity && pointer < balanceNode->keyNum)

      {

            printf("%s", balanceNode->keys[pointer]);

            printf("↓");

            pointer++;

      }

      CONSOLE_SCREEN_BUFFER_INFO ipBuffer;

      GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &ipBuffer);

      COORD coord = { 0 };

      coord.X = ipBuffer.dwCursorPosition.X - 1;

      coord.Y = ipBuffer.dwCursorPosition.Y + 1;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

      printf("\\");

      coord.X = ipBuffer.dwCursorPosition.X - balanceNode->keyNum * 1.5 - 1;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

      printf("↓");

      coord.X = ipBuffer.dwCursorPosition.X - balanceNode->keyNum * 2.5 - 2;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

      printf("↓");

      coord.X = ipBuffer.dwCursorPosition.X - balanceNode->keyNum * 3.5 - 3;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

      printf("/");

      int move = (nodeSize + 2) * 4 + balanceNode->keyNum * 2 + balanceNode->poNum * 2;

      if (depth > 0)

      {

            move *= depth;

      }

      coord.X = (ipBuffer.dwCursorPosition.X >= move ? ipBuffer.dwCursorPosition.X - move : 0);

      coord.Y = ipBuffer.dwCursorPosition.Y + 2;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

      int child = 0;

      while (child < balanceNode->poNum)

      {

            struct BalanceNode* childNode = balanceNode->pointers[child];

            printBalanceNode(childNode, nodeSize);

            child++;

            if (child >= balanceNode->poNum)

            {

                  break;

            }

            if ((childNode->keyNum + childNode->poNum) < (nodeSize * 2 + 1))

            {

                  int moveBlank = nodeSize * 2 - (childNode->keyNum + childNode->poNum);

                  if (depth > 1)

                  {

                        moveBlank = depth * nodeSize * 3;

                  }

                  while (moveBlank > 0)

                  {

                        printf(" ");

                        moveBlank--;

                  }

            }

      }

      coord.X = ipBuffer.dwCursorPosition.X + 1;

      coord.Y = ipBuffer.dwCursorPosition.Y;

      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);

}

int getBalanceNodeDepth(struct BalanceNode* balanceNode, int depth)

{

      while (balanceNode->pointers[0] != NULL)

      {

            depth++;

            balanceNode = balanceNode->pointers[0];

      }

      return depth;

}

struct BalanceNode* initBalanceNode(int nodeSize);

void setBalanceNode(struct BalanceNode** root, char* data, struct BalanceNode* balanceNode, int index, int nodeSize);

int insertBalanceNode(char* data, struct BalanceTree* balanceTree)

{

      if (balanceTree == NULL)

      {

#ifdef PRINT

            printf("平衡多路查找树不存在!");

#endif

            return NULL;

      }

      if (data == NULL)

      {

#ifdef PRINT

            printf("插入数据不存在!");

#endif

            return NULL;

      }

      struct BalanceNode* root = balanceTree->root;

      if (root == NULL)

      {

            root = initBalanceNode(balanceTree->nodeSize);

            balanceTree->root = root;

            root->keys[root->keyNum++] = data;

            balanceTree->size++;

            return 1;

      }

      struct ResultBalanceInfo* result = findBalanceNode(data, balanceTree);

      setBalanceNode(&balanceTree->root, data, result->balanceNode, result->index, balanceTree->nodeSize);

      free(result); result = NULL;

}

struct BalanceNode* initBalanceNode(int nodeSize)

{

      struct BalanceNode* balanceNode = malloc(sizeof(struct BalanceNode));

      if (balanceNode == NULL)

      {

#ifdef PRINT

            printf("创建平衡多路查找树结点失败,开辟内存失败!\n");

#endif

            return NULL;

      }

      char** keys = calloc(nodeSize, sizeof(char*));

      struct BalanceNode** pointers = calloc(nodeSize + 1, sizeof(struct BalanceNode*));

      if (keys == NULL || pointers == NULL)

      {

#ifdef PRINT

            printf("创建平衡多路查找树结点存储结构失败,开辟内存失败!\n");

#endif

            return NULL;

      }

      balanceNode->keyNum = 0;

      balanceNode->keys = keys;

      balanceNode->poNum = 0;

      balanceNode->pointers = pointers;

      balanceNode->parent = NULL;

}

void setBalanceData(struct BalanceNode* balanceNode, int index, char* data, int nodeSize);

void splitBrotherNode(struct BalanceNode** root, struct BalanceNode* balanceNode, int nodeSize);

void setBalanceNode(struct BalanceNode** root, char* data, struct BalanceNode* balanceNode, int index, int nodeSize)

{

      if (balanceNode->keyNum < nodeSize)

      {

            setBalanceData(balanceNode, index, data, nodeSize);

            if (balanceNode->keyNum < nodeSize) return;

            if (balanceNode->keyNum == nodeSize)

            {

                  splitBrotherNode(root, balanceNode, nodeSize);

            }

      }

      else

      {

#ifdef PRINT

            printf("插入节点数据时,空间不足!\n");

#endif

            return;

      }

}

void setBalanceData(struct BalanceNode* balanceNode, int index, char* data, int nodeSize)

{

      int size = balanceNode->keyNum;

      if (size == nodeSize)

      {

            printf("数值越界\n");

      }

      for (int i = size; i > index; i--)

      {

            balanceNode->keys[i] = balanceNode->keys[i - 1];

            balanceNode->pointers[i] = balanceNode->pointers[i - 1];

      }

      balanceNode->keys[index] = data;

      balanceNode->keyNum++;

}

void splitBrotherBrother(struct BalanceNode* balanceNode, int midIndex, struct BalanceNode** brother, int nodeSize);

struct BalanceNode* splitBrotherParent(struct BalanceNode** root, struct BalanceNode* balanceNode,

      struct BalanceNode* brother, char* parentData, int nodeSize);

void splitBrotherNode(struct BalanceNode** root, struct BalanceNode* balanceNode, int nodeSize)

{

      int midIndex = nodeSize / 2;

      struct BalanceNode* brother = NULL;

      splitBrotherBrother(balanceNode, midIndex, &brother, nodeSize);

      char* parentData = balanceNode->keys[midIndex];

      balanceNode->keys[midIndex] = NULL;

      balanceNode->keyNum--;

      struct BalanceNode* parent = splitBrotherParent(root, balanceNode, brother, parentData, nodeSize);

      if (parent->keyNum >= nodeSize)

      {

            splitBrotherNode(root, parent, nodeSize);

      }

}

void splitBrotherBrother(struct BalanceNode* balanceNode, int midIndex, struct BalanceNode** brother, int nodeSize)

{

      (*brother) = initBalanceNode(nodeSize);

      for (int i = midIndex + 1; i <= nodeSize; i++)

      {

            int pointIndex = i - (midIndex + 1);

            (*brother)->pointers[pointIndex] = balanceNode->pointers[i];

            if ((*brother)->pointers[pointIndex] != NULL)

            {

                  (*brother)->poNum++;

                  balanceNode->poNum--;

                  (*brother)->pointers[pointIndex]->parent = (*brother);

            }

            if (i < nodeSize)

            {

                  (*brother)->keys[pointIndex] = balanceNode->keys[i];

            }

      }

      (*brother)->parent = balanceNode->parent;

      (*brother)->keyNum = balanceNode->keyNum - (midIndex + 1);

      balanceNode->keyNum = midIndex + 1;

}

struct BalanceNode* splitBrotherParent(struct BalanceNode** root, struct BalanceNode* balanceNode,

      struct BalanceNode* brother, char* parentData, int nodeSize)

{

      struct BalanceNode* parent = balanceNode->parent;

      if (balanceNode->parent == NULL)

      {

            parent = initBalanceNode(nodeSize);

            parent->keys[parent->keyNum++] = parentData;

            *root = parent;

            parent->pointers[parent->poNum++] = balanceNode;

            balanceNode->parent = parent;

            parent->pointers[parent->poNum++] = brother;

            brother->parent = parent;

      }

      else

      {

            int index = searchBalanceIndex(parent, parentData);

            for (int i = parent->keyNum; i > index; i--)

            {

                  parent->keys[i] = parent->keys[i - 1];

                  parent->pointers[i + 1] = parent->pointers[i];

            }

            parent->keys[index] = parentData;

            parent->keyNum++;

            parent->pointers[index + 1] = brother;

            parent->poNum++;

      }

      return parent;

}

int searchBalanceIndex(struct BalanceNode* balanceNode, char* data);

struct ResultBalanceInfo* findBalanceNode(char* data, struct BalanceTree* balanceTree)

{

      struct BalanceNode* balanceNode = balanceTree->root;

      struct BalanceNode* parent = NULL;

      int found = 0, index = 0;

      while (balanceNode != NULL && found == 0)

      {

            index = searchBalanceIndex(balanceNode, data);

            if (index > 0 && index <= balanceNode->keyNum && stringCompare(balanceNode->keys[index - 1], data) == 0)

            {

                  index = index - 1;

                  found = 1;

            }

            else

            {

                  parent = balanceNode;

                  balanceNode = balanceNode->pointers[index];

            }

      }

      struct ResultBalanceInfo* result = malloc(sizeof(struct ResultBalanceInfo));

      if (result == NULL)

      {

#ifdef PRINT

            printf("搜索节点创建返回值对象,开辟内存失败!\n");

#endif

            return NULL;

      }

      result->index = index;

      if (found == 1)

      {

            result->balanceNode = balanceNode;

            result->tag = 1;

      }

      else

      {

            result->balanceNode = parent;

            result->tag = 0;

      }

      return result;

}

int searchBalanceIndex(struct BalanceNode* balanceNode, char* data)

{

      int i = 0;

      for (i = 0;

            i < balanceNode->keyNum &&

            (stringCompare(balanceNode->keys[i], data) < 0 ||

                  stringCompare(balanceNode->keys[i], data) == 0);

            i++);

      return i;

}

void moveBalanceNode(struct BalanceNode* removeNode, struct BalanceTree* balanceTree);

int removeBalanceNode(char* data, struct BalanceTree* balanceTree)

{

      if (balanceTree == NULL)

      {

#ifdef PRINT

            printf("平衡多路查找树不存在!");

#endif

            return NULL;

      }

      if (data == NULL)

      {

#ifdef PRINT

            printf("插入数据不存在!");

#endif

            return NULL;

      }

      struct ResultBalanceInfo* result = findBalanceNode(data, balanceTree);

      struct BalanceNode* balanceNode = result->balanceNode;

      if (result->tag == 1)

      {

            struct BalanceNode* removeNode = balanceNode;

            if (balanceNode->poNum <= 0)

            {

                  int size = balanceNode->keyNum;

                  for (int i = result->index; i < size; i++)

                  {

                        balanceNode->keys[i] = balanceNode->keys[i + 1];

                  }

                  balanceNode->keys[size] = NULL;

                  balanceNode->keyNum--;

            }

            else

            {

                  struct BalanceNode* current = balanceNode->pointers[result->index];

                  removeNode = current;

                  while (current != NULL && current->poNum > 0)

                  {

                        removeNode = current;

                        current = current->pointers[current->poNum - 1];

                  }

                  balanceNode->keys[result->index] = removeNode->keys[removeNode->keyNum - 1];

                  removeNode->keys[--removeNode->keyNum] = NULL;

            }

            int minSize = balanceTree->nodeSize / 2 - 1;

            if (balanceTree->nodeSize % 2 > 0) minSize++;

            if (removeNode->keyNum < minSize)

            {

                  moveBalanceNode(removeNode, balanceTree);

            }

      }

      else

      {

#ifdef PRINT

            printf("平衡多路查找树,删除数值:%s不存在\n", data);

#endif

            return NULL;

      }

      return 1;

}

int findCurrentPointer(struct BalanceNode* parent, struct BalanceNode* current);

void chooseCombineNode(struct BalanceNode* removeNode, int pointer, int nodeSize);

enum BalanceLocationFlag { left = 1, mid = 2, right = 3, rightLeft = 4, leftRight = 5 };

struct BalanceNode* combineBrotherNode(struct BalanceNode* left, int leftPoint, struct BalanceNode* right, int rightPoint);

enum MoveBalanceFlag { success = 1, combineLeftParent = 2, combineNode = 3, combineRoot = 4, combineRightParent = 5 };

enum MoveBalanceFlag moveRightBalanceValue(struct BalanceNode* parent, struct BalanceNode* removeNode,

      struct SequenceQueue* queue, int minSize, struct BalanceNode** root);

enum MoveBalanceFlag moveLeftBalanceValue(struct BalanceNode* parent, struct BalanceNode* removeNode,

      struct SequenceQueue* queue, int minSize, struct BalanceNode** root);

void combineLeftParentNode(struct BalanceNode* parent, int isLeft, struct BalanceNode** root);

void combineRightParentNode(struct BalanceNode* parent, int isLeft, struct BalanceNode** root);

void moveBalanceValue(struct SequenceQueue* queue);

void moveBalanceNode(struct BalanceNode* removeNode, struct BalanceTree* balanceTree)

{

      struct BalanceNode* parent = removeNode->parent;

      if (parent == NULL)

      {

            balanceTree->root = NULL;

            return;

      }

      int minSize = balanceTree->nodeSize / 2 - 1;

      if (balanceTree->nodeSize % 2 > 0) minSize++;

      enum BalanceLocationFlag locationFlag = mid;

      int pointer = findCurrentPointer(parent, removeNode);

      if (pointer == parent->keyNum)

      {

            if (parent->parent == NULL)

            {

                  locationFlag = right;

            }

            else

            {

                  int parentPointer = findCurrentPointer(parent->parent, parent);

                  if (parentPointer == 0)

                  {

                        locationFlag = leftRight;

                  }

                  else if (parentPointer == parent->parent->keyNum)

                  {

                        locationFlag = right;

                  }

                  else

                  {

                        chooseCombineNode(removeNode, pointer, balanceTree->nodeSize);

                        return;

                  }

            }

      }

      else if (pointer == 0)

      {

            if (parent->parent == NULL)

            {

                  locationFlag = left;

            }

            else

            {

                  int parentPointer = findCurrentPointer(parent->parent, parent);

                  if (parentPointer == 0)

                  {

                        locationFlag = left;

                  }

                  else if (parentPointer == parent->parent->keyNum)

                  {

                        locationFlag = rightLeft;

                  }

                  else

                  {

                        chooseCombineNode(removeNode, pointer, balanceTree->nodeSize);

                        return;

                  }

            }

      }

      else

      {

            chooseCombineNode(removeNode, pointer, balanceTree->nodeSize);

            return;

      }

      if (parent->poNum > 2)

      {

            if (locationFlag == right || locationFlag == leftRight)

            {

                  combineBrotherNode(parent->pointers[pointer - 1], pointer - 1, removeNode, pointer);

            }

            if (locationFlag == left || locationFlag == rightLeft)

            {

                  combineBrotherNode(removeNode, pointer, parent->pointers[pointer + 1], pointer + 1);

            }

      }

      else

      {

            struct BalanceNode* rootNode = removeNode;

            struct BalanceNode* rootParent = parent;

            struct SequenceQueue* queue = initSequenceQueue();

            removeNode->keyNum++;

            enum MoveBalanceFlag moveFlag = 0;

            if (locationFlag == right || locationFlag == rightLeft)

            {

            again:

                  queue->push(&removeNode->keys[0], queue);

                  if (locationFlag == rightLeft)

                  {

                        removeNode = parent;

                        parent = parent->parent;

                  }

                  moveFlag = moveRightBalanceValue(parent, removeNode, queue, minSize, &balanceTree->root);

                  if (moveFlag == combineLeftParent)

                  {

                        parent = rootParent;

                        int isLeft = 1;

                        if (locationFlag == rightLeft)

                        {

                              isLeft = 0;

                        }

                        combineLeftParentNode(parent, isLeft, &balanceTree->root);

                  }

                  if (moveFlag == combineNode)

                  {

                        removeNode = rootNode;

                        parent = rootParent;

                        goto again;

                  }

            }

            if (locationFlag == left || locationFlag == leftRight)

            {

            leftAgain:

                  queue->push(&removeNode->keys[0], queue);

                  if (locationFlag == leftRight)

                  {

                        removeNode = parent;

                        parent = parent->parent;

                  }

                  moveFlag = moveLeftBalanceValue(parent, removeNode, queue, minSize, &balanceTree->root);

                  if (moveFlag == combineRightParent)

                  {

                        parent = rootParent;

                        int isLeft = 0;

                        if (locationFlag == leftRight)

                        {

                              isLeft = 1;

                        }

                        combineRightParentNode(parent, isLeft, &balanceTree->root);

                  }

                  if (moveFlag == combineNode)

                  {

                        removeNode = rootNode;

                        parent = rootParent;

                        goto leftAgain;

                  }

            }

            // 执行移位

            if (moveFlag == success)

            {

                  moveBalanceValue(queue);

            }

            queue->destroy(queue);

      }

}

int findCurrentPointer(struct BalanceNode* parent, struct BalanceNode* current)

{

      int poNum = parent->poNum;

      while (poNum >= 0)

      {

            poNum--;

            if (parent->pointers[poNum] == current) return poNum;

      }

      return poNum;

}

void chooseCombineNode(struct BalanceNode* removeNode, int pointer, int nodeSize)

{

      struct BalanceNode* parent = removeNode->parent;

      if (parent->pointers[pointer + 1]->keyNum < nodeSize)

      {

            combineBrotherNode(removeNode, pointer, parent->pointers[pointer + 1], pointer + 1);

      }

      else if (parent->pointers[pointer - 1]->keyNum < nodeSize)

      {

            combineBrotherNode(parent->pointers[pointer - 1], pointer - 1, removeNode, pointer);

      }

      else

      {

            struct BalanceNode* left = parent->pointers[pointer - 1];

            removeNode->keys[removeNode->keyNum++] = left->keys[left->keyNum - 1];

            left->keys[--left->keyNum] = NULL;

      }

}

struct BalanceNode* combineBrotherNode(struct BalanceNode* left, int leftPoint, struct BalanceNode* right, int rightPoint)

{

      struct BalanceNode* parent = NULL;

      if (left->keys[0] == NULL && right->parent->keyNum <= 1)

      {

            parent = right->parent;

            free(left); left = NULL;

            parent->poNum--;

            int keyNum = right->keyNum;

            while (keyNum > 0)

            {

                  right->keys[keyNum] = right->keys[keyNum - 1];

                  keyNum--;

            }

            right->keys[0] = parent->keys[leftPoint];

            right->keyNum++;

            keyNum = parent->keyNum - 1;

            int index = 0;

            while (index < keyNum)

            {

                  parent->keys[index] = parent->keys[index + 1];

                  index++;

            }

            parent->keyNum--;

            int poNum = parent->poNum - 1;

            index = leftPoint;

            while (index < poNum)

            {

                  parent->pointers[index] = parent->pointers[index + 1];

                  index++;

            }

            parent->poNum--;

            if (parent->keyNum <= 0 && parent->poNum <= 0)

            {

                  free(right->parent);

                  right->parent = NULL;

                  parent = NULL;

                  return right;

            }

      }

      else

      {

            parent = left->parent;

            left->keys[left->keyNum++] = parent->keys[leftPoint];

            if (right->keyNum > 0 && right->keys[right->keyNum - 1] != NULL)

            {

                  left->keys[left->keyNum++] = right->keys[right->keyNum - 1];

            }

            free(right); right = NULL;

            for (int i = leftPoint; i < parent->keyNum; i++, rightPoint++)

            {

                  parent->keys[i] = parent->keys[i + 1];

                  parent->pointers[rightPoint] = parent->pointers[rightPoint + 1];

            }

            parent->keys[--parent->keyNum] = NULL;

            parent->pointers[--parent->poNum] = NULL;

            if (parent->keyNum <= 0)

            {

                  free(left->parent);

                  left->parent = NULL;

                  parent = NULL;

                  return left;

            }

      }

      return parent;

}

enum MoveBalanceFlag moveRightBalanceValue(struct BalanceNode* parent, struct BalanceNode* removeNode,

      struct SequenceQueue* queue, int minSize, struct BalanceNode** root)

{

      enum MoveBalanceFlag moveFlag = success;

      int removePointer = findCurrentPointer(parent, removeNode);

      queue->push(&parent->keys[removePointer - 1], queue);

      struct BalanceNode* left = parent->pointers[removePointer - 1];

      if (left->keyNum > minSize || left->pointers[left->keyNum] != NULL)

      {

            if (left->pointers[left->keyNum] == NULL)

            {

                  queue->push(&left->keys[--left->keyNum], queue);

            }

            else

            {

                  struct BalanceNode* right = left->pointers[left->keyNum];

                  struct BalanceNode* front = NULL;

                  while (right != NULL)

                  {

                        front = right;

                        right = right->pointers[right->keyNum];

                  }

                  queue->push(&front->keys[front->keyNum - 1], queue);

                  if (front->keyNum <= minSize)

                  {

                        return moveRightBalanceValue(front->parent, front, queue, minSize, root);

                  }

                  else

                  {

                        front->keyNum--;

                  }

            }

      }

      else

      {

            int leftPointer = removePointer - 1;

            queue->push(&left->keys[left->keyNum - 1], queue);

            if (leftPointer == 0 && parent->parent != NULL)

            {

                  if (stringCompare(parent->parent->keys[parent->parent->keyNum - 1], left->keys[left->keyNum - 1]) > 0)

                  {

                        if (parent->keyNum > minSize)

                        {

                              combineBrotherNode(left, leftPointer, removeNode, removePointer);

                              queue->clear(queue);

                              return moveFlag = combineNode;

                        }

                        else

                        {

                              return moveFlag = combineLeftParent;

                        }

                  }

                  else

                  {

                        return moveRightBalanceValue(parent->parent, parent, queue, minSize, root);

                  }

            }

            else if (leftPointer == 0 && parent->parent == NULL)

            {

                  struct BalanceNode* result = combineBrotherNode(left, leftPointer, removeNode, removePointer);

                  if (result != parent)

                  {

                        *root = result; parent = NULL;

                        return moveFlag = combineRoot;

                  }

                  queue->clear(queue);

                  return moveFlag = combineNode;

            }

            else

            {

                  return moveRightBalanceValue(parent, left, queue, minSize, root);

            }

      }

      return moveFlag;

}

enum MoveBalanceFlag moveLeftBalanceValue(struct BalanceNode* parent, struct BalanceNode* removeNode,

      struct SequenceQueue* queue, int minSize, struct BalanceNode** root)

{

      enum MoveBalanceFlag moveFlag = success;

      int removePointer = findCurrentPointer(parent, removeNode);

      queue->push(&parent->keys[removePointer], queue);

      struct BalanceNode* right = parent->pointers[removePointer + 1];

      if (right->keyNum > minSize || right->pointers[0] != NULL)

      {

            if (right->pointers[0] == NULL)

            {

                  char* temp = right->keys[0];

                  int keyNum = right->keyNum - 1;

                  int index = 0;

                  while (index < keyNum)

                  {

                        right->keys[index] = right->keys[index + 1];

                        index++;

                  }

                  right->keys[keyNum] = temp;

                  queue->push(&right->keys[keyNum], queue);

                  right->keyNum--;

            }

            else

            {

                  struct BalanceNode* left = right->pointers[0];

                  struct BalanceNode* front = NULL;

                  while (left != NULL)

                  {

                        front = left;

                        left = left->pointers[0];

                  }

                  int keyNum = 0, size = front->keyNum - 1;

                  char* temp = front->keys[0];

                  while (keyNum < size)

                  {

                        front->keys[keyNum] = front->keys[keyNum + 1];

                        keyNum++;

                  }

                  front->keys[front->keyNum - 1] = temp;

                  queue->push(&front->keys[front->keyNum - 1], queue);

                  if (front->keyNum <= minSize)

                  {

                        return moveLeftBalanceValue(front->parent, front, queue, minSize, root);

                  }

                  else

                  {

                        front->keyNum--;

                  }

            }

      }

      else

      {

            int rightPointer = removePointer + 1;

            queue->push(&right->keys[right->keyNum - 1], queue);

            if (rightPointer == parent->keyNum && parent->parent != NULL)

            {

                  if (stringCompare(parent->parent->keys[0], right->keys[right->keyNum - 1]) < 0)

                  {

                        if (parent->keyNum > minSize)

                        {

                              combineBrotherNode(removeNode, removePointer, right, rightPointer);

                              queue->clear(queue);

                              return moveFlag = combineNode;

                        }

                        else

                        {

                              return moveFlag = combineRightParent;

                        }

                  }

                  else

                  {

                        return moveLeftBalanceValue(parent->parent, parent, queue, minSize, root);

                  }

            }

            else if (rightPointer == 1 && parent->parent == NULL)

            {

                  struct BalanceNode* result = combineBrotherNode( removeNode, removePointer, right, rightPointer);

                  if (result != parent)

                  {

                        *root = result; parent = NULL;

                        return moveFlag = combineRoot;

                  }

                  queue->clear(queue);

                  return moveFlag = combineNode;

            }

            else

            {

                  return moveLeftBalanceValue(parent, right, queue, minSize, root);

            }

      }

      return moveFlag;

}

void combineLeftParentValue(struct BalanceNode* parent);

void combineRightParentValue(struct BalanceNode* parent);

void combineLeftParentNode(struct BalanceNode* parent, int isLeft, struct BalanceNode** root)

{

      if (isLeft)combineLeftParentValue(parent);

      else combineRightParentValue(parent);

      

      parent = parent->parent;

      struct BalanceNode* left = parent->pointers[parent->keyNum - 1];

      left->parent = parent->parent;

      left->keys[left->keyNum++] = parent->keys[--parent->keyNum];

      left->pointers[left->poNum++] = parent->pointers[parent->poNum - 1];

      parent->pointers[parent->poNum - 1]->parent = left;

      if (*root == parent)

      {

            *root = left;

      }

      free(parent); parent = NULL;

}

void combineLeftParentValue(struct BalanceNode* parent)

{

      struct BalanceNode* left = parent->pointers[parent->keyNum - 1];

      char* leftValue = left->keys[left->keyNum - 1];

      parent->keys[parent->keyNum] = parent->keys[parent->keyNum - 1];

      parent->keys[parent->keyNum - 1] = leftValue;

      parent->keyNum++;

      free(parent->pointers[parent->poNum - 1]);

      free(parent->pointers[parent->poNum - 2]);

      parent->pointers[--parent->poNum] = NULL;

      parent->pointers[--parent->poNum] = NULL;

}

void combineRightParentNode(struct BalanceNode* parent, int isLeft, struct BalanceNode** root)

{

      if (isLeft)combineLeftParentValue(parent);

      else combineRightParentValue(parent);

      

      parent = parent->parent;

      struct BalanceNode* right = parent->pointers[parent->keyNum];

      right->parent = parent->parent;

      int keyNum = right->keyNum;

      while (keyNum > 0)

      {

            right->keys[keyNum] = right->keys[keyNum - 1];

            keyNum--;

      }

      int poNum = right->poNum;

      while (poNum > 0)

      {

            right->pointers[poNum] = right->pointers[poNum - 1];

            poNum--;

      }

      right->keys[0] = parent->keys[--parent->keyNum];

      right->keyNum++;

      right->pointers[0] = parent->pointers[0];

      right->poNum++;

      parent->pointers[0]->parent = right;

      if (*root == parent)

      {

            *root = right;

      }

      free(parent); parent = NULL;

}

void combineRightParentValue(struct BalanceNode* parent)

{

      struct BalanceNode* right = parent->pointers[parent->keyNum];

      char* rightValue = right->keys[right->keyNum - 1];

      parent->keys[parent->keyNum++] = rightValue;

      free(parent->pointers[parent->poNum - 1]);

      free(parent->pointers[parent->poNum - 2]);

      parent->pointers[--parent->poNum] = NULL;

      parent->pointers[--parent->poNum] = NULL;

}

void moveBalanceValue(struct SequenceQueue* queue)

{

      char** front = queue->front(queue);

      queue->pop(queue);

      char** next = front;

      while (queue->isNotEmpty(queue))

      {

            next = queue->front(queue);

            queue->pop(queue);

            *front = *next;

            front = next;

      }

      *next = NULL;

}

猜你喜欢

转载自blog.csdn.net/qq_43460743/article/details/130693608