基于SBT的学生成绩管理系统

C语言的期末大作业,居然拖到了最后一天才做完,最近实力真的是好弱成渣了大哭

本来还在纠结是直接那链表水一个还是写个平衡树,后来才得知用链表是得不了满分的。遂直接SBT!

首先学习SBT,对NOCOW上的CLJ大神的代码表示膜拜,完全无法理解。

然后,看了几遍陈启峰大神的PPT和论文才感觉大概明白了50%。

最后选取了博客上的一个模板,讲的也不错,详见http://www.cnblogs.com/zgmf_x20a/archive/2008/11/14/1333205.html

一开始的想针对数据的三元建3棵SBT,但到后来发现建那棵字母的SBT会极大地提高Debug的复杂度,只好建2棵来写。

被野指针坑了的说---,该模板时没有增加判断指针是否为NULL,各种崩。。。

因为时间原因,我的这个管理系统有一些缺陷。最大的就是DELETE功能,这块模板代码我不理解,但又找不到更好的,所以只能试着去改,最后的结果就是有一定几率删错节点,有极小几率崩溃,我想崩溃的情况可能是极限数据,比如2个节点,形成单链,key值多次重复等等,我大概改了好久也没成功,只好先交上去吧委屈

还有一个缺点就是最后的美工也没做好,一开始还想跟京杰学长学Qt,但时间紧迫只好放弃抓狂

最后感谢骆神,赛哥等人的援助可怜

我的第一个大程序K.O!!!

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <windows.h>
#include <fstream>
using namespace std;
#define outstars cout << "**************" << endl;
ofstream fcout("a.txt");
struct SBTNode
{

    SBTNode *lc,*rc;

    int key,sz;
    int num;
    char name[20];
    int score;

    SBTNode()
    {

        memset(name , 0 , sizeof(name));
        sz=1;
        lc=NULL;
        rc=NULL;
    }

};
SBTNode *T1;
SBTNode *T2;
SBTNode *x;
SBTNode* SBTSearch(SBTNode* T,int key);


void SBTInsert(SBTNode* &T,SBTNode* x);//修改了树的结构,故参数需引用

SBTNode* SBTDel(SBTNode* &T,int key);//

SBTNode* SBTSelect(SBTNode* T,int k);

int SBTRank(SBTNode* T,int key);

void show(SBTNode* x);

void RightRotate(SBTNode* &x)//右旋
{

    SBTNode* y=x->lc;

    x->lc=y->rc;

    y->rc=x;

    y->sz=x->sz;

    x->sz=x->lc->sz+x->rc->sz+1;

    x=y;

}



void LeftRotate(SBTNode* &x)//左旋
{

    SBTNode* y=x->rc;

    x->rc=y->lc;

    y->lc=x;

    y->sz=x->sz;

    x->sz=x->lc->sz+x->rc->sz+1;

    x=y;

}



SBTNode* SBTSearch(SBTNode* T,int key)
{
    if(!T || key==T->key)
        return T;
    if(key<T->key)
        return SBTSearch(T->lc,key);
    else
        return SBTSearch(T->rc,key);

}

void Maintain(SBTNode* &T,bool RightDeeper)
{

    if(!RightDeeper)
    {

        if(T->lc==NULL || T->rc == NULL || T->lc->lc == NULL || T->lc->rc == NULL)

            return;

        if(T->lc->lc->sz>T->rc->sz)

            RightRotate(T);

        else if(T->lc->rc->sz>T->rc->sz)
        {

            LeftRotate(T->lc);

            RightRotate(T);

        }
        else
            return;
    }

    else
    {

        if(T->lc==NULL || T->rc == NULL || T->lc->lc == NULL || T->lc->rc == NULL)

            return;

        if(T->rc->rc->sz>T->lc->sz)

            LeftRotate(T);

        else if(T->rc->lc->sz>T->lc->sz)
        {

            RightRotate(T->rc);

            LeftRotate(T);

        }

        else

            return;

    }

    Maintain(T->lc,false);

    Maintain(T->rc,true);
    Maintain(T,false);

    Maintain(T,true);

}

void SBTInsert(SBTNode* &T,SBTNode* x)
{

    if(T==NULL)
    {

        T=x;

        return;

    }

    T->sz++;

    if(x->key<T->key)

        SBTInsert(T->lc,x);

    else

        SBTInsert(T->rc,x);

    Maintain(T,x->key>=T->key);

}

SBTNode* SBTDel(SBTNode* &T,int key)
{

    SBTNode* record;
    if(T == NULL)return NULL;
    if(T->sz<=2)
    {
        record = T;

        //T=T->lc+T->rc;

        T=T->lc?T->lc:T->rc;

        return record;

    }

    T->sz--;

    if(key==T->key)
    {

        record=SBTDel(T->lc,key+1);

        T->key=record->key;

        T->sz=record->sz;
        T ->num = record->num;
        T->score = record ->score;
        strcpy(T->name , record->name);

        Maintain(T,true);

    }
    else if(key<T->key)

        record=SBTDel(T->lc,key);

    else

        record=SBTDel(T->rc,key);

    Maintain(T,key<T->key);

    return record;

}



