二叉排序树

1二叉排序树与文件操作

功能要求:

1)从键盘输入一组学生记录建立二叉排序树;

2)二叉排序树存盘;

3)由文件恢复内存的二叉排序树;

4)中序遍历二叉排序树;

5)求二叉排序树深度;

6)求二叉排序树的所有节点数和叶子节点数;

7)向二叉排序树插入一条学生记录;

8)从二叉排序树中删除一条学生记录;

9)从二叉排序树中查询一条学生记录;

10)以广义表的形式输出二叉排序树

//定义学生记录类型

Struct  student

{

    Char  num[6];   //学号

    Int    grade;    //成绩

};

//定义二叉排序树节点值的类型为学生记录类型

typedef  student   ElemType;

//定义二叉排序树的节点类型

typedef  Struct BSTNode

{

    ElemType  data;

    Struct BSTNode  *left;

    Struct BSTNode  *rchild;

} BSTNode;

 

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <fstream>
#include <windows.h>
using namespace std;
struct  student
{
    char  num[6];
    int   grade;
};

typedef  student  ElemType;

typedef  struct BSTNode
{
    ElemType  data;
    struct BSTNode  *lchild;
    struct BSTNode  *rchild;
} BSTNode,*BiTree;

BiTree Search(BiTree T,int key)
{
    if (!T)
    {
        return NULL;
    }
    if (key > T->data.grade)
    {
        return Search(T->rchild,key);
    }
    else if (key < T->data.grade)
    {
        return Search(T->lchild,key);
    }
    else
    {
        return T;
    }
}

void Insert(BiTree &T,char *num,int key)
{
    BiTree p;
    p=new BSTNode;
    p->data.grade=key;
    strcpy(p->data.num,num);
    p->lchild=p->rchild=NULL;
    if (!T)
    {
        T=p;
        return;
    }

    if (Search(T,key)!=NULL)
    {
        return;
    }
    BiTree tnode=NULL;
    BiTree troot=T;
    while(troot)
    {
        tnode=troot;
        if (key < troot->data.grade)
        {
            troot = troot->lchild;
        }
        else
        {
            troot = troot->rchild;
        }
    }
    if (key < tnode->data.grade)
        tnode->lchild = p;
    else
        tnode->rchild = p;
}

int Search_Line(BiTree T,char *s)
{
    queue<BiTree>q;
    q.push(T);
    while(!q.empty())
    {
        BiTree t=q.front();
        q.pop();
        if (strcmp((t->data.num),s)==0)
        {
            return t->data.grade;
        }
        if (t->lchild)
        {
            q.push(t->lchild);
        }
        if (t->rchild)
        {
            q.push(t->rchild);
        }
    }
}

void MidOrderTraverse(BiTree T)
{
    if (T)
    {
        MidOrderTraverse(T->lchild);
        cout<<T->data.num<<" "<<T->data.grade<<endl;
        MidOrderTraverse(T->rchild);
    }
}

void Delete(BiTree T,int key)
{
    BiTree p=T,q=NULL,s=NULL,f=NULL;
    if (!p)
    {
        return ;
    }
    while(p)
    {
        if (p->data.grade==key)
        {
            break;
        }
        f=p;
        if (p->data.grade>key)
        {
            p=p->lchild;
        }
        else
        {
            p=p->rchild;
        }
    }
    q=p;
    if (p->lchild&&p->rchild)
    {
        s=p->lchild;
        while(s->rchild)
        {
            q=s;
            s=s->rchild;
        }
        p->data=s->data;
        if (q!=p)
        {
            q->rchild=s->lchild;
        }
        else
        {
            q->lchild=s->lchild;
        }
        delete s;
        return ;
    }
    else if (!p->rchild)
    {
        p=p->lchild;
    }
    else if (!p->lchild)
    {
        p=p->rchild;
    }
    if (!f)
    {
        T=p;
    }
    else if (q==f->lchild)
    {
        f->lchild=p;
    }
    else
    {
        f->rchild=p;
    }
    delete q;

}

int count(BiTree T)
{
    if(T == NULL)
    {
        return 0;
    }
    else if ((T->lchild==NULL) && (T->rchild==NULL))
    {
        return 1;
    }
    else
    {
        return count(T->lchild)+count(T->rchild);
    }
}

int numbers(BiTree T)
{
    int sum=0;
    if (!T)
    {
        sum++;
    }
    else
    {
        sum=1+numbers(T->lchild)+numbers(T->rchild);
    }
    return sum;
}

