c语言链表基本操作(3)

实现链表的基本操作:

1. initLinkList

初始化链表,空链表有一个空的头结点。通过head->next == NULL判断链表是空的

2.createLinkList

创建链表,使用一个无限循环输入链表中每一个节点的数据,输入0跳出这个循环

3.print

输出链表

4.getElem

链表查找第i个位置的节点

5.locateElem

单链表按值查找节点

6.linkListLength

获取表长

7.insertEle

在第i个位置后面插入节点,节点的值是data

8.deleteEle

删除第i个位置的节点,注意i可能是表头和表尾,此时操作第i-1个节点指向第i+1个节点是不合法的。

下面是代码实现,注意到头结点的next指向首元节点即有数据的节点,遍历总是先从首元节点(*L).next开始:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
// 单链表,单链表一般最好设置头结点

// 按一整行输入字符串,换行符结束,并且删除换行符
char *s_gets(char *st, int n)
{
    char *ret_val;
    ret_val = fgets(st, n, stdin);
    if (ret_val)
    {
        int i = 0;
        while (ret_val[i] != '\n' || ret_val[i] != '\0')
        {
            i++;
        }
        if (ret_val[i] == '\n')
        {
            ret_val[i] = '\0';
        }
        else
        {
            // 输入内容大于长度n,后面的多余字符从输入缓存区全部删除
            while (getchar() != '\n')
            {
                continue;
            }
        }
    }
    return ret_val;
}

typedef struct node
{
    int data;
    struct node *next;
} Node, *LinkList;
// typedef Node *LinkList;

void initLinkList(LinkList *L) {
    struct node *current = (struct node *)malloc(sizeof(struct node));
    *L = current;
    (*L)->data = -1;
    (*L)->next = NULL;
}

void createLinkList(LinkList *L)
{
    struct node *current, *prev;
    prev = *L;
    while (1)
    {
        // 创建一个新的节点
        current = (struct node *)malloc(sizeof(struct node));
        scanf("%d", &current->data);
        current->next = NULL;
        if (current->data == 0)
        {
            break;
        }
        prev->next = current;
        prev = current;
    }
}

void print(LinkList *L)
{
    struct node *p = (*L)->next;
    int i = 1;
    while (p != NULL)
    {
        printf("第%d个节点data: %d\n", i, p->data);
        i++;
        p = p->next;
    }
}

// 链表按位置查找节点
struct node *getElem(LinkList L, int i)
{
    struct node *p;
    p = L->next; // 首元节点
    int j = 1;
    while (p)
    {
        if (j == i)
        {
            return p;
        }
        j++;
        p = p->next;
    }
    return NULL;
}

// 单链表按值查找节点
struct node *locateElem(LinkList L, int data)
{
    struct node *p;
    p = L->next;
    while (p)
    {
        if (p->data == data)
        {
            return p;
        }
        p = p->next;
    }
    return NULL;
}

int linkListLength(LinkList *L)
{
    int length = 0;
    struct node *p = (*L)->next;
    while (p != NULL)
    {
        length++;
        p = p->next;
    }
    return length;
}

// 在第i个位置后面插入节点,节点的值是data
void insertEle(LinkList *L, int i, int data)
{
    struct node *head = (*L)->next;
    int j = 1;
    while (head != NULL)
    {
        if (j == i)
        {
            // 插入操作
            struct node *item = (struct node *)malloc(sizeof(struct node));
            item->data = data;
            item->next = head->next;
            head->next = item;
            break;
        }
        j++;
        head = head->next;
    }
}

// 删除第i个位置的节点
void deleteEle(LinkList *L, int i)
{
    struct node *head = (*L)->next;
    int j = 1;
    if (i < 1)
    {
        puts("删除的位置不合法");
        return;
    }
    if (i == 1)
    {
        *L = (*L)->next; // 删除头结点,等价于链表从头结点的下一个加点开始
        return;
    }
    // 查找第i-1个位置的节点,如果节点不为空则j=i-1
    while (head != NULL && j < (i - 1))
    {
        j++;
        head = head->next;
    }
    // j=i-1时head也指向第i-1个节点(如果存在)
    if (j == (i - 1))
    {
        // 第i个节点不存在,则无法删除
        if (head->next == NULL)
        {
            return;
        }
        struct node *temp;
        temp = head->next; // 获取第i个及点
        if (temp->next) {
            head->next = temp->next; // 第i+1个节点存在,则第i-1个节点指向第i+1个节点
        } else {
            head->next = NULL; // 否则要删除的第i个节点就是最后一个节点,第i-1个节点指向NULL
        }
        printf("第%d个节点已删除\n", j + 1);
    }
    else
    {
        puts("删除的位置大于链表长度");
    }
}

int main()
{
    LinkList list;
    initLinkList(&list);
    createLinkList(&list);
    print(&list);
    int index = 3;
    struct node *elem = getElem(list, index);
    if (elem != NULL)
    {
        printf("查询第%d个节点的data值:%d\n", index, elem->data);
    }
    int elemData = 10;
    struct node *locate = locateElem(list, elemData);
    if (locate != NULL && locate->next != NULL)
    {
        printf("查询data值为%d的节点的下一个节点的数据为:%d\n", elemData, locate->next->data);
    }
    int length = linkListLength(&list);
    int addData = 999;
    printf("在第%d个节点后面添加一个data值为%d的节点\n", length, addData);
    insertEle(&list, length, 999); // 在链表的最后加上一个节点,节点的data值是999
    print(&list);

    deleteEle(&list, 1);
    printf("删除第1个节点:\n");
    print(&list);
    // LinkList list2;
    // initLinkList(&list2);
    return 0;
}

输出: 9 10 11 12 13 0 观察运行结果: 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

heine162

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

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

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

打赏作者

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

抵扣说明:

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

余额充值