跳转至

线性链表基础操作

从多项式运算场景中抽取出通用的线性链表操作层,包含初始化、结点分配、首结点插入/删除、清空、追加、销毁等基础功能。

链表采用头尾指针 + 长度计数的结构体管理,便于多项式等场景中快速定位表尾。

完整代码

#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef struct
{
    float coef;
    int expn;
} term, elemtype;

typedef struct lnode
{
    elemtype data;
    struct lnode *next;
} lnode, *link, *position;

typedef struct
{
    link head, tail;
    int len;
} linklist;

typedef linklist polynomial;
typedef int status;

status InitList(linklist *L)
{
    link p;
    p = (link)malloc(sizeof(lnode));
    if (p)
    {
        p->next = NULL;
        (*L).head = (*L).tail = p;
        (*L).len = 0;
        return OK;
    }
    else
        return ERROR;
}

status MakeNode(link *p, elemtype e)
{
    (*p) = (link)malloc(sizeof(lnode));
    if (!(*p)) return ERROR;
    (*p)->data = e;
    return OK;
}

status InsFirst(linklist *L, link h, link s)
{
    s->next = h->next;
    h->next = s;
    if (h == (*L).tail)
        (*L).tail = h->next;
    (*L).len++;
    return OK;
}

status DelFirst(linklist *L, link h, link *q)
{
    if (*q)
    {
        h->next = (*q)->next;
        if (!h->next)
            (*L).tail = h;
        (*L).len--;
        return OK;
    }
    else
        return FALSE;
}

status ClearList(linklist *L)
{
    link p, q;

    if (L->head != L->tail)
    {
        p = q = L->head->next;
        L->head->next = NULL;

        while (p != L->tail)
        {
            p = q->next;
            free(q);
            q = p;
        }

        free(q);

        L->tail = L->head;
        L->len = 0;
    }
    return OK;
}

position GetHead(linklist *L)
{
    return L->head;
}

position NextPos(link p)
{
    return p->next;
}

position PriorPos(linklist L, link p)
{
    link q;
    q = L.head;

    while (q->next != p)
        q = q->next;
    return q;
}

void FreeNode(link *p)
{
    free((*p));
    (*p) = NULL;
}

status ListEmpty(linklist L)
{
    return L.len == 0;
}

elemtype GetCurElem(link p)
{
    return p->data;
}

status Append(linklist *L, link s)
{
    int i = 1;
    (*L).tail->next = s;
    while (s->next)
    {
        i++;
        s = s->next;
    }
    (*L).tail = s;
    (*L).len += i;
    return OK;
}

void DestroyPolyn(linklist *L)
{
    ClearList(L);
    FreeNode(&(*L).head);
    (*L).tail = NULL;
    (*L).len = 0;
}

linklist 结构体同时记录 head(头结点)、tail(尾结点)和 len(长度)。InsFirst 在指定结点之后插入,并自动维护 tailDelFirst 删除指定结点之后的首个结点。Append 将一段链表整段拼接到尾部。DestroyPolyn 先清空数据结点再释放头结点。