SBTNode* SBTSelect(SBTNode* T,int k)
{
	int lcount;
	if(NULL == T) return NULL;
	if(T->lc == NULL)
		lcount = 0;
	else lcount = T->lc->sz;
    if(k==lcount+1)

        return T;

    if(k<=lcount)

        return SBTSelect(T->lc,k);

    else

        return SBTSelect(T->rc,k-1-lcount);

}


int SBTRank(SBTNode* T,int key)
{

    if(T==NULL)

        return 1;

    if(key<=T->key)

        return SBTRank(T->lc,key);

    else

        return T->lc->sz+1+SBTRank(T->rc,key);

}
void show(SBTNode* x)
{
     if(x == NULL) return;
     show(x ->lc);
     printf("%d %s %d\n",x->num,x->name , x->score);
     show(x ->rc);
}
void fshow(SBTNode* x)
{
     if(x == NULL) return;
     fshow(x ->lc);
     fcout << x->num << x->name <<  x->score << endl;;
     fshow(x ->rc);
}
int main()
{
    int choice1 , choice2 , choice3  ,choice4 ,Num , Score;
    char Name[20];
    choice1 = 1;
    int numdate = 0;
    while(choice1)
    {
        cout << "******************************************************************************" << endl;
        cout << "-------- << Welcome to use student achievement management system >> ----------" << endl;
        cout << "                                                     Designed By Xinming Zhou " << endl;
        cout << "******************************************************************************" << endl;

        cout << "                          1 : Insert Student's Score" << endl;
        cout << "                          2 : Show All Students' Score" << endl;
        cout << "                          3 : Sort " << endl;
        cout << "                          4 : Search "<< endl;
        cout << "                          5 : Delete " << endl;
        cout << "                          6 : Save And Exit" << endl;
        cout << "******************************************************************************" << endl;
        cout << "There are " << numdate << " date(s) in the system now"<< endl;
        cout << "Please input the operate's number:" << endl;
        scanf("%d",&choice1);
        switch(choice1)
        {
        case 1:
            system("cls");
            printf("Input num,name and score(separated by space):\n");
            scanf("%d%s%d" , &Num , Name , &Score);
            //cout << Num << Name << Score << endl;
            x = new SBTNode;
            x-> key = x -> num = Num;
            strcpy(x->name , Name);
            x->score = Score;
            //outstars
            SBTInsert(T1,x);

            x = new SBTNode;
            x->num = Num;
            strcpy(x->name , Name);
            x->key = x->score = Score;
            SBTInsert(T2,x);

            numdate++;
            break;
        case 2:
            system("cls");
            show(T1);
            break;
        case 3:
            system("cls");
            cout << "1 : Sorted By Num" << endl;
            cout << "2 : Sorted By Score" << endl;
            cout << "0 : Return to The Former"  << endl;
            scanf("%d",&choice2);
            if(choice2 == 1)
            {
                show(T1);
            }
            else if(choice2 == 2)
            {
                show(T2);
            }
            break;
        case 4:
            system("cls");
            cout << "1 : Searched By Num" << endl;
            cout << "2 : Searched By Score" << endl;
            cout << "3 : Searched By The Rank of Num" << endl;
            cout << "4 : Searched By The Rank of Score" << endl;
            cout << "0 : Return to The Former"  << endl;
            scanf("%d",&choice3);
            if(choice3 == 0)break;
            cout << "Please input your num / score / rank" << endl;
            scanf("%d",&Num);
            if(choice3 == 1)
            {
                x = SBTSearch(T1,Num);
				if(NULL == x)
					printf("No Student Matched!!!\n");
				else printf("%d %s %d\n",x ->num,x->name , x->score);
            }
            else if(choice3 == 2)
            {
                x = SBTSearch(T2,Num);
				if(NULL == x)
					printf("No Student Matched!!!\n");
				else printf("%d %s %d\n",x ->num,x->name , x->score);
            }
            else if(choice3 == 3)
            {
                x = SBTSelect(T1,Num);
				if(NULL == x)
					printf("No Student Matched!!!\n");
				else printf("%d %s %d\n",x ->num,x->name , x->score);
            }
            else if(choice3 == 4)
            {
                x = SBTSelect(T2,Num);
				if(NULL == x)
					printf("No Student Matched!!!\n");
				else printf("%d %s %d\n",x ->num,x->name , x->score);
            }
            break;
        case 5:
            system("cls");
            cout << "1 : Deleted By Num" << endl;
            cout << "2 : Deleted By Score" << endl;
            cout << "0 : Return to The Former"  << endl;
            scanf("%d",&choice4);
            if(choice4 == 0)break;
            cout << "please input the num / score you want to delete" << endl;
            scanf("%d",&Num);
            if(choice4 == 1)
            {
				SBTNode* x;
                x = SBTDel(T1,Num);
				if(NULL != x)
					SBTDel(T2, x->score);
                else
                        printf("No Student Matched!!!\n");
            }
            else if(choice4 == 2)
            {
				SBTNode* x;
                x = SBTDel(T2,Num);
				if(NULL != x)
					SBTDel(T1, x->num);
                else
                    printf("No Student Matched!!!\n");
            }

            numdate--;
            break;
        case 6:

            fshow(T1);
            fcout.close();
            goto C;
            break;
        }
    }
    C:
    return 0;
}


你可能感兴趣的:(sbt)