1. 程式人生 > >資料結構 樹的複製--非遞迴演算法

資料結構 樹的複製--非遞迴演算法

  • 藉助佇列來實現,樹結構的複製
typedef struct BiTree {
    char data;
    struct BiTree *leftChild;
    struct BiTree *rightChild;
} BiTree;


typedef struct QueueTree {
    // 為了節省空間,使用的是迴圈佇列
    BiTree **base;    // 用於存放樹結點的指標
    int front;
    int rear;
    int tag;      // 佇列是否為空
    int length;
} QueueTree;


QueueTree InitQueueTree(int length);

bool ENQueueTree(QueueTree *queue, BiTree *e);

bool DEQueueTree(QueueTree *queue, BiTree **result);

BiTree *CopyBinaryTree(BiTree *root);
  • 詳細程式碼

bool ENQueueTree(QueueTree *queue, BiTree *e) {
    if (queue->tag == queue->length) return false;
    queue->base[queue->rear] = e;
    if (queue->rear == queue->length - 1) {
        queue->rear = 0;
        queue->tag++;
        return true;
    }
    queue->rear++;
    queue->tag++;
    return true;
}

bool DEQueueTree(QueueTree *queue, BiTree **result) {
    if (queue->tag == 0) return false;
    *result = queue->base[queue->front];
    if (queue->front == queue->length - 1) {
        queue->front = 0;
        queue->tag--;
        return true;
    }
    queue->front++;
    queue->tag--;
    return true;
}

IStack InStackHTree(int stack_size) {
    IStack CS;
    CS.stack_size = stack_size;
    if (!(CS.base = (int *) malloc(stack_size * sizeof(int)))) exit(OVERFLOW);
    CS.top = CS.base;
    return CS;
}

BiTree *StackCopyBinaryTree(BiTree *root) {
    // 注意複製時,操作的都是樹節點的指標,
    // 在佇列中儲存的都是樹節點的指標
    QueueTree Q1, Q2;
    BiTree *middle, *root_copy, *middle_copy;
    if (!root) {
        return NULL;
    }
    Q1 = InitQueueTree(20);
    Q2 = InitQueueTree(20);
    if (!(middle_copy = root_copy = (BiTree *) malloc(sizeof(BiTree)))) exit(OVERFLOW);
    middle = root;
    ENQueueTree(&Q1, root);
    ENQueueTree(&Q2, root_copy);
    while (Q1.tag != 0) {
        DEQueueTree(&Q1, &middle);
        DEQueueTree(&Q2, &middle_copy);
        middle_copy->data = middle->data;
        if (middle->leftChild) {
            if (!(middle_copy->leftChild = (BiTree *) malloc(sizeof(BiTree)))) exit(OVERFLOW);
            ENQueueTree(&Q1, middle->leftChild);
            ENQueueTree(&Q2, middle_copy->leftChild);
        }
        if (middle->rightChild) {
            if (!(middle_copy->rightChild = (BiTree *) malloc(sizeof(BiTree)))) exit(OVERFLOW);
            ENQueueTree(&Q1, middle->rightChild);
            ENQueueTree(&Q2, middle_copy->rightChild);
        }
    }
    return root_copy;
}