链表合集

单链表

#include<stdio.h>
#include<stdlib.h>
typedef int datekey;
typedef struct link_node
{
    datekey info;
    struct link_node *next;
}node;
node *init()
{
    return NULL;
}
void display(node *head)//输出各个节点的值
{
    node *p;
    p=head;
    if(p==NULL)
    {
        printf("链表是空的\n");
        exit(1);
    }
    while(p)
    {
        printf("%-5d",p->info);
        p=p->next;
    }
    printf("\n");
}
node *find(node *head,int i)//返回第i个节点的地址
{
    int j=1;
    node *p=head;
    if(i<1) return NULL;
    while(p&&i!=j)
    {
        p=p->next;
        j++;
    }
    return p;
}
node *insert(node *head,datekey x,int i)//在第i个节点插入键值为x的节点
{
    node *p,*q;
    q=find(head,i);
    if(!q&&i!=0)
    {
        printf("找不到%d节点",i);
        exit(1);
    }
    p=(node *)malloc(sizeof(node));
    p->info=x;
    if(i==0)
    {
        p->next=head;
        head=p;
    }else {
        p->next=q->next;
        q->next=p;
    }
    return head;
}
node *dele(node *head,datekey x)  //删除键值为x的节点
{
    node *pre=NULL;
    node *p=head;
    if(!head)
    {
        printf("链表是空的\n");
        exit(1);
    }
    while(p&&p->info!=x) pre=p,p=p->next;
    if(p)
    {
         if(!pre) head=p->next;
         else pre->next=p->next;
         free(p);
    }
    return head;
}
int main()
{
     int i=0,n;

     while(~scanf("%d",&n))
     {
          node *head;
          head=init(head);
          for(i=0;i<n;i++)
          {
              int x;
              scanf("%d",&x);
              head=insert(head,x,i);
          }
          printf("请输入要插入的值和节点\n");
          int a,b;
          scanf("%d%d",&a,&b);
          head=insert(head,a,b);
          display(head);
          printf("输入要删除的值:\n");
          scanf("%d",&n);
          dele(head,n);
          display(head);
       }
}

带头结点的单链表

#include<stdio.h>
#include<stdlib.h>
#define maxn 1111
typedef int datekey;
typedef struct link_node
{
    datekey info;
    struct link_node *next;
}node;
node *init()
{
    node *head=(node *)malloc(sizeof(node));
    head->next=NULL;
    return head;
}
node *find(node *head,int i)
{
    int j=0;
    node *p=head;
    if(i<0)
    {
        printf("不存在这样的节点\n");
        exit(1);
    }
    while(p&&i!=j) p=p->next,j++;
    return p;
}
node *insert(node *head,datekey x,int i)
{
    node *p=find(head,i);
    if(!p)
    {
        printf("不存在这样的节点\n");
        exit(1);
    }
    node *q=(node*)malloc(sizeof(node));
    q->info = x;
    q->next=p->next;
    p->next=q;
    return  head;
}
void display(node* head)
{
    node *p=head;
    p=p->next;
    if(!p)
    {
        printf("表是空的\n");
        exit(1);
    }
    while(p) printf("%-5d",p->info),p=p->next;
    printf("\n");
}
node *dele(node* head, datekey x)
{
    node *pre=head;
    node *p=head->next;
    while(p&&p->info!=x) pre=p,p=p->next;
    if(p)
    {
        pre->next=p->next;
        free(p);
    }
    return head;
}
int main()
{
    int n,i;
    datekey x;
    while(~scanf("%d",&n))
    {
        node *head;
        head=init();
        for(i=0;i<n;i++)
        {
            scanf("%d",&x);
            head=insert(head,x,i);
        }
        display(head);
        printf("要插入的数和节点\n");
        scanf("%d%d",&x,&i);
        insert(head,x,i);
        display(head);
        printf("输入要删除的数\n");
        scanf("%d",&x);
        dele(head,x);
        display(head);
    }

}

循环链表

