首页 > 技术文章 > 中国大学MOOC_浙大数据结构_第四周编程作业

xkxf 2020-09-01 15:56 原文

第四周编程作业

是否同一棵二叉搜索树

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAX 10 + 1

typedef struct _BinTree* BinTree; 
struct _BinTree {
    int val;
    BinTree left;
    BinTree right;    
};
typedef BinTree Node; 

BinTree insert(BinTree bst, int val)
{
    if (bst == NULL) {
        bst = (BinTree) malloc(sizeof(struct _BinTree));
        bst->left = bst->right = NULL;
        bst->val = val;
    } else {
        if (val < bst->val) {
            bst->left = insert(bst->left, val);
            // 只有栈顶的调用用到了返回值
            // 其余调用则是把自己赋给自己             
        } else {
            bst->right = insert(bst->right, val);
        }
    }
    return bst;
}

// 保存初始插入序列的先序遍历 
int preOrder[MAX];
int index = 0;
void preOrderTraversal(BinTree root)
{
    if (root) {
        preOrder[index++] = root->val;
        preOrderTraversal(root->left);
        preOrderTraversal(root->right);        
    }
}

// 保存需要检查的先序遍历
int preOrder2[MAX];
int index2 = 0;
void preOrderTraversalTwo(BinTree root)
{
    if (root) {
        preOrder2[index2++] = root->val;
        preOrderTraversalTwo(root->left);
        preOrderTraversalTwo(root->right);        
    }
}

bool check(int N)
{
    for (int i = 0; i != N; ++i) {
        if (preOrder[i] != preOrder2[i]) return false;
    }
    return true;
}

void freeTree(BinTree root)
{
    if (root->left) freeTree(root->left);
    if (root->right) freeTree(root->right);
    free(root);
}

int main()
{
    BinTree root;
    
    int N, L, temp;
    
    while (true) {
        scanf("%d", &N);
        if (N == 0) break;
        scanf("%d", &L);
        
        // 1. 读入初始插入序列 
        root = NULL;
        index = 0;
        for (int i = 0; i != N; ++i) {
            scanf("%d", &temp);
            root = insert(root, temp);
        }
        preOrderTraversal(root);
        freeTree(root);
        
        for (int i = 0; i != L; ++i) {
            // 2. 读入需检查的序列 
            root = NULL;
            index2 = 0;
            for (int i = 0; i != N; ++i) {
                scanf("%d", &temp);
                root = insert(root, temp);
            }        
            preOrderTraversalTwo(root);
            freeTree(root);
            printf("%s\n", check(N) ? "Yes" : "No");                
        }
    }
        
    return 0;
}

 

Root of AVL Tree

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef struct _BinTree* BinTree; 
struct _BinTree {
    int val;
    BinTree left;
    BinTree right;   
    
    int height; 
};
typedef BinTree Node; 

Node createAVLNode(int val)
{
    Node result = (Node) malloc(sizeof(struct _BinTree));
    result->val = val;
    result->left = result->right = NULL;
    
    result->height = 1;
    
    return result;
}

int getH(BinTree bst)
{
    if (bst) {
        return bst->height;
    }
    return 0;
}

int maxH(BinTree bst1, BinTree bst2)
{
    int h1, h2;
    h1 = getH(bst1);
    h2 = getH(bst2);
    return h1 > h2 ? h1 : h2;
}

int getBF(BinTree bst)
{
    // get balance factor
    return getH(bst->left) - getH(bst->right);
}

BinTree solveLL(BinTree oldRoot)
{
    BinTree newRoot = oldRoot->left;
    // 中序不变,改变结构
    oldRoot->left = newRoot->right;
    newRoot->right = oldRoot;
    
    oldRoot->height = maxH(oldRoot->left, oldRoot->right) + 1; // oldRoot变为儿子需要先更新     
    newRoot->height = maxH(newRoot->left, newRoot->right) + 1;
    
    return newRoot;
}

