[数据结构] 二叉树基础

Python实现
"""
    Pre-order, in-order and post-order traversal of binary trees.

    Author: Wenru Dong
"""
from typing import TypeVar, Generic, Generator, Optional

T = TypeVar("T")

class TreeNode(Generic[T]):
    def __init__(self, value: T):
        self.val = value
        self.left = None
        self.right = None
    

# Pre-order traversal
def pre_order(root: Optional[TreeNode[T]]) -> Generator[T, None, None]:
    if root:
        yield root.val
        yield from pre_order(root.left)
        yield from pre_order(root.right)

# In-order traversal
def in_order(root: Optional[TreeNode[T]]) -> Generator[T, None, None]:
    if root:
        yield from in_order(root.left)
        yield root.val
        yield from in_order(root.right)

# Post-order traversal
def post_order(root: Optional[TreeNode[T]]) -> Generator[T, None, None]:
    if root:
        yield from post_order(root.left)
        yield from post_order(root.right)
        yield root.val


if __name__ == "__main__":

    singer = TreeNode("Taylor Swift")

    genre_country = TreeNode("Country")
    genre_pop = TreeNode("Pop")

    album_fearless = TreeNode("Fearless")
    album_red = TreeNode("Red")
    album_1989 = TreeNode("1989")
    album_reputation = TreeNode("Reputation")

    song_ls = TreeNode("Love Story")
    song_wh = TreeNode("White Horse")
    song_wanegbt = TreeNode("We Are Never Ever Getting Back Together")
    song_ikywt = TreeNode("I Knew You Were Trouble")
    song_sio = TreeNode("Shake It Off")
    song_bb = TreeNode("Bad Blood")
    song_lwymmd = TreeNode("Look What You Made Me Do")
    song_g = TreeNode("Gorgeous")

    singer.left, singer.right = genre_country, genre_pop
    genre_country.left, genre_country.right = album_fearless, album_red
    genre_pop.left, genre_pop.right = album_1989, album_reputation
    album_fearless.left, album_fearless.right = song_ls, song_wh
    album_red.left, album_red.right = song_wanegbt, song_ikywt
    album_1989.left, album_1989.right = song_sio, song_bb
    album_reputation.left, album_reputation.right = song_lwymmd, song_g

    print(list(pre_order(singer)))
    print(list(in_order(singer)))
    print(list(post_order(singer)))

java实现
public class BinarySearchTree {
  private Node tree;

  public Node find(int data) {
    Node p = tree;
    while (p != null) {
      if (data < p.data) p = p.left;
      else if (data > p.data) p = p.right;
      else return p;
    }
    return null;
  }
  
  public void insert(int data) {
    if (tree == null) {
      tree = new Node(data);
      return;
    }

    Node p = tree;
    while (p != null) {
      if (data > p.data) {
        if (p.right == null) {
          p.right = new Node(data);
          return;
        }
        p = p.right;
      } else { // data < p.data
        if (p.left == null) {
          p.left = new Node(data);
          return;
        }
        p = p.left;
      }
    }
  }

  public void delete(int data) {
    Node p = tree; // p指向要删除的节点,初始化指向根节点
    Node pp = null; // pp记录的是p的父节点
    while (p != null && p.data != data) {
      pp = p;
      if (data > p.data) p = p.right;
      else p = p.left;
    }
    if (p == null) return; // 没有找到

    // 要删除的节点有两个子节点
    if (p.left != null && p.right != null) { // 查找右子树中最小节点
      Node minP = p.right;
      Node minPP = p; // minPP表示minP的父节点
      while (minP.left != null) {
        minPP = minP;
        minP = minP.left;
      }
      p.data = minP.data; // 将minP的数据替换到p中
      p = minP; // 下面就变成了删除minP了
      pp = minPP;
    }

    // 删除节点是叶子节点或者仅有一个子节点
    Node child; // p的子节点
    if (p.left != null) child = p.left;
    else if (p.right != null) child = p.right;
    else child = null;

    if (pp == null) tree = child; // 删除的是根节点
    else if (pp.left == p) pp.left = child;
    else pp.right = child;
  }

  public Node findMin() {
    if (tree == null) return null;
    Node p = tree;
    while (p.left != null) {
      p = p.left;
    }
    return p;
  }

  public Node findMax() {
    if (tree == null) return null;
    Node p = tree;
    while (p.right != null) {
      p = p.right;
    }
    return p;
  }
  
  public static class Node {
    private int data;
    private Node left;
    private Node right;