#include<stdio.h>
#include<stdlib.h>
typedef int datetype;
typedef struct link_node
{
    datetype info;
    struct link_node *next;
}node;
node * init()
{
    return NULL;
}
node *create()  //创建一个个循环链表,以输入-1结束
{
    int x;
    node *head=(node *)malloc(sizeof(node)),*p,*q;
    scanf("%d",&x);
    if(x!=-1) head->info=x;
    else  return NULL;
    p=head; //p始终指向表的末尾
    while(scanf("%d",&x)&&x!=-1)
    {
        q=(node *)malloc(sizeof(node));
        q->info=x;
        p->next=q; //p指向插入的节点的地址
        p=p->next;  //p指向表的末尾
    }
    p->next=head;  //循环链表,表的末尾指向头指针
    return head;
}
void display(node *head) //输出表的内容
{
    node *p=head;
    if(!head)
    {
        printf("循环链表是空的\n");
    }
    else
    {
         p=head->next;   //先输出头结点的值
         printf("%-5d",head->info);
         while(p!=head)   //当再一次指向头结点时,链表遍历完全
        {
            printf("%-5d",p->info);
            p=p->next;
        }
    }
    printf("\n");
}
node *find_rear(node *head)  //找到表的尾指针
{
    node *p=head;
    if(!head) return NULL;
    while(p->next!=head) p=p->next; //若当前节点的指向的是头指针,循环结束
    return p;
}
node *insert(node *head,int i,datetype x) //链表中在第i节点后插入键值为x的节点
{
    node *p=head,*q,*rear;
    rear=find_rear(head);  //找到尾指针
    int j=1;           //计数从1始,指向当前头节点
    q=(node *)malloc(sizeof(node));
    q->info=x;
    if(i<0)
    {
        printf("这样的节点不存在\n");
        return NULL;
    }
    if(i==0&&!head)  //若链表为空且插入的点在第0位
    {
      head=q,head->next=head;//直接接将将待插入点改为头结点并指向自己
      return head;
    }
    if(i==0&&head)  //若插入节点在头部,但链表不为空
     {
       q->next=head,head=q; //将待插入点指向原来的头结点,改变头结点
       rear->next=head;  //使尾指针指向新的头结点
       return head;
     }
     if(i>0&&!head)  //节点大于0,且链表为空,不存在
     {
         printf("无法找到这样的节点\n");
         return head;
     }
    while(p->next!=head&&i!=j) p=p->next,j++; //节点大于1,链表不为空,扫描链表,找到第i个节点
    if(i>0&&i==j) //找到节点,进行插入
    {

      q->next=p->next;
      p->next=q;
    }else if(i!=j) printf("不存在这样的节点\n");
    return head;
}
node *dele(node *head,datetype x)
{
    node *pre=NULL,*p=head;
    if(!head)
    {
        printf("链表是空白的\n");
        return head;
    }
    while(p->next!=head&&p->info!=x) pre=p,p=p->next; //pre始终指向p节点的前驱
    if(p->info!=x)
    {
        printf("不存在这样的点\n");
        return head;
    }
    if(head->info==x) //要删除头节点时
    {
        if(head->next==head) //链表只有头结点,则返回空
        {
            free(head);
            return NULL;
        }
        else  //否则找到到尾指针,使得尾指针指向删除后新的头指针
        {
           pre=head->next;
           while(pre->next!=head) pre=pre->next;
           pre->next=head->next;
           free(head);
           head=pre->next;
        }
    }
    else
        pre->next=p->next,free(p);//删除的点在中间某个地方时,将p的前驱指向p的后继
    return head;
}
int main()
{
    node *head,*rear;
    while(1)
    {
        int id,x;
        head=create();
        display(head);
        printf("输入要插入的节点和值:");
        scanf("%d%d",&id,&x);
        head=insert(head,id,x);
        display(head);
        printf("输入要删除的值:");
        scanf("%d",&x);
        head=dele(head,x);
        display(head);
    }
}

双向链表

