下面是原始碼:
-------------------------------------------------------------------------------------
#include<iostream>
#include<time.h> //輔助函數SetRandElem()產生隨機種子
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define ELEM_INIT_LEN 50 //順序表預設大小
#define ELEM_INCR_LEN 10 //順序表預設記憶體遞增值
typedef int Status;
////////////////////////////////////////////////////////
//類SqList聲明
//
class SqList
{//- - - 順序表資料類型 - - -
private:
int *elem;//順序表指標
int length;//順序表使用大小
int listsize;//順序表總大小
Status IncSpace();//增加預設大小記憶體空間
Status IncSpace(int e);//增加自訂大小記憶體空間
public:
SqList();
//預設建構函式-->初始化函數
//操作結果:構造順序表
~SqList();
//解構函式-->銷毀對象
//操作結果:銷毀順序表
Status InitElem();
//操作結果:由使用者初始化順序表
Status ClearElem();
//操作結果:順序表元素全部初始化為0,length=0;
Status SetRandElem();
//操作結果:順序表被隨機數初始化
//==>備忘:輔助函數
Status Put(int i,int e);
//初始條件:0<=i<=length&&順序表已指派記憶體空間
//操作結果:第i個元素被賦值
Status Put(int i,istream in);
//初始條件:0<=i<=length&&順序表已指派記憶體空間
//操作結果:第i個元素被賦值
Status IsAscending()const;
//操作結果:順序表非遞減判斷-->非遞減返回TRUE,其他返回FALSE
Status IsDescending()const;
//操作結果:順序表非遞增判斷-->非遞增返回TRUE,其他返回FALSE
Status IsEmpty();
//操作結果:如果順序表為空白,返回TRUE,否則返回FALSE
Status IsFull();
//操作結果:如果順序表為滿,返回TRUE,否則返回FALSE
Status Ascending();
//操作結果:順序表按非遞減排列
Status Descending();
//操作結果:順序表按非遞增排列
Status Insert(int e);
//初始條件:順序表有序排列(非遞減/非遞增),若未排列會詢問使用者是否排列,不排列則在尾部插入
//操作結果:元素e被插入順序表
Status InsertI(int i,int e);
//初始條件:0<=i<=length&&順序表已指派記憶體空間
//操作結果:元素e被插入順序表的第i個元素處
Status InsertL(int e);
//初始條件:length<listsize
//操作結果:元素e被插入順序表尾部
Status DeleteI(int i);
//初始條件:0<=i<=length&&順序表已指派記憶體空間
//操作結果:順序表中第i個元素被刪除
Status Delete(int e);
//初始條件:順序表已指派記憶體空間
//操作結果:若元素e存在,則刪除e,並返回TRUE;若不存在,返回FALSE
Status Link(SqList &e);
//操作結果:將順序表e中所有元素插入到該順序表之中
//==>備忘:兩順序表均會被排序(預設為非遞減)
Status LinkAndDel(SqList &e);
//操作結果:將順序表e中所有元素插入到該順序表之中並重複資料刪除元素
//==>備忘:兩順序表均會被排序(預設為非遞減)
Status LinkL(SqList &e);
//操作結果:順序表e將被直接連接在該順序表尾部
int Max()const;
//操作結果:返回順序表中最大的元素的值
int Min()const;
//操作結果:返回順序表中最小的元素的值
int Get(int i)const;
//操作結果:返回順序表中第i個元素的值
int GetSize()const{return length;}
//操作結果:返回資料使用大小
int GetLen()const{return listsize;}
//操作結果:返回順序表總大小
void PutElem();
//操作結果:按順序輸出順序表的所有元素
};
//////////////////////////////////////////////////////
//類SqList的實現
//
SqList::SqList()//Checked
{//預設建構函式
elem=(int *)malloc(ELEM_INIT_LEN*sizeof(int));
for(int i=0;i<ELEM_INIT_LEN;i++)
elem[i]=0;
listsize=ELEM_INIT_LEN;
length=0;
}
SqList::~SqList()
{//解構函式
int *temp;
listsize=0;
length=0;
temp=elem;
elem=NULL;
delete [] elem;
}
Status SqList::IncSpace()
{
if(!elem)
{
cout<<"ERROR in IncSpace:elem=NULL!";
return FALSE;
}
elem=(int *)realloc(elem,(ELEM_INCR_LEN+listsize)*sizeof(int));
listsize+=ELEM_INCR_LEN;
return OK;
}
Status SqList::IncSpace(int e)
{
if(!elem)
{
cout<<"ERROR in IncSpace:elem=NULL!";
return FALSE;
}
elem=(int *)realloc(elem,(e+listsize)*sizeof(int));
listsize+=e;
return OK;
}
Status SqList::InitElem()//Checked
{//設定元素
cout<<"Input "<<listsize<<" numbers to initialize elements:";
for(int i=0;i<listsize;i++)
{
cin>>elem[i];
length++;
}
if(elem&&length==listsize)
return OK;
else
return FALSE;
}
Status SqList::ClearElem()
{
if(!elem)
return ERROR;
for (int i=0;i<length;i++)
elem[i]=0;
length=0;
return TRUE;
}
Status SqList::SetRandElem()
{//隨機設定順序表元素
for(int i=0;i<listsize;i++)
{
elem[i]=rand()%32768; //隨機函數需修改
length++;
}
if(elem&&length==listsize)
return OK;
else
return FALSE;
}
int SqList::Get(int i)const//Checked
{//擷取第i個元素的值
if(elem)
return elem[i];
else
return INFEASIBLE;
}
Status SqList::Put(int i,int e)//Checked
{//給第i個元素賦值
if (i<0||i>length)
return ERROR;
if (!elem)
return ERROR;
elem[i]=e;
return OK;
}
Status SqList::Put(int i,istream in)
{//用輸入資料流給第i個元素賦值
if (i<0||i>length)
return ERROR;
if (!elem)
return ERROR;
cin>>elem[i];
return OK;
}
Status SqList::IsAscending()const//Checked
{//非遞增序列判斷
if(length>0&&length<=listsize)
{
for(int i=1;i<length;i++)
{
if(elem[i-1]>elem[i])
return FALSE;
}
}
else
return FALSE;
return TRUE;
}
Status SqList::IsDescending()const//Checked
{//非遞增序列判斷
if(length>0&&length<=listsize)
{
for(int i=1;i<length;i++)
{
if(elem[i-1]<elem[i])
return FALSE;
}
}
else
return FALSE;
return TRUE;
}
Status SqList::IsEmpty()
{
return length<=0;
}
Status SqList::IsFull()
{
return length>=listsize;
}
Status SqList::Ascending()//Checked
{//非遞減序列排序
int i,j,temp=0;
for(i=1;i<length;i++)
{
for(j=0;j<length-i;j++)
{
if(elem[j]>elem[j+1])
{
temp=elem[j];
elem[j]=elem[j+1];
elem[j+1]=temp;
}
}
}
if(IsAscending())
return TRUE;
else
return FALSE;
return FALSE;
}
Status SqList::Descending()//Checked
{//非遞增序列排序
int i,j,temp=0;
for(i=0;i<length;i++)
{
for(j=0;j<length-i;j++)
{
if(elem[j]<elem[j+1])
{
temp=elem[j];
elem[j]=elem[j+1];
elem[j+1]=temp;
}
}
}
if(IsDescending())
return TRUE;
else
return FALSE;
return FALSE;
}
Status SqList::Insert(int e)//Checked
{//插入元素e,[未排序次序表會詢問是否排序]
int i=1,j=0,ans=-1;
if(IsFull())
IncSpace();
if(IsAscending())
ans=1;
else if(IsDescending())
ans=2;
else
ans=0;
if(ans==0)
{//順序表未排序
cout<<endl<<"The Array is not arrenged,do you want to arrange now?"<<endl;
cout<<"1:Yes,and make it ascending."<<endl;
cout<<"2:Yes,and make it descending."<<endl;
cout<<"0:No,I don't want to do that."<<endl;
cin>>ans;
if(ans==1)
Ascending();
else if(ans==2)
Descending();
else if(ans!=0)
{
cout<<"ERROR:User's input to choose the arrange way.";
return ERROR;
}
}
if(ans==1)
{//非遞減
if(e<=elem[0])
i=0;
else if(e>=elem[length-1])
return InsertL(e);
else
{
//判斷中去掉了&&i<listsizze-1 最佳化:此處採用二分法
while(!(elem[i-1]<=e&&elem[i]>=e))
i++;
}
for(j=length;j>i;j--)
elem[j]=elem[j-1];
elem[j]=e;
length++;
return TRUE;
}
else if(ans==2)
{//非遞增
if(e>=elem[0])
i=0;
else if(e<=elem[length-1])
return InsertL(e);
else
{
//判斷中去掉了&&i<listsizze-1 最佳化:此處採用二分法
while(!(elem[i-1]>=e&&elem[i]<=e))
i++;
}
for(j=length;j>i;j--)
elem[j]=elem[j-1];
elem[j]=e;
length++;
return TRUE;
}
else if (ans==0)
return InsertL(e);
return FALSE;
}
Status SqList::InsertI(int i,int e)//Checked
{//將e插入第i個元素處
if(IsFull())
IncSpace();
if(i>=0&&i<length)
{
for(int j=length;j>i;j--)
{
elem[j]=elem[j-1];
}
elem[j]=e;
length++;
return TRUE;
}
else if(i==length)
{
elem[length]=e;
length++;
return TRUE;
}
return FALSE;
}
Status SqList::InsertL(int e)//Checked
{//在尾部插入
if(IsFull())
IncSpace();
elem[length]=e;
length++;
return TRUE;
}
Status SqList::DeleteI(int i)//Checked
{//刪除第i個元素
if(i>=0&&i<length-1)
{
for(;i<length-1;i++)
elem[i]=elem[i+1];
length--;
}
else if(i==length-1&&length>0)
{
elem[i]=0;
length--;
}
else
return FALSE;
return TRUE;
}
Status SqList::Delete(int e)//Checked
{//刪除元素e
int i=0;
while(elem[i]!=e&&i<length){i++;}
if(i<length)
{
DeleteI(i);
return TRUE;
}
else
{
cout<<"Can't find element "<<e<<"!"<<endl;
return FALSE;
}
return FALSE;
}
Status SqList::Link(SqList &e)
{//連結兩個順序表
if(e.GetLen()!=0)
{
int i=0,j=0,k=e.GetSize();
if(!(listsize>=length+k))
IncSpace(k);
if(!IsAscending())
Ascending();
if(!e.IsAscending())
e.Ascending();
while(i<length&&k)
{
if(elem[i]<e.Get(j))
i++;
else if(elem[i]>=e.Get(j))
{
InsertI(i,e.Get(j));
i++;
j++;
k--;
}
}
while(k)
{
InsertI(i,e.Get(j));
i++;
j++;
k--;
}
return TRUE;
}
else
return FALSE;
}
Status SqList::LinkAndDel(SqList &e)
{//連結兩個順序表,並重複資料刪除元素
if(e.GetLen!=0)
{
int i=0,j=0,k=e.GetSize();
if(!(listsize>=length+k))
IncSpace(k);
if(!IsAscending())
Ascending();
if(!e.IsAscending())
e.Ascending();
while (i<length)
{
if (elem[i]==elem[i+1])
DeleteI(i+1);
else
i++;
}
i=0;
while(i<length&&k)
{
if(elem[i]<e.Get(j))
i++;
else if(elem[i]>e.Get(j))
{
InsertI(i,e.Get(j));
i++;
j++;
k--;
}
else if(elem[i]==e.Get(j))
{
j++;
k--;
}
}
while(k)
{
InsertI(i,e.Get(j));
i++;
j++;
k--;
}
return TRUE;
}
else
return FALSE;
}
Status SqList::LinkL(SqList &e)
{//在尾部連結
if(e.GetSize()!=0)
{
int i=length,j=0,k=e.GetSize();
if(!(listsize>=length+k))
IncSpace(k);
while(j<e.GetSize()&&length<=listsize)
{
elem[i]=e.Get(j);
length++;
i++;
j++;
}
return OK;
}
else
return FALSE;
}
int SqList::Max()const//Checked
{//擷取最大值
if (length==0)
{
cout<<"No elements in the list!"<<endl;
return ERROR;
}
int i,max=elem[0];
for(i=1;i<length;i++)
{
if(elem[i]>max)
max=elem[i];
}
return max;
}
int SqList::Min()const//Checked
{//擷取最小值
if (length==0)
{
cout<<"No elements in the list!"<<endl;
return ERROR;
}
int i,min=elem[0];
for(i=1;i<length;i++)
{
if(elem[i]<min)
min=elem[i];
}
return min;
}
void SqList::PutElem()//Checked
{//輸出元素
int sum=0;
if(length>=0&&length<=listsize)
{
for(int i=0;i<length;i++)
{
cout<<elem[i]<<" ";
sum++;
}
cout<<endl<<"The sum numbers that have been put are "<<sum<<"."<<endl;
cout<<"The listsize is "<<listsize<<",and the length is "<<length<<"."<<endl;
}
else
{
cout<<"Element Error!"<<endl;
cout<<"length="<<length<<" listsize="<<listsize<<endl;
system("pause");
exit(ERROR);
}
}
//////////////////////////////////////////////////////////
//主函數部分:測試用......
//
int main()
{
SqList trip,trip12,trip13,trip14;
int i=0,temp;
trip.SetRandElem();
cout<<"After setrandelem,trip is:"<<endl;
trip.PutElem();
cout<<endl<<"The biggest is "<<trip.Max()<<endl<<endl;
cout<<"The smallest is "<<trip.Min()<<endl<<endl;
if(trip.IsDescending())
{
trip.Ascending();
cout<<"After ascending:"<<endl;
trip.PutElem();
cout<<endl;
}
if(trip.IsAscending())
{
trip.Descending();
cout<<"After descending:"<<endl;
trip.PutElem();
cout<<endl;
}
cout<<"Input a number to insert:";
cin>>temp;
trip.Insert(temp);
cout<<"After Insert:";
trip.PutElem();
cout<<endl;
cout<<"Input a element to delete:";
cin>>temp;
trip.Delete(temp);
cout<<"After Delete:";
trip.PutElem();
cout<<endl;
trip12.SetRandElem();
cout<<"After setrandelem,trip12 is:"<<endl;
trip12.PutElem();
cout<<endl;
trip.Link(trip12);
cout<<"After Linking:"<<endl;
trip.PutElem();
cout<<endl;
trip13.SetRandElem();
cout<<"After setrandelem,trip13 is:"<<endl;
trip13.PutElem();
cout<<endl;
trip.LinkL(trip13);
cout<<"After Linking at Last:"<<endl;
trip.PutElem();
cout<<endl;
trip14.SetRandElem();
cout<<"After setrandelem,trip14 is:"<<endl;
system("pause");
trip14.PutElem();
system("pause");
cout<<endl;
trip.ClearElem();
cout<<"After clearelements,trip is:"<<endl;
trip.PutElem();
cout<<endl;
cout<<"Linking.....[TEST......]"<<endl;
trip.LinkAndDel(trip12);
cout<<"Linking.....[TEST......]"<<endl;
trip.LinkAndDel(trip13);
cout<<"Linking.....[TEST......]"<<endl;
trip.LinkAndDel(trip14);
cout<<"After link trip12,trip13,trip14 to trip,and delete the repeat number:"<<endl;
trip.PutElem();
return TRUE;
}
本實驗運行環境說明:
/////////////////////////////////////////////////////////////
硬體環境:
///////////////
CPU:Inter E7200 主頻:2.53GHz
主板:ASUS P5QL Pro
記憶體:Kingston DDR2 800 1Gx2
硬碟:SeaGate 7200.11 32M 500G
顯卡:GALAXY GeForce 9600GT 中將版
///////////////
軟體環境:
///////////////
作業系統:Windows XP SP 3
IDE:Microsoft VC++ 6.0整合式開發環境
本次實驗主要發現問題如下:
當設定預設順序表大小為5000之後,隨即函數產生5000個隨機數,在之後的測試過程中,總共產生15000個隨機數,所有類操作均正確無誤,但是除了LinkAndDel()的最後幾步測試會卡在某個 cout<<"Linking.....[TEST......]"<<endl;處,初步斷定為記憶體溢出造成程式進入假死機狀態。具體原因有待進一步測試.......