线性表习题

一、数据准备

#define ERROR0

#define TRUE1

#define FALSE0

#define OK1

#define MAXSIZE20/* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */

typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */

//定义结点

typedef struct Node{

    ElemTypedata;

    structNode*next;

}Node;

typedefstructNode* LinkList;

二、初始化单向链表

Status InitList(LinkList *L){

    *L = (LinkList)malloc(sizeof(Node));

    if(*L==NULL) {

        returnERROR;

    }

    (*L)->next=NULL;

    returnOK;

}

三、插入数据到单向链表

Status InsertList(LinkList *L,int index,ElemType data){

    if(index<1) {

        returnERROR;

    }

    if(*L==NULL) {

        InitList(L);

    }


    LinkListp = *L;

    inti=1;

    while(i

        p = p->next;

        i++;

    }

    if(p ==NULL&& i==index) {

        returnERROR;

    }

    //生成新结点

    LinkList temp = (LinkList)malloc(sizeof(Node));

    temp->data= data;


    temp->next= p->next;

    p->next= temp;


    returnOK;

}

四、遍历单向链表


void TraverseList(LinkList L){

    if(L ==NULL) {

        return;

    }


    LinkListp = L->next;

    while(p!=NULL) {

        printf("%d ",p->data);

        p = p->next;

    }

    printf("\n");

}

五、作业

1.题目:

 将2个递增的有序链表合并为一个有序链表; 要求结果链表仍然使用两个链表的存储空间,不另外占用其他的存储空间. 表中不允许有重复的数据


void MergeList(LinkList *la,LinkList *lb,LinkList *lc){

    //目标:将2个递增的有序链表La,Lb 合并为一个递增的有序链表Lc

    if(*la==NULL&& lb ==NULL) {

        return;

    }else{

        if(*la ==NULL) {

            *lc = *lb;

        }else{

            *lc = *la;

        }

    }

    //pa 是链表La的工作指针,pb 是链表Lb的工作指针, 初始化为首元结点;

    *lc = *la;


    LinkListpa = (*la)->next;

    LinkListpb = (*lb)->next;

    LinkListpc = (*lc);

    LinkListtemp;

    while(pa && pb) {

        if(pa->data< pb->data) {

            //取较小者La中的元素,将pa链接在pc的后面,pa指针后移

            pc->next= pa;

            pc = pa;

            pa = pa->next;

        }elseif(pa->data> pb->data){

            //取较小者Lb的元素,将pb链接在pc后面, pb指针后移

            pc->next= pb;

            pc = pb;

            pb = pb->next;

        }else{

            //相等时取La中的元素,删除Lb的元素;

            pc->next= pa;

            pc = pa;

            pa = pa->next;

            temp = pb->next;

            free(pb);

            pb = temp;

        }

    }

    //将非空表的剩余元素之间链接在Lc表的最后

    pc->next= pa?pa:pb;

    //释放Lb的头结点

    free(*lb);

}

2.作业2:

 题目:

 已知两个链表A和B分别表示两个集合.其元素递增排列. 设计一个算法,用于求出A与B的交集,并存储在A链表中;

 例如:

 La = {2,4,6,8}; Lb = {4,6,8,10};

 Lc = {4,6,8}


void Intersection(LinkList *la,LinkList *lb,LinkList *lc){

    //目标: 求2个递增的有序链表La,Lb的交集, 使用头指针Lc指向带回;

    *lc = *la;

    LinkListpa,pb,pc,temp;

    //用pa,pb指向la,lb中的数据,进行比较

    pa = (*la)->next;

    pb = (*lb)->next;

    pc = *lc;


    while(pa && pb) {

        if(pa->data== pb->data) {

            //相等取pa,删除pb

            pc->next= pa;

            pc = pa;

            pa = pa->next;


            temp = pb->next;

            free(pb);

            pb = temp;

        }elseif(pa->data> pb->data){

            //删除较小的pb

            temp = pb;

            pb = pb->next;

            free(temp);

        }else{

            //删除较小的pa

            temp = pa->next;

            free(pa);

            pa = temp;

        }

    }


    //删除后面没比较过的数据

    while(pa) {

        temp = pa;

        pa = pa->next;

        free(temp);

    }

    while(pb) {

        temp = pb;

        pb = pb->next;

        free(temp);

    }

   //

    pc->next=NULL;

    free(*lb);

}

3.作业3:

 题目:

 设计一个算法,将链表中所有节点的链接方向"原地旋转",即要求仅仅利用原表的存储空间. 换句话说,要求算法空间复杂度为O(1);

 例如:L={0,2,4,6,8,10}, 逆转后: L = {10,8,6,4,2,0};

//后插法