#include<stdio.h>
#include<stdlib.h>
typedef int datatype;
typedef struct dlink_list
{
    datatype info;
    struct dlink_list *llink,*rlink;//指向前驱的指针和指向后继的指针
}node;
node *init()
{
    return NULL;
}
void display(node *head)//输出链表各节点的值
{
    node *p=head;
    if(!head) //链表为空
    {
        printf("链表是空的\n");
        return NULL;
    }
    while(p)
    {
        printf("%-5d",p->info);
        p=p->rlink;
    }
    printf("\n");
}
node *create() //创建一个双向链表,以输入-1结束
{
    int x;
    node *head,*p,*q;
    head=(node *)malloc(sizeof(node));
    scanf("%d",&x);
    if(x!=-1) head->info=x,head->rlink=NULL,head->llink=NULL;
    else {free(head);return NULL;}//若只输入-1,则释放申请的空间,返回空链表
    p=head;//p始终指向当前链表的尾部
    while(scanf("%d",&x)&&x!=-1)
    {
        q=(node *)malloc(sizeof(node));
        q->info=x;
        p->rlink=q; //尾部指向新插入的节点
        q->llink=p; //使要插入的节点指向原链表的尾部
        p=p->rlink;//p指向新链表的尾部
    }
    p=p->rlink=NULL; //使链表尾部指向NULL
    return head;
}
node *insert(node* head, int i, int x)  //插入一个新节点,插在第i的节点后面
{
    int j=1;
    node *p,*q;
    q=(node *)malloc(sizeof(node));
    q->info=x;
    if(i<0)
    {
        printf("不存在这样的节点\n");
        free(q);
        return head;
    }
    if(i==0&&!head)  //插在头结点前面并且此时链表为空
    {
        head=q;  //直接将待插入点改为头结点
        head->rlink=NULL; //前驱后继各指向空
        head->llink=NULL;
        return head;
    }
    if(i==0&&head) //插在头结点前面
    {
        q->rlink=head; //新的节点指向原头结点
        head->llink=q; //原头结点的左指针指向新插入的节点
        head=q;  //改变头结点
        head->llink=NULL;//使得新的头节点的左指针指向NULL
        return head;
    }
    p=head;
    while(p&&i!=j) p=p->rlink,j++; //当插入节点在中间某个地方时
    if(p)
    {
        if(p->rlink==NULL)  //插入的节点在尾部
        {
            p->rlink=q;//原链表的尾部的右指针指向新插入节点
            q->llink=p;//新插入节点的左指针指向原链表尾部
            p=p->rlink;//p指向当前指针待插入节点
            p->rlink=NULL; //尾部的指针指向NULL
        }
        else
        {
            q->rlink=p->rlink; //使得新插入节点的右指针指向待插入节点的后一个节点
            p->rlink=q; //使得当前节点指向
            q->rlink->llink=q;//当前节点后一个节点的左指针指向待插入节点
            q->llink=p; //待插入节点的左指针指向当前节点
        }
        return head;
    }
    else
    {
        printf("不存在这样的节点\n");
        free(q);
        return head;
    }
}
node *dele(node* head, int x)
{
    node *p=head;
    if(!head)
    {
      printf("链表是空的\n");
      return NULL;
    }
    while(p&&p->info!=x) p=p->rlink; //找到第一个等于x的节点,p指向待删除的节点
    if(head->info==x)//头结点等于x的情况
    {
        if(head->rlink==NULL) free(p),head=NULL; //若只有头结点,返回空
        else head=head->rlink,head->llink=NULL,free(p); //否则下一个作为头结点,头结点的左指针指向为空,释放空间
        return head;
    }
    if(p) //当找到等于x的节点
    {
        if(p->rlink==NULL) p->llink->rlink=NULL,free(p); //删除的点在尾部,尾指针向前移
        else
        {
            p->llink->rlink=p->rlink;  // 当前节点的前驱指向当前节点的后继
            p->rlink->llink=p->llink; //当前节点后继的左指针指向当前节点的前驱
            free(p);
        }
        return head;
    }
    else
    {
        printf("不存在这样的节点\n");
        return head;
    }
}
int main()
{
    int x,id;
    node  *head;
    printf("创建一个链表:\n");
    head=create();
    display(head);
    printf("输入要插入的节点和值:");
    scanf("%d%d",&id,&x);
    head=insert(head,id,x);
    display(head);
    printf("输入要删除的数据:");
    scanf("%d",&x);
    head=dele(head,x);
    display(head);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值