    public Node(int data) {
      this.data = data;
    }
  }
}

C++实现
/*************************************************************************
 > Author: 
 > Mail:    
 > Time:    2020-08-22
 > Desc:    二叉搜索树实现
 ************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef char ElemType;

typedef struct node {
    ElemType data;
    struct node *lchild, *rchild;
} BTree, *BTreePtr;

/**************** 插入 **********************/
Status Insert(BTreePtr *T, ElemType e) {

    BTreePtr p;

    if (*T == NULL) {
        *T = (BTreePtr)malloc(sizeof(BTree));
        (*T)->data = e;

        return TRUE;
    } else {
        p = *T;
        while ( p != NULL) {

            if (e > p->data) {

                if (p->rchild == NULL) {
                    p->rchild = (BTreePtr) malloc (sizeof(BTree));
                    p->rchild->data = e;
                    return TRUE;
                }
                p = p->rchild;
            } else {

                if (p->lchild == NULL)
                {
                    p->lchild = (BTreePtr) malloc (sizeof(BTree));
                    p->lchild->data = e;
                    return TRUE;
                }
                p = p->lchild;
            }
        }
    }

    return FALSE;
}

/**************** 删除 **********************/
Status Delete(BTreePtr T, ElemType e) {
    BTreePtr p, pp, minP, minPP, child;
    child = NULL;
    p = T;
    pp = NULL;

    while ( (p != NULL) && (p->data != e) ) {
        pp = p;

        if (e > p->data) {
            p = p->rchild;
        } else {
            p = p->lchild;
        }
    }

    if (p == NULL) return FALSE;

    //双节点
    if ((p->lchild != NULL) && (p->rchild != NULL))
    {
        minPP = p;
        minP = p->rchild;

        while (minP->lchild != NULL) {
            minPP = minP;
            minP = minP->lchild;
        }
        p->data = minP->data;
        minPP->lchild = minP->rchild;
        free(minP);

        return TRUE;
    }

    //有一个节点
    if ((p->lchild != NULL) || (p->rchild != NULL)) { //应该将原有的pp同child连接在一起

        if (p->lchild) {
            child = p->lchild;
        } else {
           child = p->rchild;
        }
        if(pp->data>p->data)
        {
            pp->lchild=child;
        } else
        {
            pp->rchild=child;
        }
        free(p);
        return TRUE;
    }

    //没有节点
    if (pp->lchild == p) {//这里面临pp除p以外的节点为null的情况
        pp->lchild = child;
    } else {
        pp->rchild = child;
    }

    return TRUE;
}

/**************** 查找 **********************/

Status Find(BTreePtr T, ElemType e) {

    if (T == NULL) return FALSE;

    while ((T != NULL) && (T->data != e)) {

        if (e > T->data) {
            T = T->rchild;
        } else {
            T = T->lchild;
        }
    }

    if (T) {
        return TRUE;
    } else {
        return FALSE;
    }
}


/**************** 最大值 **********************/
ElemType FindMax(BTreePtr T) {
    ElemType max;

    while(T != NULL) {
        max = T->data;
        T = T->rchild;
    }
    return max;
}


/**************** 最小值 **********************/
ElemType FindMin(BTreePtr T) {
    ElemType min;

    while(T != NULL) {
        min = T->data;
        T = T->lchild;
    }
    return min;
}


void PreOrderTraverse(BTreePtr T)//前序遍历二叉树
{
    if (T == NULL) return;

    if(T)
    {
        printf("%d ",T->data);
        PreOrderTraverse(T->lchild);
        PreOrderTraverse(T->rchild);
    }
}


void DestroyTree(BTreePtr T) {
    if (T)
    {
        if (T->lchild)
        {
            DestroyTree(T->lchild);
        }

        if(T->rchild)
        {
            DestroyTree(T->rchild);
        }

        free(T);
        T = NULL;
    }
}

/***************** 执行测试 *************************/
int main(int argc, char const *argv[])
{
    BTreePtr T;
    T = NULL;
    int a[] = {33, 16, 50, 13, 18, 34, 58, 15, 17, 25, 51, 66, 19, 27, 55};
    int i;
    for (i = 0; i < 15; i++) {
        Insert(&T, a[i]);
    }
    printf("Max is %d\n", FindMax(T));
    printf("Min is %d\n", FindMin(T));
    Delete(T, 18);
    Delete(T, 13);
    PreOrderTraverse(T);
    DestroyTree(T);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值