静态链表

#include <stdlib.h>
#include <stdio.h>
#define STATUS_OK 0
#define STATUS_FAILED -1
// 定义基本数据结构
// 1 利用大数组定义静态链表,数组由头结点,尾结点,已用链表,备用链表四部分构成
// 2 数组头结点:存放链表第一个结点的索引值
// 3 数组尾结点:存放备用链表第一个结点的索引值
#define MAXSIZE 10
typedef char ElemType;
typedef struct node {
    ElemType data;
    int cur;
}LNode;                                                                    // 定义结点名称
typedef LNode StaticLinkedList[MAXSIZE]; // 定义链表名称
// 常见操作:
// init - 核心
// insert - 核心
// delete - 核心
// find
// traverse
// length
// 初始化操作:本质是将一个大数组赋索引值,形成空的单链表的过程
// 赋值过程分为:
//     a. 头结点:备用链表的头结点索引位置,赋值为0,尾结点:链表的第一个结点的索引,赋值为0
//     b. 普通结点:指向数组下个元素的索引位置,索引值+1
void init(StaticLinkedList list) {
    for (int i = 0; i < MAXSIZE - 1; i++) {
        list[i].cur = i + 1; // 各个结点的指针指向下一数组序号
    }
    list[MAXSIZE - 1].cur = 0;
}
// 申请内存空间操作:
// 1 本质是将备用链表第一个结点取出,并更新备用链表第一个结点的指向
int malloc_node(StaticLinkedList list)
{
    int p = list[0].cur;                                   // 备用链表第一个结点的索引
    printf("malloc_node-1-p索引值:%d
", p);
    if (list[0].cur) {                                            // 是否非0,初始化以后,除了数组最后一个结点,都是非零。排除数组尾结点
        list[0].cur = list[p].cur;                      // 更新备用链表头结点索引
    }
    return p;
}
// 释放操作:
// 1 本质是将结点添加到备用链表的过程
void free_node(StaticLinkedList list, int k)    // 结点释放后,放到备用链表的第一个结点位置。头插法
{
    printf("free_node-1-p索引值:%d
", list[0].cur);
    list[k].cur = list[0].cur;                             // 原第一结点的指向赋给k结点的指向
    list[0].cur = k;                                              // 更新第一结点指向为索引值k
    printf("free_node-2-p索引值:%d
", list[0].cur);
}
// 插入操作:在初始化形成的空静态链表基础上进行插入
// 步骤:
// 1 从备用链表中拿出一个结点---->自定义malloc函数
// 2 将拿出的结点赋值后,链接到链表指定位置
int insert(StaticLinkedList list, int k, ElemType x)
{
    if (k < 1 || k > length(list) + 1) return;
    int p = MAXSIZE - 1;
    int j = malloc_node(list);
    if (j) {                                                             // 排除数组尾结点
        list[j].data = x;
        for (int i = 1; i < k; i++) {                   // for循环执行1次,p指向第1个元素的索引
            p = list[p].cur;
        }
        list[j].cur = list[p].cur;
        list[p].cur = j;
        return STATUS_OK;
    }
    return STATUS_FAILED;
}
// 删除结点:
// 1 找到该结点前一结点k-1, 将k+1结点的索引赋给k-1的向量
// 2 释放k结点
void delete_node(StaticLinkedList list, int k)
{
    if (k < 1 || k > length(list)) return;
    int p = MAXSIZE - 1;
    for (int i = 1; i < k; i++) {
        p = list[p].cur;
    }                                                                          // for循环结束后,p为k-1结点的index值
    int q = list[p].cur;                                   // q 为第k个结点
    list[p].cur = list[q].cur;                             // k+1 指向赋给 k-1
    free_node(list, q);
}
// 遍历链表
// 1 从第一个结点【数组尾结点所指向的结点】开始,依次遍历每个结点的数值
void traverse(StaticLinkedList list)
{
    int p = list[MAXSIZE - 1].cur;                                       // 链表第一个结点的索引
    while (p > 0)
    {
        printf("索引值:%d, 指针向量值:%d, 数据值:%c
", p, list[p].cur, list[p].data);
        p = list[p].cur;
    }
}
int length(StaticLinkedList list)
{
    int j = 0;
    int p = list[MAXSIZE - 1].cur;                                       // 链表第一个结点的索引
    while (p > 0)
    {
        p = list[p].cur;
        j++;
    }
    return j;
}
void traverseArray(StaticLinkedList list) {
    for (int i = 1; i < MAXSIZE; i++) {
        printf("索引值:%d, 指针向量值:%d, 数据值: %c
", i, list[i].cur, list[i].data);
    }
}
int main()
{
    StaticLinkedList list;
    int status;
    init(list);

    printf("Init finished, static link list length:%d 
", length(list));
    insert(list, 1, 'A');
    insert(list, 2, 'B');
    insert(list, 3, 'C');
    insert(list, 4, 'D');
    insert(list, 5, 'E');
    insert(list, 6, 'F');
    insert(list, 7, 'G');/*
    insert(list, 8, 'H');
    insert(list, 9, 'I');
    insert(list, 10, 'K');
    insert(list, 11, 'G');*/
    traverseArray(list);
    /*printf("=========================分割线=========================
");
    insert(list, 4, 'N');
    traverse(list);
    traverseArray(list);*/
    printf("=========================分割线=========================
");
    delete_node(list, 2);
    traverseArray(list);
    printf("=========================分割线=========================
");
    traverse(list);
}
原文地址:https://www.cnblogs.com/neen/p/13537912.html