int Depth(BiTree T)
{
    if (T==NULL)
    {
        return 0;
    }
    else
    {
        int m=Depth(T->lchild);
        int n=Depth(T->rchild);
        if (m>n)
        {
            return m+1;
        }
        return n+1;
    }
}

void f_write(BiTree T)
{

    ofstream open("11.txt");
    if (!open.is_open())
    {
        cout<<"文件打开失败!"<<endl;
        return;
    }
    queue<BiTree>q;
    q.push(T);
    while(!q.empty())
    {
        BiTree t=q.front();
        q.pop();
        open<<t->data.num<<" "<<t->data.grade<<endl;
        if (t->lchild)
        {
            q.push(t->lchild);
        }
        if (t->rchild)
        {
            q.push(t->rchild);
        }
    }
    cout<<"文件打开成功!"<<endl;
    open.close();
}

void f_read(BiTree &T)
{
    // T->lchild=NULL;
    //T->rchild=NULL;
    FILE *fp;
    fp = fopen("11.txt", "r");
    if (fp == NULL)
    {
        printf("Open File failed.\n");
        return;
    }
    int a;
    char str[6];
    while (!feof(fp))
    {
        fscanf(fp, "%s %d", &str, &a);
        //printf("Line:%s %d\n", str, a);
        Insert(T,str,a);
    }
    cout<<"文件打开成功!"<<endl;
    fclose(fp);
}

void Put(BiTree T)
{
    if(T!=NULL)
    {
        cout<<T->data.num;
        if(T->lchild!=NULL||T->rchild!=NULL)
        {
            cout<<"(";
            Put(T->lchild);
            if(T->rchild!=NULL)
            {
                cout<<",";
            }
            Put(T->rchild);
            cout<<")";
        }
    }
}

void start()
{
    printf ("1.键盘输入一组学生记录建立二叉排序树\n");
    printf ("2.二叉排序树存盘\n");
    printf ("3.由文件恢复内存的二叉排序树\n");
    printf ("4.中序遍历二叉排序树\n");
    printf ("5.求二叉排序树深度\n");
    printf ("6.求二叉排序树的所有节点数和叶子节点数\n");
    printf ("7.向二叉排序树插入一条学生记录\n");
    printf ("8.从二叉排序树中删除一条学生记录\n");
    printf ("9.从二叉排序树中查询一条学生记录\n");
    printf ("10.以广义表的形式输出二叉排序树\n");
}

int main()
{
    printf("二叉排序树系统\n");
    int ch;
    BiTree T=NULL;
    while (1)
    {
        start();
        printf("请输入操作序号:\n");
        cin>>ch;
        switch(ch)
        {
        case 1:
            printf ("请输入学生个数\n");
            int n;
            cin>>n;
            printf ("请输入学生信息\n");
            for(int i=0; i<n; i++)
            {
                char s[6];
                int x;
                printf ("请输入学生学号\n");
                cin>>s;
                printf ("请输入学生成绩\n");
                cin>>x;
                Insert(T,s,x);
            }
            break;
        case 2:
                f_write(T);
            break;
        case 3:
                f_read(T);
            break;
        case 4:
                MidOrderTraverse(T);
            break;
        case 5:
                cout<<"二叉树深度为"<<Depth(T)<<endl;
            break;
        case 6:
                cout<<"二叉树结点数为"<<numbers(T)<<endl;
                cout<<"二叉树叶子结点数为"<<count(T)<<endl;
            break;
        case 7:
                char s[6];
                int x;
                printf ("请输入插入学生学号\n");
                cin>>s;
                printf ("请输入插入学生成绩\n");
                cin>>x;
                Insert(T,s,x);
            break;
        case 8:
                printf ("请输入删除学生姓名\n");
                char Del[6];
                cin>>Del;
                Delete(T,Search_Line(T,Del));
                printf ("已删除\n");
            break;
        case 9:
                 printf ("请输入查找学生姓名\n");
                 char Sear[6];
                 cin>>Sear;
                 printf ("姓名为%s的同学成绩为%d\n",s,Search_Line(T,Sear));
            break;
        case 10:
                Put(T);
            break;
        case 11:
            printf ("即将推出系统\n");
            Sleep(200);
            exit(0);
        default:
            printf("输入序号有误,请重新输入\n");
            break;
        }
    }
    return 0;
}
/*
5
001 80
002 96
003 60
004 99
005 85
*/

 

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值