C间接寻址法实现表代码,主函数调用
将原来数组存储元素的地方存放 为指向元素的指针,通过元素的指针间接的访问元素,故又称间接寻址法。其在添加元素和删除元素时移动的数组元素从可能占用空间很庞大的元素变成指向元素的指针(相对来说指针大小固定,在每一个元素占用存储空间较大时,指针移动更快些)。
间接寻址法优化重点是数组增加和删除时移动的是指向元素的指针,而不是元素本身。
即操作的其实是一个指针数组,其中每一个数组元素是指向表元素的指针。
#include <stdio.h>
#include <stdlib.h> // malloc
typedef int ListItem; // 表元素类型
typedef ListItem *addr; // 表元素指针类型
#define eq(A, B) (A == B) // 元素相等
// 数组里面放指向结点的指针,方便存取与修改结点。
typedef struct indlist *List; // 间接寻址法实现的表指针
typedef struct indlist
{
int n, // 表长
curr; // 当前位置
int maxsize; // 数组上界
addr *table; // 存储表元素指针的数组,指针数组,即数组元素是指针。
} indlist;
addr NewNode() // 返回一个表元素指针
{
return (addr)malloc(sizeof(addr));
}
List ListInit(int size); // 表结构初始化,返回一个结构体指针
int ListEmpty(List L); // 测试表是否为空
int ListLength(List L); // 表L的长度
ListItem ListRetrieve(int k, List L); // 返回表L位置k的元素
int ListLocate(ListItem x, List L); // 元素x在表L的位置
void ListInsert(int k, ListItem x, List L); // 在表L索引k的位置插入元素x
ListItem ListDelete(int k, List L); //从表L中删除位置k的元素
void PrintList(List L); // 按照位置次序输出表L中的元素
void ItemShow(ListItem x); // 输出表元素
int main(int argc, char const *argv[])
{
List L = ListInit(5);
if (ListEmpty(L) == 1)
puts("List is Empty!");
puts("After ListInsert(0, 11, L) .....");
ListInsert(0, 11, L);
ListInsert(1, 22, L);
ListInsert(2, 33, L);
PrintList(L);
printf("List length is %d.\n", ListLength(L));
printf("ListLocate(22, L) is %d.\n", ListLocate(22, L));
printf("ListRetrieve(1, L) is %d.\n", ListRetrieve(1, L));
puts("------------------------");
ListDelete(3, L);
puts("After ListDelete(3, L)");
PrintList(L);
printf("List length is %d.\n", ListLength(L));
return 0;
}
List ListInit(int size) // 表结构初始化,返回一个结构体指针;主要创建 size大小的数组
{
List L = (List)malloc(sizeof *L);
L->n = 0;
L->curr = 0;
L->maxsize = size;
L->table = (addr *)malloc(size * sizeof(addr));
return L;
}
int ListEmpty(List L) // 测试表是否为空
{
return L->n == 0;
}
int ListLength(List L) // 表L的长度
{
return L->n;
}
ListItem ListRetrieve(int k, List L) // 返回表L位置k的元素值
{
if (k < 1 || k > L->n)
return 0;
return *(L->table[k - 1]); // [] 优先级大于 * ,所以先和L->table 结合;table是一个指针数组,所以对指针元素取值就是要返回的结点值
}
int ListLocate(ListItem x, List L) // 元素x在表L的位置(比起索引多1)
{
for (int i = 0; i < L->n; i++)
if (*(L->table[i]) == x)
return ++i;
return 0;
}
void ListInsert(int k, ListItem x, List L) // 在表L索引k的位置插入元素x, 将k位置后的元素往后挪给x腾出位置,表长+1
{
if (k < 0 || k > L->n)
return;
for (int i = L->n - 1; i >= k; i--)
L->table[i + 1] = L->table[i];
L->table[k] = NewNode();
*(L->table[k]) = x;
L->n++;
}
ListItem ListDelete(int k, List L) //从表L中删除位置k(索引为k-1)的元素,返回被删除的元素;将k位置后元素往前移填补被删除的位置,表长-1
{
if (k < 1 || k > L->n)
return 0;
addr p = L->table[k - 1]; // k-1 是位置 k的索引值
ListItem x = *p;
for (int i = k; i < L->n; i++)
L->table[i - 1] = L->table[i];
L->n--;
free(p);
return x;
}
void ItemShow(ListItem x) // 输出表元素
{
printf("%d \n", x);
}
void PrintList(List L) // 按照位置次序输出表L中的元素
{
for (int i = 0; i < L->n; i++)
ItemShow(*L->table[i]);
}
result:
List is Empty!
After ListInsert(0, 11, L) .....
11
22
33
List length is 3.
ListLocate(22, L) is 2.
ListRetrieve(1, L) is 11.
------------------------
After ListDelete(3, L)
11
22
List length is 2.