单链表的创建、插入、删除和反转操作

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct List
{

    ElemType data;      //数据域
    struct List *next;  //指针域
} Node, *LinkedList;

//头插法创建链表,将新增节点插头第一个节点之前
LinkedList createH()
{
    Node *L = (Node *)malloc(sizeof(Node));     //申请一个数据域为空的头节点
    if(L == NULL)
    {
        printf("分配空间失败!\n");
        exit(0);
    }
    L->next = NULL;
    int nodeNum;
    printf("输入节点数量: ");
    scanf("%d",&nodeNum);
    printf("\n");
    printf("输入节点数据: ");
    for(int i=0; i<nodeNum; i++)        //依次插入节点
    {
        ElemType data;
        scanf("%d",&data);
        Node *p = (Node *)malloc(sizeof(Node));     //申请节点空间
        if(p == NULL)
        {
            printf("分配空间失败!\n");
            exit(0);
        }
        p->data = data;
        p->next = L->next;          //头结点指向新增节点
        L->next = p;                //新增节点指向第一个节点
    }
    return L;                       //返回头节点

}


//尾插法建立链表,新增节点插入最后一个节点之后
LinkedList createT()
{
    Node *L, *pre;
    L = (Node*)malloc(sizeof(Node));         //为头结点申请空间
    if(L == NULL)                           //判断是否申请失败
    {
        printf("申请内存失败!\n");
        exit(0);
    }
    L->next = NULL;
    pre = L;                                //pre始终指向链表尾部
    int nodeNum;
    printf("输入节点数量: ");
    scanf("%d",&nodeNum);
    printf("\n");
    printf("输入节点数据: ");
    ElemType data;
    for(int i=0; i<nodeNum; i++)
    {
        scanf("%d",&data);
        Node *p = (Node *)malloc(sizeof(Node));     //为新增节点分配空间
        if(p == NULL)
        {
            printf("申请内存失败!\n");
            exit(0);
        }
        p->data = data;
        p->next = NULL;
        pre->next = p;          //新增节点插入链表尾部
        pre = pre->next;        //pre移到尾部
    }
    return L;
}





//在指定位置插入节点
void insertNode(LinkedList L)
{
    int pos;                //插入位置
    ElemType data;          //插入节点数据
    printf("输入插入位置, 插入节点的数据: ");
    scanf("%d %d",&pos,&data);
    LinkedList p = L;       //指针p查找插入位置
    int cnt = 0;
    while(cnt<pos)
    {
        if(p->next == NULL && cnt<pos)      //判断插入位置是否大于链表长度
        {
            printf("超出链表长度\n");
            return;
//            exit(0);
        }
        p = p->next;            //指针p一直滑动到要插入的位置
        cnt++;
    }

    Node *r = (Node *)malloc(sizeof(Node));     //为插入节点申请空间
    r->data = data;
    r->next = p->next;              //插入链表对应位置
    p->next = r;
}

//删除链表中的一个数据为x的节点
void deleteNode(LinkedList L)
{

    ElemType data;
    printf("输出要删除的数据: ");
    scanf("%d",&data);
    LinkedList p = L;     //p节点进行查找
    LinkedList r = L->next;     //r表示p节点后的一个节点
    if(L->next==NULL)           //判断链表是否为空
    {
        printf("链表为空!\n");
        return;
//        exit(0);
    }
    while(r->next!=NULL)            //找到要删除数据的位置
    {
        if(r->data == data) break;
        p = p->next;
        r = r->next;

    }
    if(r->data != data)         //判断链表中是否存在要删除的数据
    {
        printf("链表中未找到要删除的数据!\n");
//        exit(0);
        return;
    }
    p->next = r->next;          //删除操作
    free(r);                //释放删除节点的内存
}