BinTree solveRR(BinTree oldRoot)
{
    BinTree newRoot = oldRoot->right;
    // 中序不变,改变结构
    oldRoot->right = newRoot->left;
    newRoot->left = oldRoot;
    
    oldRoot->height = maxH(oldRoot->left, oldRoot->right) + 1;      
    newRoot->height = maxH(newRoot->left, newRoot->right) + 1;
    
    return newRoot;
}

BinTree solveLR(BinTree oldRoot)
{
    oldRoot->left = solveRR(oldRoot->left);
    return solveLL(oldRoot);
}

BinTree solveRL(BinTree oldRoot)
{
    oldRoot->right = solveLL(oldRoot->right);
    return solveRR(oldRoot);
}

BinTree AVLInsert(BinTree bst, int val)
{
    if (!bst) {
        bst = createAVLNode(val);
    }
    
    if (val < bst->val) {
        bst->left = AVLInsert(bst->left, val);
        if (getBF(bst) == 2) {
            // 当前结点即是“问题的发现者” 
            if (val < bst->left->val) {
                // LL型不平衡 
                bst = solveLL(bst);
            } else {
                // LR型不平衡 
                bst = solveLR(bst);
            }
        }
    } else if (val > bst->val) {
        bst->right = AVLInsert(bst->right, val);
        if (getBF(bst) == -2) {
            if (val > bst->right->val) {
                // RR型不平衡 
                bst = solveRR(bst);
            } else {
                // RL型不平衡 
                bst = solveRL(bst);
            }            
        }
    }
    
    bst->height = maxH(bst->left, bst->right) + 1;
    // 无需再递归计算,在递归插入元素的同时计算即可。 
    
    return bst;
}

int main()
{
    int N, temp;    
    
    BinTree root = NULL;
    scanf("%d", &N);
    while (N--) {
        scanf("%d", &temp);
        root = AVLInsert(root, temp);
    }
    printf("%d", root->val);
    
    return 0;
}

 

Complete Binary Search Tree

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define MAXN 1000 + 1

int keys[MAXN];

int partition(int arr[], int i, int j);
void myQsort(int arr[], int i, int j);

typedef struct _BSTNode* BSTNode;
struct _BSTNode {
    int val;
    BSTNode left;
    BSTNode right;    
};

BSTNode createBSTNode(int val);
BSTNode createCBT(int N); // 创建一个具有N个空结点的完全二叉树 

typedef struct _QNode* QNode;
struct _QNode {
    BSTNode bstNode;
    QNode next;
};

QNode createQNode(BSTNode bstNode);
bool isEmpty(QNode head);
void addQ(QNode head, BSTNode bstNode);
BSTNode deleteQ(QNode head);
void freeQ(QNode node);

QNode inorderQueue;
void inorderTraversal(BSTNode root)
{
    if (root) {
        inorderTraversal(root->left);
        addQ(inorderQueue, root);
        inorderTraversal(root->right);
    }    
}

void levelorderTraversal(BSTNode root)
{
    if (root) {    
        printf("%d", root->val);        
        
        QNode head = createQNode(NULL);    
        if (root->left) {
            addQ(head, root->left);
        }
        if (root->right) {
            addQ(head, root->right);
        }    
            
        BSTNode temp;
        while (!isEmpty(head)) {
            temp = deleteQ(head);
            printf(" %d", temp->val);
            if (temp->left) {
                addQ(head, temp->left);
            }
            if (temp->right) {
                addQ(head, temp->right);
            }            
        }
    }    
}

int main()
{
    int N;

    scanf("%d", &N);
    for (int i = 0; i != N; ++i) {
        scanf("%d", &keys[i]);
    }
    
    myQsort(keys, 0, N - 1);
    
    BSTNode root = createCBT(N);
    
    inorderQueue = createQNode(NULL);
    inorderTraversal(root); // 结果保存到inorderQueue 
    for (int i = 0; i != N; ++i) {
        deleteQ(inorderQueue)->val = keys[i];
    }
    
    levelorderTraversal(root);
    
    return 0;
}

