zoukankan      html  css  js  c++  java
  • 【数据结构1800题 (陈守孔) 第2章】线性表 算法设计题全解

    【2.5】

    【题目大意】去掉链表中绝对值重复过的数字(只保留第一个)

    【解法】删除的时候用当前枚举到的节点的前一个节点,这样的话能够方便删除。用数组来判重。

    【代码】

    int flag[10000+10];
    void quchong(LNode *L){
        LNode *p = L;
        while (p->next!=NULL){
            int t = p->next->data;
            if (t<0) t = -t;
            if (flag[t]==0){
                flag[t] = 1;
                p = p->next;
            }else{
                LNode *temp = p->next;
                p->next = temp->next;
                free(temp);
            }
        }
    }
    

      

    【2.6】

    【题目大意】让你把两个有序链表合并成一个有序链表

    【做法】就按照归并排序的思路合并就ojbk了,合并的时候把合并后的结果接在第一个链表的头结点后面就好!

    【代码】

    //合并之后,放到第一个链表里面
    void _merge(LNode *h1,LNode *h2){
        LNode *p1 = h1->next;LNode *p2 = h2->next,*t;
        h1->next = NULL;
        t = h1;
        while (p1!=NULL && p2!=NULL){
            if (p1->data<p2->data){
                t->next = p1;
                t = p1;
                p1 = p1->next;
            }else{
                t->next = p2;
                t = p2;
                p2 = p2->next;
            }
        }
        while (p1!=NULL) {
            t->next = p1;t = p1;
            p1=p1->next;
        }
    
        while (p2!=NULL){
            t->next = p2;t = p2;
            p2 = p2->next;
        }
    }
    

      

    【2.7】

    【题目大意】一个升序一个逆序的链表,让你合并成一个有序的单链表。

    【做法】把逆序的那个原地倒置就好

    //先把第二个链表原地倒置 然后当成2.6的合并做就好
    void _merge(LNode *h1,LNode *h2){
        LNode *p = h2->next;
        h2->next = NULL;
        while (p){
            LNode * temp = p->next;
            p->next = h2->next;
            h2->next = p;
            p = temp;
        }
    
        LNode *p1 = h1->next;LNode *p2 = h2->next,*t;
        h1->next = NULL;
        t = h1;
        while (p1!=NULL && p2!=NULL){
            if (p1->data<p2->data){
                t->next = p1;
                t = p1;
                p1 = p1->next;
            }else{
                t->next = p2;
                t = p2;
                p2 = p2->next;
            }
        }
        while (p1!=NULL) {
            t->next = p1;t = p1;
            p1=p1->next;
        }
    
        while (p2!=NULL){
            t->next = p2;t = p2;
            p2 = p2->next;
        }
    }
    

      

    【2.8】同【2.6】代码

    【2.9】

    【题目大意】

    无头结点的单链表两个
    两个都是有序的
    让你把这两个单链表合并成一个链表。
    要求不能破坏第二个链表的结构

    【做法】

    在做归并的时候,如果第一个等于第二个,那么就跳过第二个链表遍历到的元素,这样第一个链表上有的元素,第二个链表里对应的就不会管他了。

    无头结点不好直接在h1的基础上添加新的元素,所以自己另外创建一个无头结点的链表.一个一个累加上去就好。

    【代码】

    //这里必须要用二重指针,因为我们要改变第一个链表的指向(我们新创的一个链表)
    //main函数里调用_merge(&h1,h2)即可(h2不用变)
    void _merge(LNode **h1,LNode *h2){
        LNode *p1 = *h1;LNode *p2 = h2,*h3;
        h3 = newnode();//不好直接接在第一个链表上,所以新创建一个
        LNode *t = newnode();
        t = h3;
        while (p1!=NULL && p2!=NULL){
            if (p1->data<p2->data){
                LNode *temp = newnode(); //不能破坏原始链表,所以只能自己创了
                temp->data = p1->data;
    
                t->next = temp;
                t = temp;
    
                p1 = p1->next;
            }else if (p1->data>p2->data){
                LNode *temp = newnode();
                temp->data = p2->data;
    
                t->next = temp;
                t = temp;
    
                p2 = p2->next;
            }else if (p1->data==p2->data){
                //如果两个链表中有,那么只要第一个链表中的
                p2 = p2->next;
            }
        }
        if (p1==NULL) p1 = p2; //这样写比较简洁
        while (p1!=NULL) {
            LNode *temp = newnode();
            temp->data = p1->data;
    
            t->next = temp;t = temp;
            p1=p1->next;
        }
    
        *h1 = h3->next;//让h1再指向h3
    }
    

      

    【2.10】和【2.9的代码一样】只不过变成带头结点的了。遍历到两个链表的p和q的时候,如果p->data==q->data,则跳过其中一个就好了。

    因为是集合,所以只会重复一次。

    【2.11】

    【题目大意】

    求两个集合的交集(在两个链表里递增排列),

    【做法】

    也没说带不带头结点。。。就当做是有头结点吧。放在A链表中,这个简单,重构下A链表就好。

    在归并的时候,如果p和q节点的节点值相同,就加到A链表的后面就好

    【代码】

    void _merge(LNode *h1,LNode *h2){
        LNode *p1 = h1->next;LNode *p2 = h2->next,*t;
        h1->next = NULL;
        t = h1;
        while (p1!=NULL && p2!=NULL){
            if (p1->data<p2->data){
                p1 = p1->next;
            }else if (p1->data>p2->data){
                p2 = p2->next;
            }else if (p1->data==p2->data){
                //如果两个链表中有,任取一个放在newA链表后面
                t->next = p1;
                t = p1;
                p1 = p1->next;
            }
        }
    }
    

      

    【2.12】和【2.11】一样的。

    【2.13】也一样。。

    【2.14】

    题目大意:给你三个递增链表A,B,C让你求A∪(B∩C),时间复杂度要求为O(|A|+|B|+|C|)

  • 相关阅读:
    我的Git教程 之 初始化本地库
    再学Java 之 Integer 包装类缓存
    再学Java 之 private、protected、public和default的作用域
    再学Java 之 形参个数可变函数
    再学Java 之 foreach循环
    解决MySQL中文乱码问题
    再学Java 之 解决No enclosing instance of type * is accessible
    从一个例子学习 instanceof 和 getclass 的区别
    如何单独启动wamp 中自带的MySQL
    网络游戏程序员须知 UDP vs TCP(转)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/11571430.html
Copyright © 2011-2022 走看看