王道考研 ++++ 二叉排序树(C语言 链表)

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

typedef struct LTree
{
  int data;
  struct LTree *Lchild,*Rchild;
}LTree,*BiTree;

void InsertTree(BiTree *T,int number);
void Traversal(BiTree T);
void SearchElement(BiTree T,int number);
bool Delete(BiTree *p);
bool DeleteElement(BiTree *T,int number);
/*插入节点*/
void InsertTree(BiTree *T,int number)
{
  /*当节点为空时插入*/
  if(*T == NULL)
  {
    (*T) = (BiTree)malloc(sizeof(LTree));
    (*T)->data = number;
    (*T)->Lchild = (*T)->Rchild = NULL;//置左右节点子节点为空
    return ;
  }
  else if(number == (*T)->data)//树中已经存在值相同的节点
    return;//结束
  else if(number < (*T)->data)//元素小于当前节点向左子树走
    InsertTree(&(*T)->Lchild,number);
  else if(number > (*T)->data)//元素大于当前节点向右子树走
    InsertTree(&(*T)->Rchild,number);
}
/*中序遍历*/
void Traversal(BiTree T)
{
  if(T == NULL)return;
  Traversal(T->Lchild);
  printf("%d ",T->data);
  Traversal(T->Rchild);
}
/*查找元素*/
void SearchElement(BiTree T,int number)
{
  //当遍历到NULL(代表没找到节点)或 找到与树中与查找元素相同的节点时 结束查找
  while (T != NULL && T->data != number)
  {
    if(number < T->data)T = T->Lchild;//元素小于节点的值 向左走
    else T = T->Rchild;//否则 向右走
  }

  if(T == NULL)printf("没有此数!\n");
  else printf("查找成功!\n");
}
/*从二叉排序树中删除结点 p , 并重接它的左/右子树*/
bool Delete(BiTree *p){
    BiTree q, s;

    if ((*p)->Rchild == NULL)
   {  // 右子树空 则只需要重接它的左子树
        q = *p;
        *p = (*p)->Lchild;
        free(q);

    }
    else if ((*p)->Lchild == NULL)
    {  // 左子树空 则只需要重接它的右子树
        q = *p;
        *p = (*p)->Rchild;
        free(q);

    }
    else
    {  // 左右子树都不空
        q = *p;
        s = (*p)->Lchild;
        while (s->Rchild)
        {  // 向右到尽头,找到待删结点的前驱
            q = s;
            s = s->Rchild;
        }
        (*p)->data = s->data;  // s 指向被删除结点的直接前驱 (将被删结点前驱的值取代被删结点的值)
        if (q != *p)
            q->Rchild = s->Lchild;  // 重接 q 的右子树
        else
            q->Lchild = s->Lchild;  // 重接 q 的左子树
        free(s);
    }

    return true;
}

/**
 * 二叉排序树的删除
 * 当二叉排序树中存在关键字等于 number 的数据元素时,删除该数据元素并返回TRUE
 */
bool DeleteElement(BiTree *T, int number){
    if (!*T)return false;
    else
    {
        if (number == (*T)->data)
            Delete(T);
        else if (number < (*T)->data)
            DeleteElement(&(*T)->Lchild, number);
        else
            DeleteElement(&(*T)->Rchild, number);
    }
}
int main(int argc, char const *argv[]) {
  BiTree T = NULL;
  int number;

  printf("请输入数字,-1结束:");
  scanf("%d",&number);
  while (number != -1)
  {
    InsertTree(&T,number);
    scanf("%d",&number);
  }
  printf("中序遍历:");
  Traversal(T);
  printf("\n请输入查找数字:");
  scanf("%d",&number);
  SearchElement(T,number);
  printf("请输入删除数字:");
  scanf("%d",&number);
  DeleteElement(&T,number);
  printf("删后遍历:");
  Traversal(T);
  printf("\n");
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉排序树转换为有序的双向链表C语言实现: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构体 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 定义双向链表节点结构体 typedef struct ListNode { int val; struct ListNode *prev; struct ListNode *next; } ListNode; // 将二叉排序树转换为有序的双向链表 ListNode* treeToList(TreeNode* root) { if (root == NULL) { return NULL; } // 将左子树转换为有序的双向链表 ListNode *leftList = treeToList(root->left); // 将右子树转换为有序的双向链表 ListNode *rightList = treeToList(root->right); // 创建当前节点的双向链表节点 ListNode *curNode = (ListNode*)malloc(sizeof(ListNode)); curNode->val = root->val; curNode->prev = NULL; curNode->next = NULL; // 将左子树的双向链表和当前节点连接起来 if (leftList != NULL) { ListNode *leftTail = leftList; while (leftTail->next != NULL) { leftTail = leftTail->next; } leftTail->next = curNode; curNode->prev = leftTail; } else { leftList = curNode; } // 将右子树的双向链表和当前节点连接起来 if (rightList != NULL) { rightList->prev = curNode; curNode->next = rightList; } return leftList; } // 创建二叉树节点 TreeNode* createNode(int val) { TreeNode *node = (TreeNode*)malloc(sizeof(TreeNode)); node->val = val; node->left = NULL; node->right = NULL; return node; } // 插入节点到二叉排序树中 TreeNode* insertNode(TreeNode *root, int val) { if (root == NULL) { return createNode(val); } if (val < root->val) { root->left = insertNode(root->left, val); } else { root->right = insertNode(root->right, val); } return root; } // 中序遍历二叉树 void inorderTraversal(TreeNode *root) { if (root == NULL) { return; } inorderTraversal(root->left); printf("%d ", root->val); inorderTraversal(root->right); } // 打印双向链表 void printList(ListNode *head) { ListNode *curNode = head; while (curNode != NULL) { printf("%d ", curNode->val); curNode = curNode->next; } printf("\n"); } int main() { // 创建二叉排序树 TreeNode *root = NULL; root = insertNode(root, 5); insertNode(root, 3); insertNode(root, 7); insertNode(root, 2); insertNode(root, 4); insertNode(root, 6); insertNode(root, 8); // 中序遍历二叉树 printf("Inorder traversal of binary search tree:\n"); inorderTraversal(root); printf("\n"); // 将二叉排序树转换为有序的双向链表 ListNode *head = treeToList(root); // 打印双向链表 printf("Doubly linked list:\n"); printList(head); return ; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值