C代码实现:操作循环链表按规则移除结点

来源:互联网 发布:windows平板和安卓平板 编辑:程序博客网 时间:2024/06/07 02:10

 一组顺序数字 1~10,依123 123 循环数数,每遇到3的位置移除该位置数,重新123继续数;

 直至剩余一个数,问该数是多少?


 同事提起的一个问题,思考之后使用C语言实现了下,代码如下:

#include <stdlib.h>#include <stdio.h>//定义一个数据结构 用于创建链表的结点typedef struct list{    int num;            //结点值    struct list * next; //结点指向下一个结点的指针}List;//*创建循环链表 接收链表长度 返回头结点指针List * create(int n){    List * head;    //头结点 指针    List * p1;      //当前结点的前一结点 指针    List * p2;      //当前结点 指针        int i;          //变量i 用于指示循环;同时也用作后续结点的num值(便于理解)        //为头结点 动态分配其数据类型大的空间 返回指针 赋值给head指针;出错则打印error    if ((head = (List *)malloc(sizeof(List))) == NULL) {        printf("Error");        return NULL;    }        //为头结点赋值:将头结点的next指针置空,num设置为链表长度    head->next = NULL;    head->num = n;        //循环添加头结点之后的后续结点    for (i= 1; i < n + 1; i++) {        //动态分配结点 赋值给临时变量 指针p        List * p=(List *)malloc(sizeof(List));                //p num字段赋值为i的值(对应一个数字)        p->num = i;                if (head->next == NULL) {            //将后续结点连入链表头结点(只连入一次)            head->next = p;                        p1 = head;  //更新当前结点的前一结点 指针            p2 = p;     //更新当前结点 指针        }else{            p1 = p2;    //更新当前结点的前一结点 指针            p2->next = p;   //将新创建结点 连入链表            p2 = p;     //更新当前结点 指针        }    }        p2->next = head->next;//将链表 首尾链接 形成循环        //返回头结点指针    return head;}//*操作循环链表 将对应数数3的位置结点跳过 重新数数 直至链表剩余一个结点 返回该结点指针//*接收参数:链表头结点指针 链表长度List * lastOne(List * table,int lenth){    //判断链表是否为空    if (table->next == NULL) {        return NULL;    }        //判断链表是否只有一个结点 若只有一个结点 返回其指针即可    if (table->next->next == NULL) {        return table->next;    }        List * beforEnd = table;    //当前结点的前一结点指针    List * end = table->next;   //当前结点指针        int i = 0;      //变量 表示1-3循环    int count = 0;  //循环条件:长度为length的链表 最多只需要循环遍历处理length-1次 最后保留1个数    while (count < lenth - 1) {        i++;//表示位置 从1开始        if (i%3 == 0) {            //位置数数至3 则对应位置的结点需要移除 用p表示            List * p = end;            printf("对应下标3的位置:需要移除的数是%d\n",p->num);                        //链表重新连接            beforEnd->next = end->next;                        //更新当前结点指针(当前结点的前一结点指针不变)            end = end->next;                        //释放移除的结点内存            if (p != NULL) {                free(p);                count ++;//处理次数 用作循环条件            }            i = 0;//位置标识置0        }else{            //继续遍历            printf("对应下标%d的位置:数字=%d\n",i,end->num);            beforEnd = end; //更新当前结点的前一结点指针            end = end->next;//更新当前结点指针        }    }    printf("最后剩余的数字=%d\n",end->num);    //返回最终剩余的一个结点    return end;}int main() {    //定义链表长度    int num = 10;        //创建循环链表 返回链表头结点    List * start = create(num);        //测试 循环打印链表 我们可以打印2*num次    List * p = start->next;    int i =0;    while (p && i<(num*2)) {        printf("%d\n",p->num);        p = p->next;        i++;    }        //操作循环链表    List * point = lastOne(start,num);        //释放最终链表中剩余的一个结点    if (point != NULL) {        free(point);    }        //释放链表头结点    if (start != NULL) {        free(start);    }        return 0;}


C语言的部分也不太熟悉了,代码实现不是很简洁,希望和大家交流,学习更简洁易懂的处理;

log如下:

./linkedlist 1234567891012345678910对应下标1的位置:数字=1对应下标2的位置:数字=2对应下标3的位置:需要移除的数是3对应下标1的位置:数字=4对应下标2的位置:数字=5对应下标3的位置:需要移除的数是6对应下标1的位置:数字=7对应下标2的位置:数字=8对应下标3的位置:需要移除的数是9对应下标1的位置:数字=10对应下标2的位置:数字=1对应下标3的位置:需要移除的数是2对应下标1的位置:数字=4对应下标2的位置:数字=5对应下标3的位置:需要移除的数是7对应下标1的位置:数字=8对应下标2的位置:数字=10对应下标3的位置:需要移除的数是1对应下标1的位置:数字=4对应下标2的位置:数字=5对应下标3的位置:需要移除的数是8对应下标1的位置:数字=10对应下标2的位置:数字=4对应下标3的位置:需要移除的数是5对应下标1的位置:数字=10对应下标2的位置:数字=4对应下标3的位置:需要移除的数是10最后剩余的数字=4




阅读全文
0 0