链表操作大全 C语言版

本文详细介绍了一个初学者在学习链表过程中遇到的问题及解决方法,包括链表的创建、打印、合并、查找、删除、插入和求长度等核心操作。通过实际代码示例,帮助读者深入理解链表的基本原理和实现技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本人刚学链表,一开始遇到了很多问题,看了很久才略懂一二,有一些体会全都写在了代码里,水平有限,请各位批评改正。。

#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct node List;
struct node{
    int data;
    List* next;
};

List* CreatList();
void PrintList(const List* p);
List* ConList(List* L1,List* L2);
List* FindKth(List* p,int k);
List* DeleteList(List* p,int i);
List* InsertList(List* p,int i,ElementType x);
int LengthList(List* p);
/******************************************************/
int main()
{
    int i,x;
    List* p=CreatList();
    PrintList(p);
    
    List* q=CreatList();
    PrintList(q);
    
    List* s=ConList(p,q);
    PrintList(s);
    
    printf("请输入要删除第几个位置的元素:\n");
    scanf("%d",&i);
    DeleteList(s,i);
    PrintList(s);
    
    printf("请输入要插入第几个位置的元素:\n");
    scanf("%d",&i);
    printf("请输入要插入的元素值:\n");
    scanf("%d",&x);
    InsertList(s,i,x);
    PrintList(s);
    
    printf("此时表长度为: %d\n",LengthList(s));
}

/******************************************************/
List* CreatList()                                ·                     //建立一个新链表并输入一些值
{
    int n,value;
    List* head=(List*)malloc(sizeof(List));
    if(head==NULL)
    {
        printf("error\n");
        return NULL;
    }
    List* p=head;
    List* q;
    p->next=NULL;
    
    printf("请输入节点个数\n");
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    {
        q=(List*)malloc(sizeof(List));
        if(q==NULL)
        {
            printf("error\n");
            return NULL;
        }
        printf("请输入要插入的元素\n");
        scanf("%d",&value);
        q->data=value;
        q->next=NULL;
        p->next=q;
        p=q;
    }
    p->next=NULL;
    return head;
}
/********************************************************/
void PrintList(const List* p)                    //打印链表
{
    List *q=p->next;
    while(q)
    {
        printf("%d  ",q->data);
        q=q->next;
    }
    printf("\n");
}


/*******************************************************/
List* ConList(List* L1,List* L2)                //链表归并
{
    List* L=(List*)malloc(sizeof(List));        //由于一些题目要求重新定义一个头指针
    List* p1=L1->next;
    List* p2=L2->next;
    List* p=L;                                    //新链表表头
    L->next=NULL;
    
    if(p1==NULL&&p2==NULL)                        //三种特殊情况
    {
        printf("error\n");
        return NULL;
    }
    else if(p1==NULL&&p2!=NULL)
    {
        return L2;
    }
    else if(p2==NULL&&p1!=NULL)
    {
        return L1;
    }
    
    while(p1!=NULL&&p2!=NULL)                    //归并开始(按升序排列)
    {
        if(p1->data<=p2->data)                    
        {
            p->next=p1;
            p=p1;
            p1=p1->next;
            
        }
        else{
            p->next=p2;
            p=p2;
            p2=p2->next;
        }
    }
    p->next=NULL;
    if(p1==NULL)
    {
        p->next=p2;
    }
    else if(p2==NULL)
    {
        p->next=p1;
    }
    L1->next=NULL;                            //其实这两个无所谓。。有的题要求而已
    L2->next=NULL;
    
    return L;
}
/***************************************************/
List* DeleteList(List* p,int i)                //删除表中第i个位置元素
{
    List* q;
    List* s;
    if(i==1)                                //第一个节点要特殊讨论一下
    {
        q=p->next;
        s=q->next;
        if(q!=NULL)
        {
            p->next=s;
        }
        else{
            return NULL;
        }
        free(q);
        return p;
    }    
        q=FindKth(p,i-1);                    //寻找到i的前一个节点
    
    if(q==NULL)                                //两种越界情况
    {
        printf("error\n");
        return NULL;
    }
    else if(q->next==NULL)
    {
        printf("error\n");
        return NULL;
    }
    else{
        s=q->next;
        q->next=s->next;
        free(s);
        return p;
    }
}
/****************************************************************/
List* FindKth(List* p,int k)                //寻找第k个位置的节点,并返回之
{
    int cnt;
    List* q=p->next;
    cnt=1;                                    //此时为第一个节点
    while(q!=NULL&&cnt<k)
    {
        cnt++;
        q=q->next;
    }
    if(cnt==k)                                //找到了 (注意找到了,是最后一个也是NULL)
    {
        return q;
    }
    else{                                    //没找到
        return NULL;
    }
}
/*************************************************************/
List* InsertList(List* p,int i,ElementType x)        //插入节点
{
    List* q;
    List* s;
    if(i==1)                                        //此时为第一个节点
    {
        q=p->next;
        s=(List*)malloc(sizeof(List));
        s->data=x;
        p->next=s;
        s->next=q;
        return p;
    }
    q=FindKth(p,i-1);                                //找到此节点前一个元素
    if(q==NULL)
    {
        printf("error\n");
        return NULL;
    }
    else{
        
        s=(List*)malloc(sizeof(List));
        s->data=x;
        s->next=q->next;
        q->next=s;
        return p;
    }
}
/***********************************************************/
int LengthList(List* p)                            //求长度
{
    int cnt=0;
    List* q=p->next;
    while(q)
    {
        q=q->next;
        cnt++;
    }
    return cnt;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值