线性表-链表

链表,包含插入、删除、查找、清空

#include <stdio.h>
#include <malloc.h>

typedef enum
{
    ERROR = 0,
    SUCCESS = 1,
} State;

typedef int Data;

/**
 * 节点
 */
typedef struct Node
{
    Data data;
    struct Node *next;
} *Node;

/**
 * 头节点
 */
typedef struct Head
{
    int length;
    Node next;
} *Head;

/**
 * 初始化链表
 * @return 返回初始化的链表
 */
Head initLinkedList()
{
    Head head = malloc(sizeof(struct Head));
    head->length = 0;
    head->next = NULL;
    return head;
}

/**
 * 根据下标获取链表元素
 * @param head 头结点
 * @param index 元素下标
 * @param data 查询到的元素
 * @return 操作状态
 */
State getEleByIndex(Head head, int index, Data *ele)
{
    if (head->length == 0 || index > head -> length - 1) {
        perror("index超出链表长度");
        return ERROR;
    }

    //定义临时指针和下标计数器
    Node point = head->next;
    int currentIndex = 0;

    //遍历链表
    while (point->next && currentIndex < head->length) {
        if (index == currentIndex) {
            *ele = point->data;
            return SUCCESS;
        }
        point = point->next;
        currentIndex++;
    }

    printf("未找到下标%d的元素", index);
    return ERROR;
}

/**
 * 向链表指定位置插入元素
 * @param head 头结点
 * @param index 插入的索引位置
 * @param ele 插入的元素
 * @return 操作状态
 */
State linkedInsert(Head head, int index, Data ele)
{
    //校验index
    if(index > head->length) {
        perror("index超出链表当前大小");
        return ERROR;
    }

    Node node = malloc(sizeof(struct Node));
    node->data = ele;

    //如果是空链表特殊处理
    if (head->length == 0) {
        node->next = head->next;
        head->next = node;
        head->length++;
        return SUCCESS;
    }

    if (index == 0) {
        node->next = head->next;
        head->next = node;
        head->length++;
        return SUCCESS;
    }

    //定义临时指针
    Node point = head->next;
    int currentIndex = 1;

    //将指针移动到index位置
    while (point->next && currentIndex < index) {
        point = point->next;
        currentIndex++;
    }

    //插入元素
    Node temp = point->next;
    node->next = temp;
    point->next = node;
    head->length++;
    return SUCCESS;
}

/**
 * 根据下标删除链表指定元素
 * @param head 头结点
 * @param index 下标
 * @param ele 删除的元素会被赋给这个指针
 * @return 操作状态
 */
State linkedDeleteByIndex(Head head, int index, Data *ele)
{
    //校验index
    if (head->length == 0 || index > head->length - 1) {
        perror("index超出链表长度");
        return ERROR;
    }

    //定义临时指针与计数器
    Node point = head->next;
    int currentIndex = 0;

    //如果删除头结点特殊处理
    if (index == 0) {
        Node temp = head->next;
        *ele = temp->data;
        head->next = head->next->next;
        head->length--;
        free(temp);
        return SUCCESS;
    }

    //找到index前一个node
    while (point) {
        if (currentIndex == index - 1) break;
        point = point->next;
        currentIndex++;
    }

    //删除节点,回收内存
    Node temp = point->next;
    *ele = temp->data;
    point->next = point->next->next;
    head->length--;
    free(temp);

    return SUCCESS;
}

/**
 * 清空链表
 * @param head 头结点
 * @return 操作状态
 */
State linkedClear(Head head)
{
    //判断链表是否有节点
    if (!head || head->length == 0) {
        perror("当前链表已为空");
        return ERROR;
    }

    //临时指针与计数器
    Node node = head->next;
    head->next = NULL;
    head->length = 0;

    //遍历链表删除节点,回收内存
    while (node) {
        Node temp = node;
        node = node->next;
        free(temp);
    }

    return SUCCESS;
}

int main() {
    Head head = initLinkedList();

    for (int i = 0; i < 10; i++) {
        linkedInsert(head, i, i + 1);
    }

    linkedInsert(head, 10, 100);

    Data ele;

    linkedDeleteByIndex(head, 10, &ele);

    printf("删除元素%d\n", ele);

    linkedClear(head);

    Node node = head->next;

    while (node) {
        printf("%d\n", node->data);
        node = node->next;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值