硬核:
靜態鏈表的基本操作,底層實現
#include<cstdio>
#include<cstdlib>
#define MAXSIZE 1000 //鏈表的最大長度
#define ElemType int
#define Status int
using namespace std;
//靜態鏈表的結構(數據域、遊標)
typedef struct {
ElemType data; //數據域
int cur; //遊標域或者指針域
}component,SLinkList[MAXSIZE];
//創建備用列表
void InitSpace_SL(SLinkList &space){
//將一維數組space中分量鏈成一個備用備用鏈表,space[0].cur 爲備用頭指針
//“0”表示空指針
for(int i=0;i<MAXSIZE-1;i++){
space[i].cur = i+1; //將每個數組分量鏈接到一起
}
//最後一個指針爲0
space[MAXSIZE-1].cur = 0;
}
//提取分配空間(申請一個空閒結點)
int Malloc_SL(SLinkList &space){
//若備用空間鏈表非空,則返回分配的結點下標,否則返回0
int i = space[0].cur;
if(space[0].cur)
space[0].cur = space[i].cur;
return i;
}
//釋放空閒結點
void Free_SL(SLinkList &space, int k){
//將下標爲k的空閒結點回收到備用鏈表
space[k].cur = space[0].cur; //回收結點的“遊標”指向備用鏈表的頭結點之後節點(即第一個結點)
space[0].cur = k; //備用鏈表的頭結點指向新回收的結點
}
//創建靜態鏈表(書上的,就是標記最後一個結點的遊標爲0)
void CreatList_SL(SLinkList &space,int n){
InitSpace_SL(space); //初始化備用空間
int S = MAXSIZE-1;
//將數組最後一個結點當做靜態鏈表(非備用鏈表)的頭結點
int r=S; //r指向當前鏈表的最後結點
for(int j=1;j<=n;j++){ //建立鏈表
int i = Malloc_SL(space); //分配結點
scanf("%d",&space[i].data); //輸入元素值
space[r].cur = i; //插入到表尾
r=i; //更新表尾
}
space[r].cur = 0; //尾結點的指針爲空
printf("創建成功\n");
}
//獲取靜態鏈表長度
int LengthList_SL(SLinkList space){
int i=space[MAXSIZE-1].cur,count=0;
while(i){
i=space[i].cur;
count++;
}
printf("長度爲:%d\n",count);
return count;
}
//遍歷靜態鏈表
void TraverseList_SL(SLinkList space){
printf("遍歷鏈表:");
int i = space[MAXSIZE-1].cur; //i指向表中的第1個結點的位序
while(i) { //遍歷
printf("%d ",space[i].data);
i = space[i].cur; //指向下一個元素
}
printf("\n");
}
//在靜態鏈表中查找第1個值爲e的元素
void LocateElem_SL(SLinkList space,ElemType e){
int i = space[MAXSIZE-1].cur; //i指向表中的第1個結點的位序
int local = 1; //初始化其序爲1
while(i && (space[i].data != e)){ //當結點存在並且數據域不等於e
i = space[i].cur; //指向下一個元素
local++; //位序加1
}
if(i==0){ //如果i已經到了最後一個元素的遊標(爲0)則說明前面沒有符合要求的元素值
printf("該元素不存在\n");
}else{
printf("第一個值爲%d的位序爲:%d\n",e,local);
}
}
//用e返回線性表中第i個元素的值
void GetList_SL(SLinkList space,int i){
int s=space[MAXSIZE-1].cur;
int j=1;
while(s && j<i){
s=space[s].cur;
j++;
}
if(s==0){ //如果i已經到了最後一個元素的遊標(爲0)則說明前面沒有符合要求的元素值
printf("位序錯誤\n");
}else{
printf("第%d個元素的值爲:%d\n",i,space[s].data);
}
}
//清空鏈表
void ClearList_SL(SLinkList &space){
int i = space[MAXSIZE-1].cur;
while(i){
int j = i;
i = space[i].cur;
Free_SL(space,j);
}
space[MAXSIZE-1].cur = 0;
printf("清空鏈表成功\n");
}
//在L中第i個元素之前插入數據元素e
Status ListInsert_SL(SLinkList &space,int i,ElemType e){
if(i<1 || i> LengthList_SL(space)+1){ //檢查插入位置是否正確
printf("插入位置錯誤\n");
return 0;
}
int j = Malloc_SL(space); //申請新結點
int k = MAXSIZE-1;
if(j){ //如果結點申請成功
space[j].data = e; //賦值給結點
for(int l=1;l<i;l++){ //找到第i-1個結點
k = space[k].cur; //指向下一個結點
}
space[j].cur = space[k].cur; //新結點指向第i-1個元素後的元素
space[k].cur = j; //第i-1個元素指向新結點
}
printf("插入成功\n");
return 0;
}
//刪除L中第i個元素,並返回其值
Status ListDelete_SL(SLinkList &space,int i,ElemType e){
if(i<1 || i> LengthList_SL(space)){ //檢查插入位置是否正確
printf("刪除位置錯誤\n");
return 0;
}
int k = MAXSIZE-1;
for(int l=1;l<i;l++){ //找到第i-1個結點
k = space[k].cur; //指向下一個結點
}
int j = space[k].cur; //j爲將刪除的結點
space[k].cur = space[j].cur; //將i-1結點的指針域和i+1的指針域連接起來
e = space[j].data; //賦值e
Free_SL(space,j);
printf("刪除%d個元素%d成功\n",i,e);
return 0;
}
//查找前驅 cur_e不是第一個元素
Status PriorElem_SL(SLinkList space,ElemType cur_e,ElemType pre_e){
int i = space[MAXSIZE-1].cur;
if(cur_e == space[i].data){
printf("第一個元素沒有前驅\n");
return 0;
}
while(i && cur_e != space[i].data){
pre_e = space[i].data; //將前驅結點置爲當前結點
i = space[i].cur; //指向下一個結點
}
if(i==0){
printf("該元素不存在\n");
}else{
printf("%d的前驅是%d\n",cur_e,pre_e);
}
return 0;
}
//查找後繼元素 cur_e不是最後一個元素
Status NextElem_Sq(SLinkList space,ElemType cur_e,ElemType next_e){
int i = space[MAXSIZE-1].cur;
int j; //用j標記查找的結點
while(i && cur_e != space[i].data){
i = space[i].cur; //指向下一個結點
}
if(i==0){
printf("該元素不存在\n");
}else{
i = space[i].cur;
if(i==0){
printf("最後一個元素沒有後繼\n");
}else{
next_e = space[i].data;
printf("%d的後繼是%d\n",cur_e,next_e);
}
}
return 0;
}
//判斷是否爲空
bool EmptyList_SL(SLinkList space){
if(space[MAXSIZE-1].cur==0){ //判斷其鏈表的頭指針的遊標是否爲0
printf("鏈表爲空\n");
return true;
}else{
printf("鏈表不爲空\n");
return false;
}
}
int main(){
SLinkList space;
int n,a,b,d,e,f,g,h,i,j,k;
printf("請輸入建立鏈表的元素個數:\n");
scanf("%d",&n); //輸入鏈表的個數
CreatList_SL(space,n);
// EmptyList_SL(space);
// LengthList_SL(space);
TraverseList_SL(space);
// printf("請輸入查找的元素值:");
// scanf("%d",&a); //輸入查找的元素值
// LocateElem_SL(space,a);
// printf("請輸入查找的位序:");
// scanf("%d",&b); //輸入查找的位序
// GetList_SL(space,b);
// ClearList_SL(space);
// TraverseList_SL(space);
// EmptyList_SL(space);
// printf("請輸入插入的位序和值:");
// scanf("%d%d",&d,&e); //輸入插入的位序和值
// ListInsert_SL(space,d,e);
// TraverseList_SL(space);
// LengthList_SL(space);
// printf("請輸入刪除的位序:");
// scanf("%d",&f);
// ListDelete_SL(space,f,g);
// TraverseList_SL(space);
// LengthList_SL(space);
// printf("請輸入查找的元素(返回其前驅):");
// scanf("%d",&h);
// PriorElem_SL(space,h,i);
printf("請輸入查找的元素(返回其後繼):");
scanf("%d",&j);
NextElem_Sq(space,j,k);
return 0;
}