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