带头结点的单链表实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define eleType int
//定义链表节点结构体
typedef struct Node {
    eleType data;//数据域
    struct Node* next;//指针域,指向下一结点的地址
}Node,*List;
// 初始化链表节点,即申请一个头节点
void InitList(List* L)
{
    *L = (Node*)malloc(sizeof(Node));
    (*L)->next = NULL;
}
//链表销毁
void DestoryList(List* L)
{
    Node* p = *L;//创建一个结点指向链表的头结点
    Node* q;
    while (p!=NULL)
    {
        q = p;//用q指向结点p
        p = p->next;//p指向下一个结点
        free(q);//释放结点q,从头结点一直到最后一个结点
    }
    *L = NULL;
}
//头插法,在链表头部插入元素
void HeadInsert(List* L, eleType e)
{
    Node* p = (Node*)malloc(sizeof(Node));
    p->data = e;
    p->next = (*L)->next;
    (*L)->next = p;
}
//尾插法,在链表尾部插入元素
void TailInsert(List* L, eleType e)
{
    Node* p=*L;
    Node* q = (Node*)malloc(sizeof(Node));
    q->data = e;
    q->next = NULL;
    while (p->next != NULL)
    {
        p = p->next;
    }
    p->next = q;
}
//在指定位置i插入元素e
void ListInsert(List* L, int i, eleType e)
{
    if (i < 1)
    {
        printf("插入失败\n");
        return;
    }
    Node* p = *L;
    int j = 0;
    while (p!=NULL&& j < i - 1)
    {
        p = p->next;
    }
    if (p == NULL) { 
        // 插入位置超出链表长度,使用尾插法
        TailInsert(&*L, e);
        return;
    }
    Node* q = (Node*)malloc(sizeof(Node));
    q->data = e;
    q->next = p->next;
    p->next = q;
}
//删除链表指定结点,返回删除的值
eleType ListDelete(List* L,Node* p)
{
    if (p == NULL || *L == NULL) {
        return NULL; // 节点为空或链表为空,无法删除
    }
    eleType element = p->data;
    if (p->next == NULL) { // 要删除的节点是尾节点
        if (*L == p) { // 只有一个节点的情况
            free(p);
            *L = NULL;
        }
        else {
            Node* q = *L;
            while (q->next != p) {
                q = q->next;
            }
            q->next = NULL; // 将倒数第二个节点的next指针置为NULL
            free(p); // 释放尾节点的内存
        }
    }
    else { // 要删除的节点不是尾节点
        Node* q = p->next;
        p->data = q->data;
        p->next = q->next;
        free(q);
    }

    return element;
}
//修改指定位置的元素
void ModifyNode(List* L, int i, eleType e)
{
    if (i < 1)
    {
        printf("修改失败\n");
        return;
    }
    Node* p = *L;
    int j = 0;
    while (p != NULL && j < i - 1)
    {
        p = p->next;
        j++;
    }
    if (p == NULL || p->next == NULL) {
        printf("修改失败,指定位置不存在\n");
        return;
    }
    p->next->data = e;
    printf("修改成功\n");
}
//按位查找返回元素
eleType GetElement(List L, int i)
{
    if (i < 1)
    {
        printf("指定位置不存在\n");
        return NULL;
    }
    Node* p = L;
    int j = 0;
    while (p != NULL && j < i - 1)
    {
        p = p->next;
    }
    if (p->next == NULL || p == NULL) {
        printf("指定位置不存在\n");
        return NULL;
    }
    return p->next->data;
}
//按值查找返回结点
Node* LocalElement(List L, eleType e)
{
    Node* p= (Node*)malloc(sizeof(Node));
    p = L;
    while (p != NULL &&p->data!=e)
    {
        p = p->next;
    }
    return p;
}
//统计链表长度
int ListLength(List L)
{
    if (L->next == NULL)
        return 0;
    int length = 0;
    Node* p = L->next;
    while (p!=NULL)
    {
        p = p->next;
        length++;
    }
    return length;
}
//打印链表
void PrintList(List L)
{
    if (L->next == NULL)
    {
        printf("该链表为空\n");
        return;
    }
    Node* p = L->next;
    while (p != NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}
int main()
{
    List L;
    InitList(&L);

    HeadInsert(&L, 1);
    HeadInsert(&L, 2);
    TailInsert(&L, 3);
    TailInsert(&L, 4);
    ListInsert(&L, 3, 5);

    printf("链表长度: %d\n", ListLength(L));
    printf("链表元素: ");
    PrintList(L);

    Node* nodeToModify = LocalElement(L, 3);
    if (nodeToModify) {
        ModifyNode(&L, 3, 6);
        printf("修改后的链表元素: ");
        PrintList(L);
    }

    Node* nodeToDelete = LocalElement(L, 2);
    if (nodeToDelete) {
        eleType deletedElement = ListDelete(&L, nodeToDelete);
        printf("删除元素: %d\n", deletedElement);
        printf("修改后的链表元素: ");
        PrintList(L);
    }

    DestoryList(&L);

    return 0;
}
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值