C循环单链表代码实现,主函数调用
引入了一个表头结点,同时循环单链表有表长以及表尾指针属性。表头结点不存放值,只存放指向第一个元素的指针域;同时表尾指针的next指向表头结点;即从链表任意位置出发都可以遍历完所有链表元素;
#include <stdio.h>
#include <stdlib.h>
typedef int ListItem; // 表元素类型
typedef ListItem *addr; // 表元素指针类型
#define eq(A, B) (A == B) // 元素相等
typedef struct node *link; // 表结点指针类型
typedef struct node
{
ListItem element; // 表元素
link next; // 指向下一个结点的指针域
} Node;
link NewNode() // 新建一个结点
{
return (link)malloc(sizeof(Node));
}
typedef struct clist *List;
typedef struct clist
{
int n; // 表长
link last; // 链表尾指针
} Clist;
List ListInit(); // 表结构初始化,返回一个结构体指针
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();
puts("List init success!");
if (ListEmpty(L) == 1)
puts("this is empty list.");
ListInsert(0, 11, L);
ListInsert(1, 22, L);
ListInsert(2, 33, L);
printf("List length is %d.\n", ListLength(L));
PrintList(L);
printf("ListLocate(33, L) is %d.\n", ListLocate(33, L));
printf("ListRetrieve(2, L) is %d.\n", ListRetrieve(2, L));
puts("-------------");
puts("after ListDelete(2,L)");
ListDelete(2, L);
PrintList(L);
return 0;
}
List ListInit() // 表结构初始化,返回一个结构体指针;创建一个带有表头结点空的循环链表,
{
List L = (List)malloc(sizeof *L);
link y = NewNode();
y->next = y;
L->last = y;
L->n = 0;
return L;
}
int ListEmpty(List L) // 测试表是否为空
{
return L->n == 0 ? 1 : 0;
}
int ListLength(List L) // 表L的长度
{
return L->n;
}
ListItem ListRetrieve(int k, List L) // 返回表L位置k的元素
{
int i = 1;
if (k < 1 || k > L->n)
return 0;
link p = L->last->next->next;
while (i < k)
{
p = p->next;
i++;
}
return p->element;
}
int ListLocate(ListItem x, List L) // 元素x在表L的位置
{
int i = 1;
link p = L->last->next->next; // 第一个位置元素
L->last->next->element = x; // 令表头结点的元素值等于x
while (p->element != x)
{
p = p->next;
i++;
}
return ((p == L->last->next) ? 0 : i);
}
void ListInsert(int k, ListItem x, List L) // 在表L索引k的位置插入元素x
{
if (k < 0 || k > L->n)
return;
link p = L->last->next;
for (int i = 1; i <= k; i++)
p = p->next;
link y = NewNode();
y->element = x;
y->next = p->next;
p->next = y;
if (k == L->n) // 表尾插入
L->last = y;
L->n++;
}
ListItem ListDelete(int k, List L) //从表L中删除位置k的元素
{
if (k < 1 || k > L->n)
return 0;
link q = L->last->next; // 表头结点,简化对删除第一个结点边界情况处理
for (int i = 0; i < k - 1; i++)
q = q->next;
link p = q->next; // k位置后一个结点
q->next = p->next; // k的后后结点为p的后结点,相当于跳过了p
if (k == L->n) // 删除表尾
L->last = q;
ListItem x = p->element;
free(p);
L->n--;
return x;
}
void ItemShow(ListItem x) // 输出表元素
{
printf("%d \n", x);
}
void PrintList(List L) // 按照位置次序输出表L中的元素
{
for (link p = L->last->next->next; p != L->last->next; p = p->next)
{
ItemShow(p->element);
}
}
result:
List init success!
this is empty list.
List length is 3.
11
22
33
ListLocate(33, L) is 3.
ListRetrieve(2, L) is 22.
-------------
after ListDelete(2,L)
11
33