数据结构--单向链表创建、销毁及解决一些问题

定义节点

typedef int data_t;
typedef struct node_t
{
    data_t data;
    struct node_t *next;
}linknode_t, * linklist_t;

创建链表

/*
 *创建带有头结点的单链表,单链表中的数据为键盘输入的数据,键盘输入-1结束
 * */
linklist_t CreateLinklist()
{
    data_t new_data;
    linklist_t head, p_new, p_tmp;
    head = (linklist_t)malloc(sizeof(linknode_t));
    if (NULL == head)
    {
        printf("create head node error!\n");
        return NULL;
    }
    p_tmp = head;
    scanf("%d", &new_data);
    while (-1 != new_data)
    {
        p_new = (linklist_t)malloc(sizeof(linklist_t));
        if (NULL == p_new)
        {
            printf("create new node error!\n");
            break;
        }
        p_new->data = new_data;
        p_tmp->next = p_new;
        p_tmp = p_new;
        scanf("%d", &new_data);
    }
    p_tmp->next = NULL;
    return head;
}

销毁链表

/*
 *销毁单链表
 * */
int DestroyLinklist(linklist_t head)
{
    int count = 0;
    if (NULL == head)
    {
        return 0;
    }
    linklist_t p_de = head->next;
    while (NULL != p_de)
    {
        head->next = head->next->next;
        count++;
        free(p_de);
        p_de = head->next;
    }
    free(head);
    head = NULL;
    printf("DestroyLinklist count = %d\n", count+1);
    return 0;
}

遍历链表

/*
 * 遍历链表并输出
 * */
void TraverseLinklist(linklist_t head)
{
    if (NULL == head || NULL == head->next)
    {
        printf("DestroyLinklist linklist is empty\n");
        return;
    }
    linklist_t p = head->next;
    while(1)
    {
        printf("%5d", p->data);
        if (p->next == NULL)
            break;
        p = p->next;
    }
    printf("\n");
}

运行结果展示

在这里插入图片描述

单链表在指定位置插入(默认节点下标从0开始,头节点不包括)

/*
 *链表的插入,将x插入表中节点i之前
 *返回值为0代表插入正确,返回值为-1代表插入失败
 * */
int InsertLinklist(linklist_t head, data_t x, int i)
{
    linklist_t p_new = NULL, p_before;
    int count = 0;
    p_before = head;
    while (count != i && p_before != NULL)
    {
        count++;
        p_before = p_before->next;
    }
    if (NULL == p_before)
    {
        printf("the %d location is error!\n", i);
        return -1;
    }
    else
    {
        p_new = (linklist_t )malloc(sizeof(linknode_t));
        if (NULL == p_new)
        {
            printf("malloc new node error!\n");
            return -1;
        }
        p_new->data = x;
        p_new->next = p_before->next;
        p_before->next = p_new;
        return 0;
    }
}

运行结果展示

结果一:插入位置为末尾

在这里插入图片描述

结果一:插入位置正常

在这里插入图片描述

结果一:插入位置超出范围

在这里插入图片描述

单链表倒置

/*
 *链表倒置,使用头插法
 * */
void ReverseLinklist(linklist_t head)
{
    if (NULL == head || NULL == head->next)
    {
        printf("ReverseLinklist linklist is empty!\n");
        return ;
    }
    linklist_t p_old = head->next, p_tmp;
    head->next = NULL;
    while (NULL != p_old)
    {
        p_tmp = p_old;
        p_old = p_old->next;
        p_tmp->next = head->next;
        head->next = p_tmp;
    }
}

运行结果展示

在这里插入图片描述

单链表问题一:设结点data域为整型,求链表中相邻两结点data值之和为最大的第一结点的指针

linklist_t AddMax(linklist_t list)
{
    if (NULL == list || NULL == list->next)
    {
        printf("linklist is empty!\n");
        return NULL;
    }
    linklist_t p1 = list->next, p2 = p1->next, p_first = p1;
    if (NULL == p2) //只有一个元素
    {
        return p_first;
    }
    int max = p1->data + p2->data, tmp = 0;
    while (NULL != p2->next)
    {
        p1 = p2;
        p2 = p2->next;
        tmp = p1->data + p2->data;
        if (tmp > max)
        {
            max = tmp;
            p_first = p1;
        }
    }
    return p_first;
}

运行结果展示

在这里插入图片描述

单链表问题二:设两单链表A、B按data值(设为整型)递增有序,设计算法,将表A和B合并成一表A,且表A也按data值递增有序。list1为A,将原来的两个表中的各项依次取出,比较之后按照相应的顺序以尾插法的形式插入到list1中

void Merge(linklist_t list1, linklist_t list2)
{
    linklist_t p1 = list1->next, p2 = list2->next, list_tmp = list1;
    free(list2);
    list2 = NULL;
    while (p1 && p2)
    {
        if (p1->data <= p2->data) 
        {
            list_tmp->next = p1;
            list_tmp = p1;
            p1 = p1->next;
        }
        else
        {
            list_tmp->next = p2;
            list_tmp = p2;
            p2 = p2->next;
        }
    }
    if (NULL == p1) //收尾
    {
        p1 = p2;
    }
    list_tmp->next = p1;
}

结果展示

在这里插入图片描述
对单链表操作的一些心得

  1. 想明白链表中的节点定义方式为何是那样
  2. 明白指针在单链表中的用途,是各个节点之间的“链子”,指针不能乱指,一不小心指错就会导致链表中的节点数据丢失
  3. 对于链表进行插入等操作,记住:链表的头指针一般情况下不动,通过新增加一个节点指针对链表中的元素进行遍历、插入等操作,如果动头指针,很可能会导致丢失链表中的一些数据(原因如上一条所示)
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值