int partition(int arr[], int i, int j)
{
    int x = arr[i];
    
    while (i < j) {
        while (arr[j] >= x && i < j) j--;
        arr[i] = arr[j];
        while (arr[i] <= x && i < j) i++;
        arr[j] = arr[i];        
    }
    
    arr[i] = x;
    
    return i;
}

void myQsort(int arr[], int i, int j)
{
    if (i >= j) {
        return;
    } else {
        int mid = partition(arr, i, j);
        myQsort(arr, i, mid);
        myQsort(arr, mid + 1, j);
    }
}

BSTNode createBSTNode(int val)
{
    BSTNode result = (BSTNode) malloc(sizeof(struct _BSTNode));
    result->val = val;
    result->left = result->right = NULL;
    
    return result;
}

BSTNode createCBT(int N)
{
    BSTNode root, newNode, parent;
    QNode head = createQNode(NULL);
    
    parent = root = createBSTNode(-1);
    
    for (int i = 1; i != N; ++i) {
        // 1. 创建新结点 
        newNode = createBSTNode(-1);
        
        // 2. 更新parent 
        if (parent->left && parent->right) {
            parent = deleteQ(head);
        }
        
        // 3. 放新结点 
        if (parent->left) {
            parent->right = newNode;
        } else {
            parent->left = newNode;
        }    
        
        // 4. 新结点入队 
        addQ(head, newNode);
    }
    
    freeQ(head);
    
    return root;
}

QNode createQNode(BSTNode bstNode)
{
    QNode result = (QNode) malloc(sizeof(struct _QNode));
    result->bstNode = bstNode;
    result->next = NULL;
    
    return result;    
}

bool isEmpty(QNode head)
{
    return head->next == NULL;
}

void addQ(QNode head, BSTNode bstNode)
{
    QNode temp = head;
    while (temp->next) {
        temp = temp->next;
    }
    temp->next = createQNode(bstNode);
}

BSTNode deleteQ(QNode head)
{
    if (isEmpty(head)) return NULL;
    
    QNode temp = head->next;
    head->next = temp->next;
    BSTNode bstNode = temp->bstNode;
    free(temp);
    
    return bstNode;
}

void freeQ(QNode node)
{
    if (node) {
        freeQ(node->next);
        free(node);
    }
}

 

二叉搜索树的操作集

BinTree createNode(ElementType x)
{
    BinTree bt = (BinTree) malloc(sizeof(struct TNode));
    bt->Left = bt->Right = NULL;
    bt->Data = x;
    
    return bt;
}

BinTree Insert( BinTree BST, ElementType X )
{
    if (BST == NULL) {
        BST = createNode(X);
    } else {
        if (X < BST->Data) {
            BST->Left = Insert(BST->Left, X);
        } else if (X > BST->Data) {
            BST->Right = Insert(BST->Right, X);
        }
    }
    return BST;
}

Position Find( BinTree BST, ElementType X )
{
    while (BST) {
        if (X > BST->Data) {
            BST = BST->Right;
        } else if (X < BST->Data) {
            BST = BST->Left;
        } else {
            break;
        }
    }
    
    return BST;
}

Position FindMin( BinTree BST )
{
    if (BST) {
        while (BST->Left) {
            BST = BST->Left;
        }
    }
    
    return BST;    
}

Position FindMax( BinTree BST )
{
    if (BST) {
        while (BST->Right) {
            BST = BST->Right;
        }
    }
    
    return BST;
}


BinTree Delete( BinTree BST, ElementType X )
{
    Position temp;
    if (BST == NULL) {
        printf("Not Found\n");
    } else {
        if (X < BST->Data) {
            BST->Left = Delete(BST->Left, X);
        } else if (X > BST->Data) {
            BST->Right = Delete(BST->Right, X);
        } else {
            if (BST->Left && BST->Right) {
                temp = FindMin(BST->Right);
                BST->Data = temp->Data;
                BST->Right = Delete(BST->Right, BST->Data);
            } else {
                temp = BST;
                if (BST->Left) {
                    BST = BST->Left;
                } else {
                    BST = BST->Right;
                }
                free(temp);
            }
        }
    }
    
    return BST;
}

 

推荐阅读