二叉排序树各类算法实现
Posted cjj2503
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉排序树各类算法实现相关的知识,希望对你有一定的参考价值。
数据结构----二叉排序树各类算法实现
实现如下排序二叉树算法:
(1)创建排序二叉树
(2)排序二叉树插入算法
(3)排序二叉树删除算法
(4)排序二叉树查找算法
测试数据说明:
201 456 333 556 784 345 204 450 673 677
431 321 999 822 745 777 564 202 354 611
278 398 411 833 923 222 335 444 501 512
536 721 288 377 388 395 572 655 943 675
294 368 794 561 532 455 821 937 955 518
-1 //以上为排序二叉树存储的数据,以-1结尾
431 //查找的数据元素
1000 //查找的数据元素
201 //要删除的数据元素
556 //要删除的数据元素
input.txt
201 456 333 556 784 345 204 450 673 677
431 321 999 822 745 777 564 202 354 611
278 398 411 833 923 222 335 444 501 512
536 721 288 377 388 395 572 655 943 675
294 368 794 561 532 455 821 937 955 518
-1
431
1000
201
556
output.txt
The result of in order travel of the sort BiTree is:
201 202 204 222 278 288 294 321 333 335
345 354 368 377 388 395 398 411 431 444
450 455 456 501 512 518 532 536 556 561
564 572 611 655 673 675 677 721 745 777
784 794 821 822 833 923 937 943 955 999
the data 431 exists!
the data 1000 does not exists!
The result of in order travel after deleting the data 201:
202 204 222 278 288 294 321 333 335 345
354 368 377 388 395 398 411 431 444 450
455 456 501 512 518 532 536 556 561 564
572 611 655 673 675 677 721 745 777 784
794 821 822 833 923 937 943 955 999
The result of in order travel after deleting the data 556:
202 204 222 278 288 294 321 333 335 345
354 368 377 388 395 398 411 431 444 450
455 456 501 512 518 532 536 561 564 572
611 655 673 675 677 721 745 777 784 794
821 822 833 923 937 943 955 999
代码部分
BiSortTree.h
#ifndef BISORTTREE_H
#define BISORTTREE_H
typedef int DataType;
typedef struct node{
DataType data;
struct node *leftChild;
struct node *rightChild;
} BiTreeNode;
BiTreeNode * createTree(DataType datas[], int n);
int Insert(BiTreeNode **root, DataType item);
int Delete(BiTreeNode **root, DataType item);
BiTreeNode* Search(BiTreeNode *root, DataType item);
void InOrder(BiTreeNode *root,DataType data[], int *n);
#endif
BiSortTree.c
#include "BiSortTree.h"
#include "malloc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//extern char errMessage[];
//初始化二叉树
void SearchTreeInit(BiTreeNode **root)
{
if (root == NULL) //非法输入
return;
*root = NULL;
}
BiTreeNode* CreateNewNode(DataType item)
{
BiTreeNode *root;
root = (BiTreeNode*)malloc(sizeof(BiTreeNode));
root->data= item;
root->leftChild = NULL;
root->rightChild = NULL;
return root;
}
//插入
int Insert(BiTreeNode **root, DataType item){
if (root == NULL)
{
return 0;
}
BiTreeNode * newnode = CreateNewNode(item);
if (*root == NULL) //空树
{
*root = newnode;
}
if ((*root)->data > item)
{
Insert(&(*root)->leftChild, item);
}
else if ((*root)->data<item)
{
Insert(&(*root)->rightChild , item);
}
}
//创建不带头结点的排序二叉树,datas中存放二叉排序树的所有数据,n为数组元素个数,返回值为创建的二叉排序树根结点指针
BiTreeNode* createTree(DataType datas[], int n) {
BiTreeNode* bt = NULL;
int i = 0;
while (i < n)
{
Insert(&bt, datas[i]);
i++;
}
return bt;
//补充代码
}
//删除函数
int Delete1(BiTreeNode **p)
{
BiTreeNode *q, *s;
//情况 1,结点 p 本身为叶子结点,直接删除即可
if (!(*p)->leftChild && !(*p)->rightChild) {
*p = NULL;
}
else if (!(*p)->leftChild) { //左子树为空,只需用结点 p 的右子树根结点代替结点 p 即可;
q = *p;
*p = (*p)->rightChild;
free(q);
}
else if (!(*p)->rightChild) {//右子树为空,只需用结点 p 的左子树根结点代替结点 p 即可;
q = *p;
*p = (*p)->leftChild;//这里不是指针 *p 指向左子树,而是将左子树存储的结点的地址赋值给指针变量 p
free(q);
}
else {//左右子树均不为空,采用第 2 种方式
q = *p;
s = (*p)->leftChild;
//遍历,找到结点 p 的直接前驱
while (s->rightChild)
{
q = s;
s = s->rightChild;
}
//直接改变结点 p 的值
(*p)->data = s->data;
//判断结点 p 的左子树 s 是否有右子树,分为两种情况讨论
if (q != *p) {
q->rightChild = s->leftChild;//若有,则在删除直接前驱结点的同时,令前驱的左孩子结点改为 q 指向结点的孩子结点
}
else {
q->leftChild = s->leftChild;//否则,直接将左子树上移即可
}
free(s);
}
}
int Delete(BiTreeNode **root, DataType item)
{
if (!(*root)) {//不存在关键字等于key的数据元素
return 0;
}
else
{
if (item == (*root)->data) {
Delete1(root);
return 1;
}
else if (item < (*root)->data) {
//使用递归的方式
return Delete(&(*root)->leftChild, item);
}
else {
return Delete(&(*root)->rightChild, item);
}
}
}
//在二叉排序树root上查找数据元素item是否存在, 如果找到则返回数据元素所在结点的指针,找不到则返回NULL
BiTreeNode* Search(BiTreeNode* root, DataType item) {
if (root == NULL || root->data == item)
{
return root;
}
if (item < root->data)
{
return Search(root->leftChild, item);
}
else
{
return Search(root->rightChild, item);
}
//补充代码
}
//中序遍历,遍历结果通过data[], 返回,n为遍历后,数组元素的个数
void InOrder(BiTreeNode* root, DataType data[], int* n)
{
if (root->leftChild != NULL)
InOrder(root->leftChild, data, n);
data[*n] = root->data;
(*n)++;
if (root->rightChild != NULL)
InOrder(root->rightChild, data, n);
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "BiSortTree.h"
/*生成在[200, 1000]之间互不相同的整数保存数组A中,以此数组元素作为关键字,设计实现以下操作的程序:
① 建立对应的BST树,按中序遍历算法输出所建立的BST树的结点;
② 在BST树上的查找指定的关键字(输入要查找的整数);
③ 在BST树上的删除指定的关键字(输入要删除的整数);
按中序遍历算法输出所建立的BST树的结点;
④ 主函数通过调用函数实现以上操作。
*/
/*
功能:
主函数
参数:
argc - argv 数组的长度,大小至少为 1,argc - 1 为命令行参数的数量。
argv - 字符串指针数组,数组长度为命令行参数个数 + 1。其中 argv[0] 固定指向当前
所执行的可执行文件的路径字符串,argv[1] 及其后面的指针指向各个命令行参数。
例如通过命令行输入 "C:\\hello.exe -a -b" 后,main 函数的 argc 的值为 3,
argv[0] 指向字符串 "C:\\hello.exe",argv[1] 指向字符串 "-a",argv[2] 指向字符串 "-b"。
返回值:
成功返回 0, 失败返回 1
*/
int main(int argc, char* argv[])
{
// 使用第一个参数输入待处理文件的名称,若没有输入此参数就报告错误
if(argc < 2)
{
printf("Usage: app.exe filename\\n");
return 1;
}
// 打开待处理的文件。读取文件中的内容。
FILE* file = fopen(argv[1], "rt");
if(NULL == file)
{
printf("Can not open file \\"%s\\".\\n", argv[1]);
return 1;
}
int datas[100];
int n=0;
int d;
int data[100];
int count=0;
int i=0;
fscanf(file,"%d",&d);
while(d!=-1){
datas[n]=d;
n++;
fscanf(file,"%d",&d);
}
// for(int i=0;i<n;i++)
// printf("%d ",datas[i]);
BiTreeNode * root= createTree(datas, n);
printf("The result of in order travel of the sort BiTree is:\\n");
InOrder(root,data,&count);
for(i=0;i<count-1;i++ )
{
if(i>0&&i%10==0)
printf("\\n");
printf("%-4d ",data[i]);
}
printf("%d ",data[count-1]);
printf("\\n");
fscanf(file,"%d",&d);
BiTreeNode *p=Search(root,d);
if(p!=NULL)
printf("the data %d exists!", d);
else
printf("the data %d does not exists!", d);
printf("\\n");
fscanf(file,"%d",&d);
p=Search(root,d);
if(p!=NULL)
printf("the data %d exists!", d);
else
printf("the data %d does not exists!", d);
printf("\\n");
fscanf(file,"%d",&d);
Delete(&root,d);
printf("The result of in order travel after deleting the data %d:\\n",d);
count=0;
InOrder(root,data,&count);
for(i=0;i<count-1;i++ )
{
if(i>0&&i%10==0)
printf("\\n");
printf("%-4d ",data[i]);
}
printf("%d ",data[count-1]);
printf("\\n");
fscanf(file,"%d",&d);
Delete(&root,d);
printf("The result of in order travel after deleting the data %d:\\n",d);
count=0;
InOrder(root,data,&count);
for(i=0;i<count-1;i++ )
{
if(i>0&&i%10==0)
printf("\\n");
printf("%-4d ",data[i]);
}
printf("%d ",data[count-1]);
fclose(file);
return 0;
}
以上是关于二叉排序树各类算法实现的主要内容,如果未能解决你的问题,请参考以下文章