• 【考研数据结构代码题】day11-day20


    十一、尾插法 

    思想:r->next=S; r=S;
    **/

    1. LinkList insert_tail(LinkList &L){
    2.     LNode *S, *r=L;
    3.     int x;
    4.     L=(LinkList)malloc(sizeof(LNode));
    5.     scanf("%d",&x);
    6.     while(x!=NULL){
    7.         S=(LinkList)malloc(sizeof(LNode));
    8.         S->data=x;
    9.         r->next=S;
    10.         r=S;
    11.     }
    12.     r->next=NULL;
    13. }


        

        
    /**
    十二、将带头结点的单链表就地逆置


    思想:使用头插法依次将结点重新插入单链表
    逆置就想到头插法
    防止断链:r指针标记,保留p的后继,直到r为空
    **/
    法一:

    1. LinkList reverse_linklist(LinkList &L){
    2.     LNode *P=L->next, *r=p->next;
    3.     L->next=NULL;//头结点指向空
    4.     while(p!=NULL){
    5.         r=p->next;//保留后继,防止断链
    6.         //头插法
    7.         p->next=L->next;
    8.         L->next=p;
    9.         //p,r向后移动
    10.         p=r;
    11.     }
    12.     return L;
    13. }

    法二:改变链表指针方向:将p的后继,指向p的前驱
    使用三个指针pre,p,r,

    1. LinkList reverse_linklist(LinkList &L){
    2.     LNode *pre=L->next,
    3.     *P=pre->next,
    4.     *r=p->next;
    5.     pre->next=NULL;//第一个结点的后继指向空
    6.     while(r!=NULL){
    7.         p->next=pre;
    8.         pre=p;
    9.         p=r;
    10.         r=r->next;
    11.     }
    12.     L->next=p;//最后,r指向空,头结点指向最后一个结点
    13.     return L;
    14. }


    /**
    十三、带头结点的单链表,结点值无序,编写函数删除大小介于s与t之间的元素


    思想:1.找 2.删除
    遍历链表,删除在最小值和最大值之间的数
    **/

    1. void Dels_t_Link(LinkList &L int s,int t){
    2.     LNode *pre=L, *p=L->next;
    3.     while(p!=NULL){
    4.         if(p->data>=s && p->data<=t){
    5.             pre->next=p->next;
    6.             free(p);
    7.             p=p->next;
    8.         }
    9.         else{//如果不是,两个指针都向后移
    10.             pre=p;
    11.             p=p->next;
    12.         }
    13.     }
    14.     
    15. }


    /**
    十四、给定两个单链表,编写算法找出两个单链表的公共结点  双指针问题


    若有公共结点,链表形状是Y型,而不是X型

    ○ → ○ → ○ → ○ ↘          
                                     ○ → ○ → ○
            ○ → ○ → ○ ↗
    思考:1.如何判断链表有公共结点? ----》 p,q同时到达表尾时,p=q 说明有公共结点;没有p=q 说明不存在公共结点
        2.如何同时到达表尾? 长度相等好办,长度不相等呢?   ----》 若LA较长,LA表的p指针先移动k次(k=LA.length-LB.length)然后p,q再同步向后移动
    **/
    法一:暴力法;两次循环 时间复杂度O(LA x LB)

    1. search_commmon(LinkList &LA,LinkList &LB){
    2.         while(p!=NULL){
    3.             while(q!=NULL){
    4.             if(p=q){    //p=q,说明两个表的结点相遇/重合
    5.                 return p;
    6.             q=q->next;
    7.             }
    8.             p=p->next;//一轮之后,没找到,p后移一个单位
    9.         }
    10.     }


        
    法二:线性的方法优化后:O(2LA + LB) 也就是 O(LA+LB)

    1. LinkList search_commmon(LinkList &LA,LinkList &LB){
    2.     int k;
    3.     int lenA=length(LA);
    4.     int lenB=length(LB);
    5.     if(lenA-lenB){
    6.         k=lenA-lenB;    //求出两个链表之差
    7.     }else {
    8.         k=lenB-lenA;
    9.     }
    10.     p=LA->next;
    11.     q=LB->next
    12.     while(k--){ //p先移动k位
    13.         p=p->next;
    14.     }
    15.     while(p!=NULL){
    16.         if(p=q) return p; //若p=q,则找到了公共结点
    17.         else{             //若不等,则同步向后移动
    18.             p=p->next;
    19.             q=q->next;
    20.         }
    21.     }
    22.     return 0;   //如果最后都没用p=q,说明没有公共结点
    23. }


    /**
    十五、将带头结点的单链表A 分解为两个带头结点的单链表A和B;


    使得A表中含有原表中序号为奇数的元素,B表中含有原表中序号为偶数的元素,且保持其相对顺序不变
    分析:要保持顺序不变,自然想到尾插法
    思想:不断地使用尾插法,依次生成链表A、B
    **/

    1. LinkList create(LinkList &L){
    2.     int i=0;
    3.     B = (LinkList)malloc(sizeof(LNode));
    4.     LNode *ra,*rb=B;  //A和B的表尾指针
    5.     p=A->next;
    6.     while(p!=NULL){
    7.         i++;
    8.         if(i%2==0){ //如果是偶数,插入B中
    9.             rb->next=p;
    10.             rb=p;
    11.         }
    12.         else{   //如果是奇数,插入到A中
    13.             ra->next=p;
    14.             ra=p;
    15.         }
    16.         p=p->next;
    17.     }
    18.     ra->next=NULL;
    19.     rb->next=NULL;
    20.     return B;
    21. }


       /**
    十六、将带头结点单链表C={a1,b1,a2,b2,...an,bn}拆分成两个单链表


    使得A={a1,a2,...an},B={bn,...b2,b1}
    分析:对于A使用尾插法;对B采用头插法
            头插防断链;尾插留指针
    **/

    1. LinkList create(LinkList &hc){
    2.     LNode *ra=hc;   //尾插法的尾指针
    3.     LNode *p=hc->next;  //遍历指针
    4.     A=(LinkList)malloc(sizeof(LNode));
    5.     B=(LinkList)malloc(sizeof(LNode));
    6.     A->next=NULL;
    7.     B->next=NULL;
    8.     while(p!=NULL){//头插尾插交替进行,不必使用i
    9.         ra->next=p;//尾插法插入A
    10.         ra=p;
    11.         p=p->next;
    12.         if(p!=NULL){
    13.             r=p->next;  //标记防断链
    14.             p->next=B->next; //头插法插入B
    15.             B->next=p;
    16.             p=r;
    17.         }       
    18.     }
    19.     ra->next=NULL;
    20. }


    /**
    十七、递增有序的单链表中,删除重复的结点

    分析:递增有序,则重复元素是相邻的
        1.找    2.删(需要知道前驱pre)  双指针(也可以用后继,如法二)
    **/

    1. 法一:双指针pre、p
    2. void del_same(LinkList &L){
    3.     LNode *pre=L->next, *p=pre->next;
    4.     while(p!=NULL){
    5.         if(pre->data==p->data){
    6.             pre->next=p->next;
    7.             free(p);
    8.             p=p->next;
    9.         }
    10.         else{   //两个指针同时向后移一位
    11.             pre=p;
    12.             p=p->next;
    13.         }
    14.     }
    15. }

    法二:一个指针p (实际还是双指针的思想,需令q=p->next)

    1. void del_same(LinkList &L){
    2.     LNode *p=L->next,*q;
    3.     while(p->next!=NULL){
    4.         q=p->next;
    5.         if(p->data==q->data){
    6.             p->next=q->next;
    7.             free(q);
    8.             p=p->next;
    9.         }
    10.         else{
    11.             p=p->next;//相较法一,这里就只需移动一个指针了
    12.         }
    13.     }
    14. }


    /**
    十八、两个按元素值递增次序排列的单链表,编写算法将两个单链表归并为一个元素值递减排列的单链表,要求利用原本的单链表结点存放归并后的单链表


    思想:不断地将较小数头插法插入入合并链表,被插入结点的的指针后移一位,直到某一条链表为空
    **/

    1. LinkList Merge(LinkList &LA,LinkList &LB){
    2.     LNode *p=LA->next,*q=LB->next;
    3.     A->next=NULL;
    4.     while (p!=NULL){
    5.         while(q!=NULL){
    6.             if(p->data > q->data){ //将B中较小数头插入A, q后移继续比较
    7.                 r=q->next;//防止断链
    8.                 q->next=LA->next;
    9.                 LA->next=q;
    10.                 q=r;//q向后移动
    11.             }
    12.             else{ //若p->data较小,p结点头插入A,p后移一位,继续比较
    13.                 r=p->next;
    14.                 p->next=LA->next;
    15.                 LA->next=p;
    16.                 p=r;
    17.             }
    18.         }    
    19.     }
    20.     //q==NULL,但p!=NULL;将A中剩余部分依次头插入A,或者改变指针方向
    21.     while(p!=NULL){
    22.         r=p->next;
    23.         p->next=LA->next;
    24.         LA->next=p;
    25.         p=r;
    26.     }
    27.     //若p=NUUL;但q!=NULL;将B中剩余的依次头插入A,或者改变指针方向
    28.     while(q!=NULL){
    29.         r=q->next;
    30.         q->next=LA->next;
    31.         LA->next=q;
    32.         q=r;
    33.     }
    34. }


    /**
    十九、A和B是两个单链表,其中元素递增有序,设计算法从A、B中的公共元素产生单链表C,要求不破坏A、B的结点(即不能改变其指针,只能申请新结点)

    思想:表A、B有序,依次比较A、B元素。小的指针往后移,
    若相等则创建新的结点,其元素值等于两结点的值。
    使用尾插法插入到新表中,并将两个指针同时后移一位,直到表尾(若有剩余,无需处理)
    **/

    1. LinkList common(LinkList A,LinkList B){
    2.     LNode *p=A->next,*q=B->next;
    3.     LNode *r;
    4.     LinkList C = (LinkList)malloc(sizeof(LNode));
    5.     r=C;
    6.     while(p!=NULL && q!=NULL){
    7.         if(p->datadata){
    8.             p=p->next;
    9.         }
    10.         else if(p->data>q->data){
    11.             q=q->next;
    12.         }
    13.         else if(p->data==q->data){  //若两个元素相等
    14.             S=(LinkList)malloc(sizeof(LNode));
    15.             S->data=p->data;
    16.             r->next=S;
    17.             r=S;
    18.             p=p->next;  //两个指针同时向后移
    19.             q=q->next;
    20.         }
    21.         r->next=NULL;
    22.         return C;   
    23.     }
    24.  
    25. }

    /*************
    二十、两个链表A、B分别表示两个集合,其元素递增有序排列。编写函数求A、B的交集,并存放于A链表中

    分析:A中只能存放公共元素,不符合要求的结点要释放掉 边比较边释放空间
    算法思想:
    1.依次扫描A、B结点,比较扫描结点data域的值,将较小的指针向后移(并释放空间)
    2.若两者相等,尾插入A,直到遍历表尾
    3.若有剩余,则剩余元素不可能有交集,全部释放)
    **/

    1. LinkList common(LinkList &A,LinkList &B){
    2.     LNode *p=A->next,*q=B->next, *r,*u;
    3.     A->next=NUll;//尾插尾结点置空,p保留了A的后继,不用担心断链
    4.     r=A;
    5.     while(p!=NULL&&q!=NULL){
    6.         if(p->datadata){
    7.             u=p;
    8.             p=p->next;
    9.             free(p);
    10.         }
    11.         else if(p->data > q->data){
    12.             u=q;
    13.             q=q->next;
    14.             free(u);
    15.         }
    16.         else if(p->data==q->data){  //如果两元素相等,保留p,释放q
    17.             //保留p,尾插入A
    18.             r->next=p;
    19.             r=p;
    20.             p=p->next;
    21.             //释放q
    22.             u=q;
    23.             q=q->next;
    24.             free(u);
    25.         }
    26.     }
    27.     while(p!=NULL){ //若A有剩余
    28.         u=p;
    29.         p=p->next;
    30.         free(u);
    31.     }
    32.     while(q!=NULL){ //若B有剩余
    33.         u=q;
    34.         q=q->next;
    35.         free(u);
    36.     }
    37.     r->next=NULL;
    38.     return A;
    39. }

  • 相关阅读:
    学习笔记——七周成为数据分析师《第一周:数据分析思维》
    ARM接口编程—GPIO(exynox 4412平台)
    Exception in thread “main“ java.lang.UnsupportedOperationException解决办法
    (Java高级教程)第一章Java多线程基础-第一节3:线程状态和线程安全
    微信又更新啦,再也不怕错过女朋友的消息
    【自留地】后端 - PHP - MySQL - Nginx - Python - Java
    用Python操控Minecraft我的世界 1.安装Spigot服务器并添加RaspberryJuice插件
    Redis面试常问题2022整理
    聊聊Mybatis的Executor之CachingExecutor
    c语言实现数据结构中的顺序表
  • 原文地址:https://blog.csdn.net/Arthur_diyun/article/details/128025190