c语言之单链表的基础操作(插入删除查找头插尾插)

c语言之单链表的基础操作(插入删除查找头插尾插)

有头结点

#include <stdio.h>
#include <stdlib.h> //malloc函数所需要的
struct Node
{
    // 定义一个结构体
    int data;          // 数据域
    struct Node *next; // 指针:指向node节点的指针,叫next,此处struct意为这是一个结构体,可以省略掉
};
typedef struct Node Node;      // 将结构体Node取了个名字叫做Node
typedef struct Node *Linklist; // 为这个单链表结构取了个名字叫做LinkList

// 初始化一个单链表,因为他有头结点,所以需要为头结点开辟一片空间
bool InitLinkList(Linklist &L)
{
    L = (Node *)malloc(sizeof(Node)); // 为头结点分配空间
    if (L == NULL)
    {
        // 用于检测是否分配成功
        return false;
    }
    L->next = NULL; // 头结点之后暂时还没有节点

    return true;
}

// 判断单链表是否为空
bool Empty(Linklist &L)
{
    return (L->next == NULL);
}

// 按位序插入,在表中L的第i个位置上面插入指定元素e
bool LinkInsert(Linklist &L, int i, int e)
{
    // 找到第i-1个节点,将新节点插入其后面
    Node *p = GetNum(L, e);
    return InsertNextNode(p, e);
}

// 给定节点的后插操作
bool InsertNextNode(Node *p, int e)
{
    if (p == NULL)
    {
        return false;
    }
    Node *s = (Node *)malloc(sizeof(Node));
    if (s == NULL)
    {
        return false; // 内存分配失败
    }
    s->data = e; // 将数据e保存到节点s中
    s->next = p->next;
    p->next = s; // 将节点s连接到p之后
    return true;
}

// 指定节点的前插操作
bool InsertPriorNode(Node *p, int e)
{
    if (p == NULL)
    {
        return false;
    }
    Node *s = (Node *)malloc(sizeof(Node *));
    if (s = NULL)
    {
        return false;
    }
    s->next = p->next;
    p->next = s;       // 新节点s连到p之后
    s->data = p->data; // 将p中的元素复制到s中
    p->data = e;       // p中元素覆盖为e
    return true;
}

// 按位序删除
bool ListDelete(Linklist &L, int i, int &e)
{
    Node *p = GetNum(L, e);
    if (p == NULL) // i值不合法
    {
        return false;
    }
    if (p->next == NULL) // 第i-1个节点之后已经没有节点了
    {
        return false;
    }
    Node *q = q->next; // 让q指向被删除节点
    e = q->data;       // 用e返回节点数据值
    p->next = q->next; // 将*q节点从链中断开
    free(q);           // 释放节点的存储空间
    return true;       // 删除成功
}

// 删除指定节点
bool DeleteNode(Node *p)
{
    // 如果p是最后一个节点,有bug,可能会扣分
    if (p == NULL)
    {
        return false;
    }
    Node *q = p->next;       // 令指针*q指向p的后继指针
    p->data = p->next->data; // 和后继节点交换数据域
    p->next = q->next;       // 将q节点从链中断开
    free(q);                 // 释放后继节点的存储空间
    return true;
}

// 按位查找,返回第i个元素
Node *GetNum(Linklist L, int i)
{
    if (i < 1)
    { // 传入的参数不合法
        return NULL;
    }
    Node *p;                       // 指针p指向当前扫描到的节点
    int j = 0;                     // 当前p指向的第几个节点
    p = L;                         // L指向节点,头结点是第0个节点
    while (p != NULL && j < i - 1) // 循环找到第i个节点
    {
        p = p->next;
        j++;
    }
    return p;
}

// 按值查找
Node *LocatNum(Linklist L, int e)
{
    Node *p = L->next;
    // 从第一个节点开始查找数据域为e的节点
    while (p != NULL && p->data != e)
    {
        p = p->next;
    }
    return p;
}

// 求表的长度
int Length(Linklist L)
{
    int len = 0;
    Node *p = L;
    while (p->next != NULL)
    {
        p = p->next;
        len++;
    }
    return len;
}


//尾插法建立单链表
Linklist List_TailInsert(Linklist &L){
    //正向建立单链表
    int x;
    L=(Linklist)malloc(sizeof(Node));//建立头结点,初始化空表
    Node *s,*r=L;//r为尾指针
    scanf("%d",&x);
    while (x!=9999)//输入9999表示结束
    {
        s=(Node *)malloc(sizeof(Node));
        s->data=x;
        r->data=x;
        r=s;
        scanf("%d",&x);
    }
    r->next=NULL;//尾节点指针置空
    return L;
}

//头插法建立单链表
Linklist List_HeadInsert(Linklist &L){
    //反向建立单链表
    Node *s;
    int x;
    L=(Linklist)malloc(sizeof(Node));//建立头结点
    L->next=NULL;//初始化空表
    scanf("%d",&x);
    while (x!=9999)//输入9999表示结束
    {
        s=(Node *)malloc(sizeof(Node));
        s->data=x;
        s->next=L->next;
        L->next=s;
        scanf("%d",&x);
    }
    return L;
}

void test()
{
    Linklist L; // 创建一个单链表
    InitLinkList(L);
}

