• 单链表的使用(插入,查找,删除,链表的倒置,删除相同结点)



    typedef struct node//该结构体代表一个结点

    {
    int data; //结点的数据域
    struct node *next; //结点的指针域
    }lnode,*linklist; //定义一个结构体变量和指向结构体的指针
    //用头插法创建一个链表
    linklist create_begin()
    {
    linklist head=(linklist)malloc(sizeof(lnode));//定义头结点并开辟空间
    head->next=NULL; //为避免指针乱指,将头结点下一个指针赋空
    int x;
    printf("please input the data: ");
    scanf("%d",&x);
    while(x!=-1) //数据为-1时停止继续输入
    {
    lnode *s=(linklist)malloc(sizeof(lnode));//s指向要插入的新结点,并为它开辟空间
    s->data=x;
    s->next=head->next; //将s结点的next指针 指向 头结点next指针 所指向的空间
    head->next=s; //将头结点的next指针指向s结点,实现头插
    printf("please input the data: ");
    scanf("%d",&x);
    }
    return head;
    }
    linklist create_end()
    {
    linklist head=(linklist)malloc(sizeof(lnode));//定义头结点并开辟空间
    head->next=NULL; //为避免指针乱指,将头结点下一个指针赋空
    lnode *p=head,*s; //定义指向结构体的p指针和s指针,使p指针指向头指针所指向的
    int x;
    printf("please input the data: ");
    scanf("%d",&x);
    while(x!=-1) //数据为-1时停止继续输入
    {
    s=(linklist)malloc(sizeof(lnode));//s指向要插入的新结点,并为它开辟空间
    s->data=x;
    s->next=p->next; //新结点的next指针指向p结点next指针所指向的,且p结点的next始终为空
    p->next=s; //p结点的next指向新结点
    p=s; //p指向s所指向的,确保p指针指向的结点始终为最后一个结点
    printf("please input the data: ");
    scanf("%d",&x);
    }
    return head;
    }
    //打印结点中的数据
    void print(lnode *p)
    {
    p=p->next;
    while(p)
    {
    printf("%d ",p->data);
    p=p->next;
    }
    printf(" ");
    }
    //查找链表中的结点,按照结点在链表中的次序查找,x代表顺序,默认头结点的下一个为1
    linklist findone(linklist p,int x)
    {
    p=p->next;//p从第一个结点开始查找
    int j=1;//记录结点数
    while(p)
    {
    if(j==x)
    return p;
    p=p->next;
    j++; //指针每后移一次结点数+1
    }
    return NULL;//循环跳出代表p指针为空,即没有查找到次序为x的结点
    }
    //查找链表中的结点,按照结点中的数据查找,x代表具体数据
    linklist findtwo(linklist p,int x)
    {
    p=p->next;
    while(p)
    {
    if(p->data==x)
    return p; //找到则返回该结点
    p=p->next;
    }
    return NULL;//遍历结束则返回空
    }
    //向链表中插入数据,i代表插入的位置,x代表插入的具体数据
    int insert(linklist head,int i,int x)
    {
    lnode *p,*s;
    p=findone(head,i-1);//要向指定位置插入新结点,必须找到指定位置的直接前驱结点,所以用p指向要插入位置的直接前驱结点
    if(p==NULL)
    {
    return false;//找不到直接前驱结点,插入失败
    }
    else
    {
    s=(linklist)malloc(sizeof(lnode));
    s->data=x;
    s->next=p->next;//要插入的结点s的next指针指向直接前驱结点的next指针所指向的结点,即指向当前要插入位置所在的结点
    p->next=s; //直接前驱结点的next指针指向新结点
    return true;//插入成功
    }
    }
    //删除链表中的指定位置结点,head为头指针,i为要删除结点在链表中的次序
    int del(linklist head,int i)
    {
    lnode *p,*s;
    p=findone(head,i-1); //p指向要删除结点的前一个结点是否存在
    //判断要删除结点的前一个结点是否存在
    if(p==NULL)
    {
    return false;
    }
    else
    {
    //判断要删除结点(p->next)是否存在
    if(p->next==NULL)
    {
    return false;
    }
    else
    {
    s=p->next; //s指向要删除的结点
    p->next=s->next;//p的next指向s的next指向的结点
    free(s); //释放s结点的空间
    return true;
    }
    }
    }
    //链表的倒置,思路:依次取原链表的每个结点,用头插法插入到新的链表中
    void reserve(linklist head)
    {
    lnode *p,*s;
    p=head->next;
    head->next=NULL;//创建一个新链表
    //p指向当前结点,判断p是否为空
    while(p)
    {
    //s表示要插入的结点,p用来标记下一个要插入的结点,防止丢失
    s=p;
    p=p->next;
    //用头插法依次插入
    s->next=head->next;
    head->next=s;
    }
    }
    //删除链表中重复的结点,思路:利用两个循环,p指向第一个结点,从它直接后继结点开始查找和它相同的结点,找到则删除,然后p依次向下指,直到最后结点
    void del_same(linklist head)
    {
    lnode *p,*s,*r;
    p=head->next;
    if(p!=NULL)
    while(p->next)//判断p的下一个结点是否存在
    {
    s=p;
    while(s->next)//从p的后继结点开始循环查找,此处和删除结点类似,必须要知道要删结点的直接前驱,如果找到相同的结点,s为直接前驱
    {
    if(s->next->data==p->data)
    {
    r=s->next;
    s->next=r->next;
    free(r);
    }
    else
    {
    s=s->next;//依次向后遍历
    }
    }
    if(p->next!=NULL)//如果p的下一个结点不为空,p指向下一个结点,否则的话,p指向空,循环条件(p->next)会出错
    p=p->next;
    }
    }
  • 相关阅读:
    第一次学习打卡
    第一次Java作业
    浏览器兼容问题汇总
    js 获取js自身参数
    文字内容展开与折叠jquery代码
    Jquery DIV滚动至浏览器顶部位置固定
    js操作cookie方法
    利用CSS边框合并属性打造table细边框
    js获取当前日期及获取当前日期的前一天日期函数
    asp.net抓取网页html源代码失败 只因UserAgent作怪
  • 原文地址:https://www.cnblogs.com/runninglzw/p/3763766.html
Copyright © 2020-2023  润新知