美文网首页
二叉搜索树的升级版

二叉搜索树的升级版

作者: pengtoxen | 来源:发表于2018-07-06 14:08 被阅读0次

    二叉树存在的问题

    1. 在二叉树中,子节点的左孩子或者右孩子为NULL,或者两者都为空,有点浪费空间(一个空指针浪费了一个字长的内存空间)
    2. 已知1个包含NULL指针的节点,是否可以找到他的前驱或者后驱?

    聪明的前人就想到了方法来利用这些NULL指针.那是怎么利用的呢?

    typedef enum {Link, Thread} PointerTag;
    
    typedef struct node {
        int data;
        struct node *left; //左指针
        struct node *right; //右指针
        PointerTag Ltag; //左标记
        PointerTag Rtag; //右标记
    } Node;
    

    将节点的数据格式更改为上面的结构体,一个节点除了左右孩子指针,还多了两个标记为LtagRtag.对于左孩子来说,如果左孩子不为空,则Ltag = Link,表示是孩子元素;如果是左孩子为空,则Ltag = Thread,表明左孩子存的是(前驱元素的指针),右孩子同理.这样我们就把这些NULL指针利用了起来,给定一个节点,可以知道他的前驱或者后驱元素,对于遍历是方便的事情.

    #include <stdio.h>
    #include<stdlib.h>
    
    //Link=0表示指向左节点,Thread=1表示指向前驱或者后驱
    typedef enum {Link, Thread} PointerTag;
    
    typedef struct node {
        int data;
        struct node *left; //左指针
        struct node *right; //右指针
        PointerTag Ltag; //左标记
        PointerTag Rtag; //有标记
    } Node;
    
    Node *insert(Node *node, int data, int leaf);//leaf=0插入左节点,leaf=1插入右节点
    Node *newNode(int data);//创建节点
    void initHead(Node *head, Node *root);//初始化头结点
    void initInOrder(Node *node);//中序遍历线索化
    void inOrder(Node *head);//中序遍历二叉树
    
    //全局变量,保存遍历后之前的节点
    Node *pre;
    
    int main(void) {
        //创建二叉树
        Node *root = insert(NULL, 100, 0);
        insert(root, 20, 0);
        insert(root, 150, 0);
        insert(root, 160, 1);
        //初始化头结点
        Node *head;
        initHead(head, root);
        //遍历第一个节点,是没有前驱的
        pre = head;
        initInOrder(root);
        pre->Rtag = Thread;
        pre->right = head;
        inOrder(head);
        postOrder(head);
        return 0;
    }
    
    Node *insert(Node *node, int data, int leaf) {
        if(node == NULL) {
            return newNode(data);
        }
        if(leaf == 0) {
            node->left = insert(node->left, data, leaf);
        } else {
            node->right = insert(node->right, data, leaf);
        }
        return node;
    }
    
    Node *newNode(int data) {
        Node *root = (Node *)malloc(sizeof(Node));
        root->data = data;
        root->left = NULL;
        root->right = NULL;
        root->Ltag = Link;
        root->Rtag = Link;
        return root;
    }
    
    void initHead(Node *head, Node *root) {
        head->left = root;
        head->right = head;
        head->Ltag = Link;
        head->Rtag = Link;
    }
    
    void initInOrder(Node *node) {
        if(node == NULL) {
            return;
        }
        initInOrder(node->left);
        if(node->left == NULL) {
            node->Ltag = Thread;
            node->left = pre;
        }
        if(pre->right == NULL) {
            pre->Rtag = Thread;
            pre->right = node;
        }
        pre = node;
        initInOrder(node->right);
    }
    
    void inOrder(Node *head) {
        Node *cur = head->left;
        while(cur != head) {
            while(cur->Ltag == Link) {
                cur = cur->left;
            }
            printf("%d\n", cur->data);
            while(cur->Rtag == Thread && cur->right != head) {
                cur = cur->right;
                printf("%d\n", cur->data);
            }
            cur = cur->right;
        }
    }
    

    相关文章

      网友评论

          本文标题:二叉搜索树的升级版

          本文链接:https://www.haomeiwen.com/subject/mhovuftx.html