C循环链表代码实现,主函数调用

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

猜你喜欢

转载自blog.csdn.net/qq_44880154/article/details/113723993