无头结点

#include <stdio.h>
#include <stdlib.h> //malloc函数所需要的
struct Node
{
    // 定义一个结构体
    int data;          // 数据域
    struct Node *next; // 指针:指向node节点的指针,叫next,此处struct意为这是一个结构体,可以省略掉
};
typedef struct Node Node;      // 将结构体Node取了个名字叫做Node
typedef struct Node *Linklist; // 为这个单链表结构取了个名字叫做LinkList

// 初始化一个单链表
bool InitLinkList(Linklist &L)
{
    L = NULL;
    // 将其置为空表,防止脏数据
    return true;
}

// 判断单链表是否为空
bool Empty(Linklist &L)
{
    return (L == NULL);
}

// 按位序插入,在表中L的第i个位置上面插入指定元素e
bool LinkInsert(Linklist &L, int i, int e)
{
    // 找到第i-1个节点,将新节点插入其后面
    // 因为不带头结点,所以插入第一个节点的操作与其他节点操作不同
    if (i == 1)
    {
        Node *s = (Node *)malloc(sizeof(Node));
        s->next = NULL;
        s->data = e;
        L = s; // 头指针指向新节点
        return true;
    }
    Node *p = GetNum(L, e);
    return InsertNextNode(p, e);
}

// 给定节点的后插操作
bool InsertNextNode(Node *p, int e)
{
    if (p == NULL)
    {
        return false;
    }
    Node *s = (Node *)malloc(sizeof(Node));
    if (s == NULL)
    {
        return false; // 内存分配失败
    }
    s->data = e; // 将数据e保存到节点s中
    s->next = p->next;
    p->next = s; // 将节点s连接到p之后
    return true;
}

// 指定节点的前插操作
bool InsertPriorNode(Node *p, int e)
{
    if (p == NULL)
    {
        return false;
    }
    Node *s = (Node *)malloc(sizeof(Node *));
    if (s = NULL)
    {
        return false;
    }
    s->next = p->next;
    p->next = s;       // 新节点s连到p之后
    s->data = p->data; // 将p中的元素复制到s中
    p->data = e;       // p中元素覆盖为e
    return true;
}

// 按位序删除
bool ListDelete(Linklist &L, int i, int &e)
{

    if (L == NULL)
    {
        return false;
    }
    if (i = 1)
    {
        e = L->data;
        Node *a = L;
        L = L->next;
        free(a);
        return true;
    }
    Node *p = GetNum(L, e); // 指针p指向当前扫描到的节点
    if (p == NULL)          // i值不合法
    {
        return false;
    }
    if (p->next == NULL) // 第i-1个节点之后已经没有节点了
    {
        return false;
    }
    Node *q = q->next; // 让q指向被删除节点
    e = q->data;       // 用e返回节点数据值
    p->next = q->next; // 将*q节点从链中断开
    free(q);           // 释放节点的存储空间
    return true;       // 删除成功
}

// 删除指定节点
bool DeleteNode(Node *p)
{
    // 如果p是最后一个节点,有bug,可能会扣分
    if (p == NULL)
    {
        return false;
    }
    Node *q = p->next;       // 令指针*q指向p的后继指针
    p->data = p->next->data; // 和后继节点交换数据域
    p->next = q->next;       // 将q节点从链中断开
    free(q);                 // 释放后继节点的存储空间
    return true;
}

// 按位查找,返回第i个元素
Node *GetNum(Linklist L, int i)
{
    Node *p;                       // 指针p指向当前扫描到的节点
    int j = 1;                     // 当前p指向的第几个节点
    p = L;                         // L指向节点,头结点是第0个节点
    while (p != NULL && j < i - 1) // 循环找到第i个节点
    {
        p = p->next;
        j++;
    }
    return p;
}

// 按值查找
Node *LocatNum(Linklist L, int e)
{
    Node *p = L->next;
    // 从第一个节点开始查找数据域为e的节点
    while (p != NULL && p->data != e)
    {
        p = p->next;
    }
    return p;
}

// 求表的长度
int Length(Linklist L)
{
    int len = 0;
    Node *p = L;
    while (p->next != NULL)
    {
        p = p->next;
        len++;
    }
    return len + 1;
}

// 头插法插入节点
bool HeadInsert(Linklist &L, int e)
{
    Node *s = (Node *)malloc(sizeof(Node));
    if (s == NULL)
    {
        return false; // 内存分配失败
    }
    s->data = e;
    s->next = L; // 将新节点s插入到链表头部
    L = s;       // 更新链表头指针
    return true;
}

// 尾插法插入节点
bool TailInsert(Linklist &L, int e)
{
    Node *s = (Node *)malloc(sizeof(Node));
    if (s == NULL)
    {
        return false; // 内存分配失败
    }
    s->data = e;
    s->next = NULL; // 尾部插入新节点时,将其next指针置空
    if (L == NULL)
    {
        L = s; // 空链表时直接将新节点作为头节点
    }
    else
    {
        Node *p = L;
        while (p->next != NULL)
        {
            p = p->next; // 找到尾节点
        }
        p->next = s; // 将新节点连接到尾节点后
    }
    return true;
}

void test()
{
    Linklist L; // 创建一个单链表
    InitLinkList(L);
}
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值