準備數據
#define MAXLEN 100 //定義順序表的最大長度
struct DATA
{
char key[10]; //結點的關鍵字
char name[20];
int age;
};
struct SLType //定義順序表結構
{
DATA ListData[MAXLEN+1];//保存順序表的結構數組
int ListLen; //順序表已存結點的數量
};
定義了順序表的最大長度MAXLEN、順序表數據元素的類型DATA以及順序表的數據結構SLType。在數據結構SLType中,Listen為順序表已存結點的數量,也就是當前順序表的長度,ListData是一個結構數組,用來存放各個數據結點。
我們認為該順序表是一個班級學生的記錄。其中,key為學號,name為學生的名稱,age為年齡。
因為數組都是從下標0開始的,為了使用方便,我們從下標1開始記錄數據結點,下標0的位置不可用。
初始化順序表
在使用順序表之前,首先創建一個空的順序表,也就是初始化順序表。這里,在程序中只需設置順序表的結點數量ListLen為0即可。這樣,后面需要添加的數據元素將從順序表的第一個位置存儲。
示例代碼:
void SLInit(SLType * SL) //初始化順序表
{
SL->Listlen=0;
}
計算線性表的長度計算線性表的長度也就是計算線性表中結點的個數,由于我們在SLType中定義了ListLen來表示結點的數量,所以我們只需要獲得這個變量的值即可。
int SLLenght(SLType *SL)
{
return(SL->ListLen); //返回順序表的元素數量
}
插入結點插入節點就是在線性表L的第i個位置上插入一個新的結點,使其后的結點編號依次加1。
這時,插入一個新節點之后,線性表L的長度將變為n+1。插入結點操作的難點在于隨后的每個結點數據都要向后移動,計算機比較大,示例代碼如下:
int SLInsert(SLType *SL,int n,DATA data)
{
int i;
if(SL->ListLen>=MAXLEN) //順序表結點數量已超過最大數量
{
cout<<"順序表已滿,不能插入結點!"<<endl;
return 0; //返回0表示插入不成功
}
if(n<1||n>SL->ListLen) //插入結點的序號不合法
{
cout<<"插入序號錯誤!"<<endl;
return 0;
}
for(i=SL->ListLen;i>=n;i--) //將順序表中的數據向后移動
{
SL->ListData[i+1]=SL->ListData[i];
}
SL->ListData[n]=data;
SL->ListLen++;
return 1;
}
在程序中首先判斷順序表結點數量時候已超過最大數量,以及插入點的序號是否正確。前面條件都瞞住以后,便將順序表中的數據向后移動,同時插入結點,并更新結點數量ListLen。追加結點
追加結點就是在順序表的尾部插入結點,因此不必進行大量數據的移動,代碼實現與插入結點相比就要簡單的多。
int SLAdd(SLType * SL,DATA data)
{
if(SL->ListLen>=MAXLEN)
{
cout<<"順序表已滿,不能再添加結點了!"<<endl;
return 0;
}
SL->ListData[++SL->ListLen]=data;
return 1;
}
刪除結點刪除結點就是刪除線性表L中的第i個結點,使得其后的所有節點編號依次減1.這是,刪除一個結點之后,線性表L的長度將變為n-1。刪除結點和插入結點類似,都需要進行大量數據的移動。
int SLDelete(SLType *SL,int n) //刪除順序表中的數據元素
{
int i;
if(n<1||n>SL->ListLen) //刪除結點的序號不合法
{
cout<<"刪除序號錯誤!"<<endl;
return 0;
}
for(i=n;i<SL->ListLen;i++)//將順序表中的數據向前移動
{
SL->ListData[i]=SL->ListData[i+1];
}
SL->ListLen--; //順序表元素數量減1
return 1; //成功刪除返回1
}
查找結點查找節點就是在線性表L中查找值為x的結點,并返回該節點在線性表L中的位置。如果在線性表中沒有找到值為x的結點,則返回一個錯誤標志。
根據x的類型不同,查找結點可以分為:
按照序號查找結點
對于一個順序表,序號就是數據元素在數組中的位置,也就是數組的下標標號。按照序號查找結點是順序表查找結點最常用的方法,這是因為順序表的存儲本身就是一個數組,示例代碼如下:
DATA * SLFindByNum(SLType *SL,int n)//根據呼號返回數據元素
{
if(n<1||n>SL->ListLen) //查詢結點的序號不合法
{
cout<<"查詢序號錯誤!"<<endl;
return 0;
}
return &(SL->ListData[n]);
}
按照關鍵字查找結點關鍵字可以是數據元素中的任意一項。
這里以key關鍵字為例進行介紹,例如,可以通過key查找學生的信息。示例代碼如下:
int SLFindByCont(SLType * SL,char *key)//按關鍵字查詢結點
{
int i;
for(i=1;i<=SL->ListLen;i++)
{
if(strcmp(SL->ListData[i].key,key)==0)//如果找到結點
{
return i;
}
}
return 0; //在整個表中都沒有找到,返回0
}
顯示所有的結點示例代碼如下:
void SLALL(SLType *SL)
{
int i;
for(i=1;i<SL->ListLen;i++)
{
cout<<"key:"<<SL->ListData[i].key<<endl;
cout<<"name:"<<SL->ListData[i].name<<endl;
cout<<"age:"<<SL->ListData[i].age<<endl;
cout<<"============================="<<endl;
}
}
順序表操作完整示例:基本上就是把上面的函數放到一塊,集中展示了一下功能,代碼有些長,請耐心閱讀^.^
#include<iostream>
#include<string>
using namespace std;
#define MAXLEN 100 //定義順序表的最大長度
/**************順序表的定義部分*****************/
struct DATA
{
string key; //結點的關鍵字
string name;
int age;
};
struct SLType //定義順序表結構
{
DATA ListData[MAXLEN+1];//保存順序表的結構數組
int ListLen; //順序表已存結點的數量
};
/************順序表的初始化函數*****************/
void SLInit(SLType * SL) //初始化順序表
{
SL->ListLen=0;
}
/***********計算線性表的長度*******************/
int SLLenght(SLType *SL)
{
return(SL->ListLen); //返回順序表的元素數量
}
/*********插入結點*******************************/
int SLInsert(SLType *SL,int n,DATA data)
{
int i;
if(SL->ListLen>=MAXLEN) //順序表結點數量已超過最大數量
{
cout<<"順序表已滿,不能插入結點!"<<endl;
return 0; //返回0表示插入不成功
}
if(n<1||n>SL->ListLen) //插入結點的序號不合法
{
cout<<"插入序號錯誤!"<<endl;
return 0;
}
for(i=SL->ListLen;i>=n;i--) //將順序表中的數據向后移動
{
SL->ListData[i+1]=SL->ListData[i];
}
SL->ListData[n]=data;
SL->ListLen++;
return 1; //成功插入,返回1
}
/***********************追加結點*************************/
int SLAdd(SLType * SL,DATA data)
{
if(SL->ListLen>=MAXLEN)
{
cout<<"順序表已滿,不能再添加結點了!"<<endl;
return 0;
}
SL->ListData[++SL->ListLen]=data;
return 1;
}
/***********************刪除結點*************************/
int SLDelete(SLType *SL,int n) //刪除順序表中的數據元素
{
int i;
if(n<1||n>SL->ListLen) //刪除結點的序號不合法
{
cout<<"刪除序號錯誤!"<<endl;
return 0;
}
for(i=n;i<SL->ListLen;i++)//將順序表中的數據向前移動
{
SL->ListData[i]=SL->ListData[i+1];
}
SL->ListLen--; //順序表元素數量減1
return 1; //成功刪除返回1
}
/*******************按照序號查找結點********************/
DATA * SLFindByNum(SLType *SL,int n)//根據序號返回數據元素
{
if(n<1||n>SL->ListLen) //查詢結點的序號不合法
{
cout<<"查詢序號錯誤!"<<endl;
return 0;
}
return &(SL->ListData[n]);
}
/*******************按照關鍵字查找結點********************/
DATA *SLFindByCont(SLType * SL,string name)//按關鍵字查詢結點
{
int i;
for(i=1;i<=SL->ListLen;i++)
{
if(SL->ListData[i].name==name)//如果找到結點
{
return &(SL->ListData[i]);
}
}
return 0; //在整個表中都沒有找到,返回0
}
/*******************顯示所有的結點********************/
void SLALL(SLType *SL)
{
int i;
for(i=1;i<=SL->ListLen;i++)
{
cout<<"key:"<<SL->ListData[i].key<<",name:"<<SL->ListData[i].name<<",age:"<<SL->ListData[i].age<<endl;
}
}
int main()
{
int i;
SLType SL; //定義順序表變量
DATA data; //定義結點保存數據類型變量
DATA *pdata;//定義指向結點的指針變量
string name;
cout<<"順序表操作演示:"<<endl;
SLInit(&SL);//初始化順序表
do
{ //循環添加結點數據
cout<<"請輸入要添加的結點(學號 姓名 年齡):";
cin>>data.key>>data.name>>data.age;
if(data.age) //若年齡不為0
{
if(!SLAdd(&SL,data))//若添加結點失敗
{
break; //退出循環
}
}else
{
break;
}
}while(1);
cout<<"順序表中的結點順序為:" <<endl;
SLALL(&SL); //顯示所有的結點
cout<<"請輸入要取出的結點序號:";
cin>>i;
pdata=SLFindByNum(&SL,i);//按序號查找結點
if(pdata)
{
cout<<"第"<<i<<"個結點為:key:"<<pdata->key<<",name:"<<pdata->name<<",age:"<<pdata->age<<endl;
}
cout<<"請輸入要查找的姓名:";
cin>>name;
pdata=SLFindByCont(&SL,name);
if(pdata)
{
cout<<"key:"<<pdata->key<<",name:"<<pdata->name<<",age:"<<pdata->age<<endl;
}
cout<<"請輸入您要刪除的結點的序號:";
cin>>i;
if(SLDelete(&SL,i))
{
cout<<"數據刪除成功"<<endl;
SLALL(&SL);
}
cout<<"請輸入您要插入的結點的序號:";
cin>>i;
cout<<"請輸入第"<<i<<"號結點的key,name,以及age"<<endl;
cin>>data.key>>data.name>>data.age;
if(SLInsert(&SL,i,data))
{
cout<<"插入數據成功"<<endl;
SLALL(&SL);
}
return 0;
}
運行界面: