C语言实现链表基本操作

C语言实现链表基本操作

代码如下:

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

typedef int ElemType;
// 定义结点类型(也可以说是定义链表结构)
typedef struct Node
{
    ElemType data;
    struct Node *next;
} LinkList; // Node, *LinkList;
    // Node表示结点的类型,*LinkList,表示指向Node节点类型的指针类型

    // 函数声明,若不声明可能会报错
LinkList *initList(LinkList *L);
LinkList *createList(int len);
int insertLinkList(LinkList *L, int pos, ElemType e);
int deleteLinkList(LinkList *L, int pos, ElemType *e);
void reverseLinkList(LinkList *L);
int searchLinkList(LinkList *L, ElemType e);
int getLen(LinkList *L);
int isEmpty(LinkList *L);
void printLinkList(LinkList *L);

int main()
{
    LinkList *L;
    ElemType e;
    int len, pos;
    printf("创建元素个数:");
    scanf("%d", &len);
    printf("\n请输入:");
    L = createList(len);
    printf("\n当前链表所有元素:");
    printLinkList(L);

    printf("\n插入位置和插入值(中间用空格隔开):");
    scanf("%d%d", &pos, &e);
    insertLinkList(L, pos, e);
    printf("\n插入元素后链表所有元素:");
    printLinkList(L);

    printf("\n请输入删除元素位置:");
    scanf("%d", &pos);
    deleteLinkList(L, pos, &e);
    printf("\n元素%d已删除", e);
    printf("\n删除后链表所有元素:");
    printLinkList(L);

    printf("\n请输入查找元素:");
    scanf("%d", &e);
    if (searchLinkList(L, e) != -1)
    {
        printf("\n%d位于:%d", e, searchLinkList(L, e));
    }
    else
        printf("\n%d未找到", e);

    reverseLinkList(L);
    printf("\n转置后链表所有元素:");
    printLinkList(L);

    return 0;
}

// 链表初始化,创建头节点
LinkList *initList(LinkList *L)
{
    L = (LinkList *) malloc(sizeof(LinkList)); // 为头节点分配空间
    L->next = NULL;                           // 头节点指针域置空
    return L;
}

// 创建指定个数的单链表
LinkList *createList(int len)
{
    int i;
    ElemType e;
    LinkList *L = initList(L), *r, *n; // 分别定义头指针、尾指针(独立于链表的指针,存在目的是为了指明新元素插入位置)、新指针(插入的新元素的指针)
    r = L;                             // 尾指针初始化为头指针
    for (i = 0; i < len; i++)
    {
        scanf("%d", &e);
        n = (LinkList *)malloc(sizeof(LinkList)); // 申请空间
        n->data = e;
        n->next = NULL; // 新指针指针域置空
        r->next = n;    // 将新指针链入单链表末尾
        r = r->next;    // 尾指针往后移
    }
    return L;
}

// 将新元素插入指定位置
int insertLinkList(LinkList *L, int pos, ElemType e)
{
    if (pos < 1 || pos > getLen(L) + 1) return 0;                             // 插入错误
    LinkList *r = L, *n;                      // 前面是访问头节点,后面是新建一个结构体n,代表插入的节点
    n = (LinkList *)malloc(sizeof(LinkList)); // 申请节点空间
    n->data = e;                              // 为节点赋值
    n->next = NULL;
    while (--pos > 0)
    {
        r = r->next; // 将尾指针移动到插入位置
    }
    n->next = r->next; // 将新指针(即将插入结构体的指针)赋值给尾指针
    r->next = n;
    return 0;
}

// 将指定位置元素删除
int deleteLinkList(LinkList *L, int pos, ElemType *e)
{
    if (pos < 1 || pos > getLen(L))
        return 0;        // 删除位置错误
    LinkList *r = L, *d; // r访问头节点,d访问删除节点并存储数据
    while (--pos > 0)
    {
        r = r->next; // 将为指针移动到删除位置
    }
    d = r->next;       // 删除元素节点
    *e = d->data;      // 保存删除元素值
    r->next = d->next; // 将尾指针跳过删除节点,链入下一个节点
    free(d);           // 释放删除节点
    return 0;
}

// 转置单链表:采用头插法
void reverseLinkList(LinkList *L)
{
    if (L == NULL || L->next == NULL)
        return ;//return L;                             // 链表为空或链表元素为1
    LinkList *r = L->next, *cur = NULL, *last = NULL; // 定义尾指针(访问头指针),欲插入指针,遍历指针
    cur = last= r->next;
    r = NULL;
    while (last != NULL)
    {
        last = last->next;       // last指向后一个节点(last作为遍历指针)
        cur->next = r; // cur指针,使当前节点指针域指向前一节点
        L->next =cur; //使头指针指向当前节点
        r = cur; // 向后移动r指针,往后的循环使原链表的元素指针指向前一个元素
        cur = last;       // 向后移动cur指针
    }
}

// 查找指定元素,返回指定元素位序
int searchLinkList(LinkList *L, ElemType e)
{
    if (isEmpty(L))
        return -1;
    int pos = 1; // 位序从1开始,下标从0开始
    LinkList *r = L->next;
    while (r)
    {
        if (r->data == e)
        {
            return pos; // 找到指定元素,返回位序
            // break;
        }
        r = r->next; // 指针后移
        pos++;
    }
    return -1; // 遍历完成仍未找到
}

// 获取链表长度
int getLen(LinkList *L)
{
    if (L->next == NULL)
        return 0;
    int len = 0;
    // LinkList *r = L;
    // while (r)
    // {
    //     r = r->next; // 指针后移
    //     len++;
    // }
    while (L){
        L = L->next;
        len++;
    }
    return len;
}

// 判断链表是否为空
int isEmpty(LinkList *L)
{
    return !L->next; // L->next == NULL也可以
}

// 打印链表
void printLinkList(LinkList *L)
{
    LinkList *r;
    r = L->next;
    while (r)
    {
        printf("%d -> ", r->data);
        r = r->next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sql1313

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值