void Inverse(LinkList *L){

    LinkListp = (*L)->next;

    (*L)->next=NULL;

    LinkList q;

    while(p !=NULL) {

        q = p->next;

        p->next= (*L)->next;


        (*L)->next= p;


        p = q;

    }

}

4.作业4:

 题目:

 设计一个算法,删除递增有序链表中值大于等于mink且小于等于maxk(mink,maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同)的所有元素;

解法一:


voidDeleteMinMax(LinkList*L,intmink,intmaxk){

    LinkListp = (*L)->next;

    LinkListq = (*L);

    LinkListtemp;

    while(p) {

        if(p->data>mink && p->data< maxk) {

            temp = p;

            p = p->next;


            q->next= p;


            free(temp);

        }else{

            q = p;

            p = p->next;

        }

    }



}

解法二:

//解法二:

voidDeleteMinMax2(LinkList*L,intmink,intmaxk){

    //目标: 删除递增有序链表L中值大于等于mink 和小于等于maxk的所有元素


    LinkListp,q,pre;

    pre = *L;

    LinkListtemp;


    //p指向首元结点

    p = (*L)->next;


    //1.查找第一值大于mink的结点

    while(p && p->data< mink) {

        //指向前驱结点

        pre = p;

        p = p->next;

    }


    //2.查找第一个值大于等于maxk的结点

    while(p && p->data<=maxk) {

        p = p->next;

    }


    //3.修改待删除的结点指针

    q = pre->next;

    pre->next= p;


    while(q != p) {

        temp = q->next;

        free(q);

        q = temp;

    }

}

