一、 实验目的
1. 掌握二叉树逻辑结构;
2. 掌握利用C/C++编程语言实现数据结构的编程方法;
3. 通过上机时间加强利用数据结构解决实际应用问题的能力;
二、 实验相关知识
1. 二叉树的二叉链表存储结构的实现;
2. 二叉树排序树的定义;
3. 二叉排序树的插入、构建、删除;
4. 二叉排序树的中序遍历。
三、 实验内容与要求
实现二叉排序树的结点插入、构建、遍历和元素删除( 已经提供结点删除函数实现)
四、 实现过程与结构
#include <stdio.h> #include <string.h> #include <algorithm> typedef char ElemType; //二叉链表中结点元素类型 typedef struct BiTNode { ElemType data; struct BiTNode* lchild, *rchild; }BiTNode, *BiTree; //二叉链表的类型定义 BiTree CreateBiTree();// 利用先序遍历创建二叉树,返回根指针。 void InOrder(BiTree T);// 二叉树的中序遍历,参数:二叉树根指针T,输出:中间没有空格,末尾不换行。 int InsertNode(BiTree& T, ElemType x);//二叉排序树的插入 BiTree CreateBiTree()// 利用先序遍历创建二叉树,返回根指针。 { //补充代码 BiTree T = NULL; int i, n, x; printf_s("输入元素的个数n和n个元素: "); scanf_s("%d:", &n); for (int i = 0; i < n; i++) { scanf_s("%d", &x); InsertNode(T, x); } return T; } int InsertNode(BiTree &T, ElemType x)//二叉排序树的插入 { //补充代码 if (T == NULL) { T = (BiTNode*)malloc(sizeof(BiTNode)); T->data = x; T->rchild = NULL; T->lchild = NULL; } else { if (T->data == x)return 0; if (T->data < x) InsertNode(T->rchild, x); else InsertNode(T->lchild, x); } return 1; } void InOrder(BiTree T) // 中序遍历 { //补充代码 if (T != NULL) { InOrder(T->lchild); printf_s("%d ",T->data); InOrder(T->rchild); } } BiTNode* find(BiTree& T, ElemType x) { if (T == NULL) return NULL; if (T->data == x) return T; else { if (x < T->data) return find(T->lchild, x); else return find(T->rchild, x); } } int Delete(BiTree &p) { BiTree q, s; //情况 1,结点 p 本身为叶子结点,直接删除即可 if (p->lchild == NULL && p->rchild == NULL) { free(p); p = NULL; return 1; } if (p->lchild == NULL) { //左子树为空,右子树非空,只需用结点 p 的右子树根结点代替结点 p 即可; q = p; p = p->rchild; free(q); return 1; } else if (p->rchild == NULL) {//右子树为空,左子树非空,只需用结点 p 的左子树根结点代替结点 p 即可; q = p; p = p->lchild;//这里不是指针 p 指向左子树,而是将左子树存储的结点的地址赋值给指针变量 p free(q); } else {//左右子树均不为空,采用第 2 种方式 q = p; s = p->lchild; //遍历,找到结点 p 的直接前驱 while (s->rchild) { q = s; s = s->rchild; } //直接改变结点 p 的值 p->data = s->data; //判断结点 p 的左子树 s 是否有右子树,分为两种情况讨论 if (q != p) { q->rchild = s->lchild;//若有,则在删除直接前驱结点的同时,令前驱的左孩子结点改为 q 指向结点的孩子结点 } else { q->lchild = s->lchild;//否则,直接将左子树上移即可 } free(s); } return 1; } int DeleteBST(BiTree &T, int key) { if (!T) {//不存在关键字等于key的数据元素 return 0; } else { if (key == T->data) { Delete(T); return 1; } else if (key < T->data) { //使用递归的方式 return DeleteBST(T->lchild, key); } else { return DeleteBST(T->rchild, key); } } } int main() { BiTree T; T = CreateBiTree(); while (1) { printf_s("请选择选项 1.插入元素 2.删除元素 其他.结束程序 "); InOrder(T); printf_s(" "); int seleted; scanf_s("%d", &seleted); switch (seleted) { case 1: { int x; printf_s("输入插入的元素x="); scanf_s("%d", &x); if (InsertNode(T, x) > 0) printf_s("插入成功"); else printf_s("元素重复,放弃插入"); InOrder(T); printf_s(" "); break; } case 2: { int x; printf_s("输入删除的元素x="); scanf_s("%d", &x); if (DeleteBST(T, x) > 0) printf_s("删除成功"); else printf_s("元素不存在,放弃删除"); InOrder(T); printf_s(" "); break; } default:return 1; } } }