数据结构 day4

 

head.h

#ifndef __HEAD_H__
#define __HEAD_H_

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

typedef char datatype[20];
// 定义节点结构体
typedef struct Node
{
    // 数据域
    union
    {
        int len;       // 头节点的数据域
        datatype data; // 其他节点的数据域
    };
    // 指针域:下一个节点的地址
    struct Node *next;
} *Linklist;
Linklist create_head();
Linklist create_node();
int insert_head(Linklist L, datatype e);
void output(Linklist L);
int insert_rear(Linklist L,datatype e);
int delete_head(Linklist L);
int delete_rear(Linklist L);
int insert_by_pos(Linklist L, int pos, datatype e);
int delete_by_pos(Linklist L, int pos);
int update_by_pos(Linklist L,int pos,datatype e);
int search_by_pos(Linklist L, int pos);
#endif

main.c

#include "head.h"

int main(int argc, const char *argv[])
{
    // 创建头结点
    Linklist L = create_head();
#if 0
            // 头插一次调用只插入一个

            int n;
    datatype e;
    printf("请输入插入数据元素的个数\n");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        printf("请输入插入的字符串");
        scanf("%s", e);
        insert_head(L, e);
    }
    output(L);
#else
    // 尾插 永远在链表尾部插入,一次插入一个
    // 循环调用尾插函数
    int n;
    datatype e;
    printf("请输入插入数据元素的个数\n");
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        printf("请输入插入的字符串");
        scanf("%s", e);
        insert_rear(L, e);
    }
    output(L);
#endif
    // delete_head(L);
    // delete_head(L);
    // delete_rear(L);
    delete_rear(L);
    output(L);
    insert_by_pos(L, 2, "abc");
    output(L);
    printf("请输入要删除的位置:\n");
    int pos;
    scanf("%d", &pos);
    delete_by_pos(L, pos);
    output(L);
    printf("请输入要修改的位置\n");
    scanf("%d", &pos);
    printf("请输入插入的字符串");
    scanf("%s", e);
    update_by_pos(L, pos, e);
    output(L);
    printf("请输入要搜索的位置\n");
    scanf("%d", &pos);
    search_by_pos(L, pos);
    return 0;
}

fun.c

#include "head.h"
/**
 * @description: 创建链表头节点
 * @return {*}
 */
Linklist create_head()
{
    Linklist L = (Linklist)malloc(sizeof(struct Node));
    if (L == NULL)
    {
        return NULL;
    }
    L->len = 0;
    L->next = NULL;
    return L;
}
/**
 * @description: 创建链表
 * @return {*}
 */
Linklist create_node()
{
    Linklist p = (Linklist)malloc(sizeof(struct Node));
    if (p == NULL)
    {
        return NULL;
    }
    strcpy(p->data, "");
    p->next = NULL;
    return p;
}
int insert_head(Linklist L, datatype e)
{
    if (L == NULL)
    {
        printf("头插入失败!\n");
        return -1;
    }
    // 在堆区申请其他结点空间
    Linklist p = create_node();
    // p的数据赋值为e
    strcpy(p->data, e);
    // p的指针域
    p->next = L->next;
    L->next = p;
    // 链表长度自增
    L->len++;
    return 0;
}
void output(Linklist L)
{
    // 判空
    if (L == NULL || L->len == 0)
    {
        printf("失败\n");
    }
    while (L->next != NULL)
    {
        L = L->next;
        printf("%s\t", L->data);
    }
    printf("\n");
}

/**
 * @description: 尾插入
 * @param {Linklist} L
 * @param {datatype} e
 * @return {*}
 */
int insert_rear(Linklist L, datatype e)
{
    // 判断头是否存在
    if (L == NULL)
    {
        return -1;
    }
    // 尾插
    // 寻找最后一个节点
    Linklist p = L;
    while (p->next)
    {
        p = p->next;
    }
    // 创建新结点
    Linklist s = create_node();
    if (s == NULL)
    {
        return -1;
    }
    // s的数据域
    strcpy(s->data, e);
    // s的指针域
    p->next = s;
    L->len++;
    return 0;
}
/**
 * @description: 头删除
 * @param {Linklist} L
 * @return {*}
 */
int delete_head(Linklist L)
{
    // 判断头是否存在
    if (L == NULL || L->len == 0)
    {
        printf("删除失败");
        return -1;
    }
    // 删除
    Linklist q = L->next;
    L->next = q->next;
    free(q);
    q = NULL;
    L->len--;
    return 0;
}

/**
 * @description: 尾删除
 * @param {Linklist} L
 * @return {*}
 */
int delete_rear(Linklist L)
{
    // 判断头是否存在
    // 判断链表是否为空
    if (L == NULL || L->len == 0)
    {
        printf("删除失败");
        return -1;
    }
    // 找到尾部节点的前一个节点
    Linklist p = L;
    for (int i = 0; i < L->len - 1; i++)
    {
        p = p->next;
    }
    // 删除p结点后面的结点
    free(p->next);
    p->next = NULL;
    L->len--;
}
/**
 * 单链表任意位置删除
 */
int insert_by_pos(Linklist L, int pos, datatype e)
{
    // 判断头结点是否存在
    // 判断位置是否合法en + 1)
    {
        if (L == NULL || pos < 1 || pos > L->len)
            printf("删除失败\n");
        return -1;
    }

    // 找到pos-1位置,起名字为p
    Linklist p = L;
    for (int i = 0; i < pos - 1; i++)
    {
        p = p->next;
    }
    // 创建新结点s
    Linklist s = create_node();
    // s的数据域
    strcpy(s->data, e);
    // s的指针与
    s->next = p->next;
    p->next = s;
    L->len++;
}
/**
 * @description: 选择删除
 * @param {Linklist} L
 * @param {int} pos
 * @return {*}
 */
int delete_by_pos(Linklist L, int pos)
{
    // 判断头结点是否存在
    // 判断位置是否合法
    if (L == NULL || pos < 1 || pos > L->len + 1)
    {
        printf("删除失败");
        return -1;
    }
    Linklist p = L;
    for (int i = 0; i < pos - 1; i++)
    {
        p = p->next;
    }
    // 删除p后面的结点
    Linklist q = p->next;
    p->next = q->next;
    free(q);
    q = NULL;
    L->len--;
    return 0;
}
/**
 * @description: 选择修改
 * @param {Linklist} L
 * @param {int} pos
 * @param {datatype} e
 * @return {*}
 */
int update_by_pos(Linklist L, int pos, datatype e)
{
    // 判断头结点是否存在
    // 判断位置是否合法
    if (L == NULL || pos < 1 || pos > L->len)
    {
        printf("修改失败");
        return -1;
    }
    Linklist p = L;
    for (int i = 0; i < pos; i++)
    {
        p = p->next;
    }
    strcpy(p->data, e);
    return 0;
}
/**
 * @description:查找
 * @param {Linklist} L
 * @param {int} pos
 * @return {*}
 */
int search_by_pos(Linklist L, int pos)
{
    // 判断头结点是否存在
    // 判断位置是否合法
    if (L == NULL || pos < 1 || pos > L->len)
    {
        printf("参数不合法");
        return -1;
    }
    Linklist p = L;
    for (int i = 0; i < pos; i++)
    {
        p = p->next;
    }
    printf("搜索结果:%s\n", p->data);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值