5.题目5:

 设将n(n>1)个整数存放到一维数组R中, 试设计一个在时间和空间两方面都尽可能高效的算法;将R中保存的序列循环左移p个位置(0

 例如: pre[10] = {0,1,2,3,4,5,6,7,8,9},

 n = 10,p = 3;

 pre[10] = {3,4,5,6,7,8,9,0,1,2}

//交换元素

voidReverse(int*pre,intleft,intright){

    inti = left;

    intj = right;

    while(i


        pre[i] = pre[i] + pre[j];

        pre[j] = pre[i] - pre[j];

        pre[i] = pre[i] - pre[j];


        i++;

        j--;

    }

}

//n为数组长度,p为移动几位,p<n

voidLeftShift(int*pre,intn,intp){

    //将长度为n的数组pre 中的数据循环左移p个位置

    if(p>0&& p

        //1. 将数组中所有元素全部逆置

        Reverse(pre,0, n-1);

        //2. 将前n-p个数据逆置

        Reverse(pre,0, n-1-p);

        //3. 将后p个数据逆置

        Reverse(pre, n-p, n-1);

    }

}


6.题目6:

 已知一个整数序列A = (a0,a1,a2,...an-1),其中(0<= ai <=n),(0<= i<=n). 若存在ap1= ap2 = ...= apm = x,且m>n/2(0<=pk<n,1<=k<=m),则称x 为 A的主元素. 例如,A = (0,5,5,3,5,7,5,5),则5是主元素; 若B = (0,5,5,3,5,1,5,7),则A中没有主元素,假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出数组元素中的主元素,若存在主元素则输出该元素,否则输出-1.


int MainElement(int *A,int n){

    //目标: 求整数序列A中的主元素;


    //count 用来计数

    intcount =1;

    //key 用来保存候选主元素, 初始A[0]

    intkey = A[0];

    //1,3,5,2,5,5,5

    //(1) 扫描数组,选取候选主元素

    for(inti=1; i

        if(A[i] == key) {

            //(2) 如果A[i]元素值 == key ,则候选主元素计数加1;

            count++;

        }else{

            if(count>0) {

                //(3) 当前元素A[i] 非候选主元素,计数减1;

                count--;

            }else{

                //(4) 如果count 等于0,则更换候选主元素,重新计数

                key = A[i];

                count =1;

            }

        }

    }

    //如果count >0

    if(count>0) {

        //(5)统计候选主元素的实际出现次数

        for(inti=0; i

            if(A[i] == key) {

                count++;

            }

        }

    }

    //(6)判断count>n/2, 确认key是不是主元素

    if(count>n/2) {

        returnkey;

    }

    //不存在主元素

    return-1;

}

7.题目7:

 用单链表保存m个整数, 结点的结构为(data,link),且|data|<=n(n为正整数). 现在要去设计一个时间复杂度尽可能高效的算法. 对于链表中的data 绝对值相等的结点, 仅保留第一次出现的结点,而删除其余绝对值相等的结点.例如,链表A = {21,-15,15,-7,15}, 删除后的链表A={21,-15,-7};

void DeleteEqualNode(LinkList *L,int n){

    //目标: 删除单链表中绝对值相等的结点;

    //1. 开辟辅助数组p.

    int*p =alloca(sizeof(int)*n);

//    int *p = malloc(sizeof(int)*n);

    //2.数组元素初始值置空

    for(inti=0; i

        *(p+i) =0;

    }

    //3.指针temp 指向首元结点

    //4.遍历链表,直到temp = NULL;

    LinkListtemp = (*L)->next;

    LinkListr = *L;

    while(temp !=NULL) {

        //5.如果该绝对值已经在结点上出现过,则删除该结点

        if(p[abs(temp->data)] ==1) {

            //移除

            //临时指针指向temp->next

            r->next= temp->next;

            //删除temp指向的结点

            free(temp);

            //temp 指向删除结点下一个结点

            temp = r->next;

        }else{

            //6. 未出现过的结点,则将数组中对应位置置为1;

            p[abs(temp->data)] =1;//记录已经出现过了

            r = temp;

            //继续向后遍历结点

            temp = temp->next;

        }

    }

}


六、验证

intmain(intargc,constchar* argv[]) {

    printf("线性表练习篇!\n");

    //链表相关的题目,有兴趣的可以尝试:https://leetcode-cn.com/tag/linked-list/

    StatusiStatus;

    LinkListLa,Lb,Lc,L;

    InitList(&La);

    InitList(&Lb);


////    ---------作业1--------

//    printf("******题目1:********\n");

//    //设计2个递增链表La,Lb

//    for(int j = 10;j>=0;j-=2)

//    {

//        iStatus = InsertList(&La, 1, j);

//    }

//    printf("La:\n");

//    TraverseList(La);

//

//    for(int j = 11;j>0;j-=2)

//    {

//        iStatus = InsertList(&Lb, 1, j);

//    }

//    printf("Lb:\n");

//    TraverseList(Lb);

//

//    MergeList(&La, &Lb, &Lc);

//    printf("Lc:\n");

//    TraverseList(Lc);


//      /*---------作业2--------*/

//        printf("******题目2:********\n");

//        InsertList(&La, 1, 8);

//        InsertList(&La, 1, 6);

//        InsertList(&La, 1, 4);

//        InsertList(&La, 1, 2);

//        printf("La:\n");

//        TraverseList(La);

//

//

//        InsertList(&Lb, 1, 10);

//        InsertList(&Lb, 1, 8);

//        InsertList(&Lb, 1, 6);

//        InsertList(&Lb, 1, 4);

//        printf("Lb:\n");

//        TraverseList(Lb);

//

//        Intersection(&La, &Lb, &Lc);

//        printf("Lc:\n");

//        TraverseList(Lc);


//        /*---------作业3--------*/

//        printf("******题目3:********\n");

//        InitList(&L);

//        for(int j = 10;j>=0;j-=2)

//        {

//            iStatus = InsertList(&L, 1, j);

//        }

//        printf("L逆转前:\n");

//        TraverseList(L);

//

//        Inverse(&L);

//        printf("L逆转后:\n");

//        TraverseList(L);


//        /*---------作业4--------*/

//        printf("******题目4:********\n");

//        InitList(&L);

//        for(int j = 10;j>=0;j-=2)

//        {

//            iStatus = InsertList(&L, 1, j);

//        }

//        printf("L链表:\n");

//        TraverseList(L);

//

//        DeleteMinMax(&L, 4, 10);

//        printf("删除链表mink与maxk之间结点的链表:\n");

//        TraverseList(L);


//        /*---------作业5--------*/

//        printf("******题目5:********\n");

//        int pre[10] = {0,1,2,3,4,5,6,7,8,9};

//        LeftShift(pre, 10, 3);

//        for (int i=0; i < 10; i++) {

//            printf("%d ",pre[i]);

//        }

//        printf("\n");


//    //    /*---------作业6--------*/

//    printf("******题目6:********\n");

//    int  A[] = {0,5,5,3,5,7,5,5};

//    int  B[] = {0,5,5,3,5,1,5,7};

//    int  C[] = {0,1,2,3,4,5,6,7};

//

//    int value = MainElement(A, 8);

//    printf("数组A 主元素为: %d\n",value);

//    value = MainElement(B, 8);

//    printf("数组B 主元素为(-1表示数组没有主元素): %d\n",value);

//    value = MainElement(C, 8);

//    printf("数组C 主元素为(-1表示数组没有主元素): %d\n",value);

         /*---------作业7--------*/

        //21,-15,15,-7,15

        printf("******题目7:********\n");

        InitList(&L);

        InsertList(&L,1,21);

        InsertList(&L,1, -15);

        InsertList(&L,1,15);

        InsertList(&L,1, -7);

        InsertList(&L,1,15);


        DeleteEqualNode(&L,21);

        TraverseList(L);

    return0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容