/** 靜態鏈表是用數組描述的鏈表,也叫游標表示法。是為了解決沒有指針的語言
* 數組的第一個和最后一個元素作為特殊元素處理,不存數據
* 第一個元素:存放備用鏈表第一個節點的下標
* 最后一個元素:則存放第一個有數據元素的下標,相當于單鏈表的頭結點的作用
*/
/** 優缺點
* 優:在插入和刪除操作時,只需要修改游標,不需要移動元素
* 從而改進了在順序存儲結構中插入和刪除操作需要移動大量元素的缺點
*
* 缺:1.連續存儲分配的表長度難以解決的問題沒有解決
* 2.失去了順序存儲結構隨機存儲的特性
*/
下面查看靜態鏈表的幾種狀態
初始狀態
順序插入數據后
在乙和丁之間插入丙
刪除數據后的狀態
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100
typedef int Status;
typedef int ElemType;
typedef struct node {
ElemType data;
int cur;
} Component,StaticLinkList[MAXSIZE];
/** 初始化的時候 為了確保是空鏈表 將第一個數據的下標職位0, 在求鏈表長度的時候有用*/
Status InitStaticList(StaticLinkList space) {
int i = 0;
for (i = 0; i < MAXSIZE-1; i++) {
space[i].cur = I+1;
}
space[MAXSIZE-1].cur = 0;
return OK;
}
//取出空閑結點的第一個來使用, 并將第一個空閑結點的下一個的結點作為備用鏈表的第一個位置存儲
int Malloc_Index(StaticLinkList space) {
int i = space[0].cur;
if (i) {
space[0].cur = space[i].cur;
}
return I;
}
Status Insert_element(StaticLinkList space, int i,ElemType e) {
if (i > MAXSIZE-1 || space[0].cur > MAXSIZE-1) {
return ERROR;
}
int k = MAXSIZE-1;
int tempIndex = Malloc_Index(space);
space[tempIndex].data = e;
if (tempIndex) {
for (int j = 1; j <= i-1; j++) {
k = space[k].cur;
}
space[tempIndex].cur = space[k].cur; //此處類似于頭插法,將下標0 永遠放在最后一個結點的next上
space[k].cur = tempIndex;
return OK;
}
return ERROR;
}
/** 將原來空閑的第一個結點作為要刪除結點的next也就是成了空閑的第二個結點, 然后將要刪除的節點作為第一個空閑結點*/
void Free_Node(StaticLinkList space, int k) {
space[k].cur = space[0].cur;
space[0].cur = k;
}
/** 這個求長度有意思,是怎么變成0的呢?因為初始化空鏈表的時候 將空鏈表的下標置為了0 */
int ListLength(StaticLinkList list) {
int j = 0;
int i = list[MAXSIZE-1].cur;
while (i) {
i = list[i].cur;
j++;
}
return j;
}
/** 需要兩個下標,一個指向當前結點,一個指向當前的前一個結點*/
Status Delete_element2(StaticLinkList space, int i, ElemType e) {
if (i > MAXSIZE-1 || ListLength(space) < i) {
return ERROR;
}
int k = MAXSIZE-1;
int previous = space[k].cur;
for (int j = 1; j < i; j++) {
previous = k;
k = space[k].cur;
}
space[previous].cur = space[k].cur;
Free_Node(space, k);
return OK;
}
Status Delete_element(StaticLinkList space, int i, ElemType e) {
if (i > MAXSIZE-1 || ListLength(space) < i) {
return ERROR;
}
int k1,k2;
k1 = MAXSIZE-1;
//k1代表將要刪除結點的上一個結點的下標
for (int j = 1; j <= i-1; j++) {
k1 = space[k1].cur;
}
k2 = space[k1].cur;
space[k1].cur = space[k2].cur;
Free_Node(space, k2);
return OK;
}
void Iterate_StaticList(StaticLinkList space) {
int minIndex = space[MAXSIZE-1].cur;
int k = minIndex;
int maxLength = ListLength(space);
for (int i = 0; i < maxLength; i++) {
printf("++++++current data: %d,%d\n",space[k].data,k);
k = space[k].cur;
}
}
#pragma mark - 使用
void k_StaticNode(void) {
StaticLinkList list;
InitStaticList(list);
//順序插入元素
for (int i = 1; i < 10; i++) {
Insert_element(list, i, i);
}
Iterate_StaticList(list);
//在指定位置插入元素
printf("\n\n");
Insert_element(list, 5, 14);
Insert_element(list, 9, 12);
Iterate_StaticList(list);
//在指定位置刪除元素
printf("\n\n");
Delete_element(list, 6, 0);
Iterate_StaticList(list);
}