//将链表各个节点的数据打印出来
void printList(LinkedList L)
{
    LinkedList p;
    if(L->next==NULL) {             //判断链表是否为空
        printf("链表为空!\n");
        return;
    }
    p = L->next;

    while(p->next!=NULL)
    {
        printf("%d->",p->data);
        p = p->next;
    }

    printf("%d\n",p->data);
}

void reverseList(LinkedList L)
{
    if(L==NULL)              //判断链表是否为空
    {
        printf("链表为空!\n");
        return;
    }
    if(L->next==NULL)                //只有一个节点时,反转即本身,无需反转
    {
        printf("只有一个元素,不需反转\n");
        return;
    }
    LinkedList p, q, r;

    p = L;
    q = L->next;
    r = q->next;
    q->next=NULL;           //第一次循环时,将q->next(即反转后的尾节点)指向null
    p = q;
    q = r;
    while(q!=NULL)
    {
        r = q->next;
        q->next = p;
        p = q;
        q = r;
    }
    L->next = p;
}



int main()
{
    LinkedList L;
    int option;
    printf("输入要进行的操作\n");
    printf("-----------------\n");
    printf("1 头插法创建链表\n");
    printf("2 尾插法插法创建链表\n");
    printf("3 插入节点\n");
    printf("4 删除节点\n");
    printf("5 反转链表\n");
    printf("0 退出\n");
    while(scanf("%d",&option)&&option!=0)       //输入指令
    {
        switch (option)
        {
        case 1:
            L = createH();         //头插法创建链表
            printList(L);          //打印链表
            break;
        case 2:
            createT();              //尾插法创建链表
            printList(L);          //打印链表
            break;
        case 3:
            insertNode(L);         //插入节点
            printList(L);          //打印链表
            break;
        case 4:
            deleteNode(L);         //删除节点
            printList(L);          //打印链表
            break;
        case 5:
            reverseList(L);        //反转链表
            printList(L);           //打印链表
        }
         printf("输入要进行的操作: ");
    }
    return 0;

}








在这里插入图片描述

代码参考于https://www.cnblogs.com/newwy/archive/2010/10/10/1847456.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单链表是一种常见的数据结构,可以通过C语言来创建操作。 首先,我们需要定义一个结构体来表示单链表的节点,节点包括数据类型和指向下一个节点的指针。定义如下: ```c typedef struct Node { int data; struct Node* next; } Node; ``` 接下来,我们可以通过定义一个指向头节点的指针来创建一个空的单链表: ```c Node* head = NULL; ``` 插入操作可以通过以下步骤实现: 1. 创建一个新节点并为它分配内存。 2. 将新节点的数据设置为所需的值。 3. 将新节点的next指针设置为当前节点的next指针。 4. 将当前节点的next指针指向新节点。 ```c Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = 10; newNode->next = NULL; if (head == NULL) { head = newNode; } else { Node* current = head; while (current->next != NULL) { current = current->next; } current->next = newNode; } ``` 删除操作可以通过以下步骤实现: 1. 找到要删除的节点的前一个节点。 2. 将前一个节点的next指针指向要删除节点的下一个节点。 3. 释放被删除节点的内存。 ```c int key = 10; // 要删除的节点值 Node* current = head; Node* previous = NULL; while (current != NULL && current->data != key) { previous = current; current = current->next; } if (current != NULL) { if (previous != NULL) { previous->next = current->next; } else { head = current->next; } free(current); } ``` 查找操作可以通过以下步骤实现: 1. 从头节点开始,依次遍历每个节点,直到找到所需节点或到达链表尾部。 2. 返回找到的节点指针,或者返回NULL表示节点不存在。 ```c int key = 10; // 要查找的节点值 Node* current = head; while (current != NULL && current->data != key) { current = current->next; } if (current != NULL) { printf("找到了节点:%d\n", current->data); } else { printf("未找到节点:%d\n", key); } ``` 通过以上步骤,我们可以创建插入删除和查找单链表中的节点。当然,在实际应用中可能还需要实现其他操作,例如获取链表长度、反转链表等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值