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;
}