链表的增删

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

struct list
{
    int data;//数据域
    struct list *next;//指针域
};

struct list *create_list()//建立一个节点
{
    return calloc(sizeof(struct list), 1);
}

struct list *insert_list(struct list *ls, int n, int data)//在指定位置下一级插入元素
{
    struct list *p = ls;
    while(p && n--)
    {
        p = p->next;
    }

    if (p == NULL)
    {
        return NULL;//n的位置大于链表节点数
    }

    struct list *node = create_list();//新建立一个节点
    node->data = data;
    node->next = p->next;
    p->next = node;
    return node;
}

int delete_list(struct list *ls, int n)//删除指定位置下一级元素
{
    struct list *p = ls;
    while(p && n--)
    {
        p = p->next;
    }

    if (p == NULL)
    {
        return -1;//n的位置不合适
    }

    struct list *tmp = p->next;
    p->next = p->next->next;
    free(tmp);
    return 0;//删除成功
}

int count_list(struct list *ls)//返回链表元素个数
{
    struct list *p = ls;
    int count = 0;
    while(p)
    {
        count++;
        p = p->next;
    }
    return count;
}

void clear_list(struct list *ls)//清空链表,只保留首节点
{
    struct list *p = ls->next;
    while(p)
    {
        struct list *tmp = p->next;
        free(p);
        p = tmp;
    }
    ls->next = NULL;//只有首节点,那么首节点的next也应该设置为NULL
}

int empty_list(struct list *ls)//返回链表是否为空
{
    if (ls->next)
        return 0;
    else
        return -1;
}

struct list *locale_list(struct list *ls, int n)//返回链表指定位置的节点
{
    struct list *p = ls;
    while(p && n--)
    {
        p = p->next;
    }

    if (p == NULL)
        return NULL;

    return p;
}

struct list *elem_locale(struct list *ls, int data)//返回数据域等于data的节点
{
    struct list *p = ls;
    while(p)
    {
        if (p->data == data)
            return p;
        p = p->next;
    }

    return NULL;//没有找到数据域等于data的节点
}

int elem_pos(struct list *ls, int data)//返回数据域等于data的节点位置
{
    int index = 0;
    struct list *p = ls;
    while(p)
    {
        index++;
        if (p->data == data)
            return index;
        p = p->next;
    }

    return -1;//没有找到数据域等于data的节点
}

struct list *last_list(struct list *ls)//得到链表最后一个节点
{
    struct list *p = ls;
    while(p->next)
    {
        p = p->next;
    }
    return p;
}

void merge_list(struct list *ls1, struct list *ls2)//合并两个链表,结果放入ls1中
{
    //只合并链表的节点,不合并链条头
    last_list(ls1)->next = ls2->next;
    free(ls2);//链表头不要了
}

void reverse(struct list *ls)//链表逆置
{
    if (ls->next == NULL)
        return;//只有一个首节点,不需要逆置

    if (ls->next->next == NULL)
        return;//也不需要逆置

    struct list *last = ls->next;//逆置后ls->next就成了最后一个节点了

    struct list *pre = ls;//上一个节点的指针
    struct list *cur = ls->next;//当前节点的指针
    struct list *next = NULL;//下一个节点的指针
    while(cur)
    {
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }

    ls->next = pre;
    last->next = NULL;
}

void traverse(struct list *ls)//循环遍历链表
{
    struct list *p = ls;
    while(p)
    {
        printf("%d\n", p->data);
        p = p->next;//p指向他对应的下一个节点
    }
}

int main(void)
{
    struct list *first = create_list();//在堆中间创建一个节点
    struct list *second = create_list();//在堆中间创建一个节点
    struct list *third = create_list();//在堆中间创建一个节点
    first->next = second;
    second->next = third;
    third->next = NULL;//对于链表的最后一个节点,next域一定为NULL
    first->data = 1;
    second->data = 2;
    third->data = 3;

    insert_list(first, 1, 10);
    insert_list(first, 1, 20);
    insert_list(first, 1, 30);

    //delete_list(first, 2);
    //clear_list(first);

    traverse(first);
    printf("----------------\n");
    printf("count = %d\n", count_list(first));
    printf("%d\n", locale_list(first, 3)->data);
    printf("data = %d\n", last_list(first)->data);

    printf("-----------------------\n");
    struct list *first1 = create_list();
    int i;
    for(i = 0; i < 10; i++)
    {
        insert_list(first1, 0, i);
    }

    printf("----------------\n");

    merge_list(first, first1);

    printf("---------------------\n");
    traverse(first);
    printf("---------------------\n");
    reverse(first);
    traverse(first);
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值