• 链表基本功能


      链表虽然也是线性表,但是相比于顺序表,让人操的心却不是同一个等级的,小小一道题目都可以分分钟虐死大半自信,昨晚憋了一个晚上的插入排序,虽然知道算法,奈何敌人太过于狡猾(指针渣渣。。)。早上几乎把链表的基本操作都做了一遍,指针指的飞起。。。

      下午曹老师给我讲解了下插入排序(还好自己没有继续搞下去,,),这种高深复杂的实现,小白还是从模仿开始的好啊,自己很难挤出来,浪费时间不说,自信真的所剩无几了,不多说,一下是一天的劳动成果

    #include<stdio.h>
    #include<stdlib.h>
    #define MAXSIZE 100
    typedef struct _node
    {
    int data;
    struct _node *next;
    }node_t;

    typedef struct linklist
    {
    node_t *head;
    node_t *tail;
    int length;
    }linklist_t;

    linklist_t* init_lklist(linklist_t *plklist)
    {
    plklist->head=NULL;
    plklist->tail=NULL;
    plklist->length=0;
    return (plklist);
    }


    int head_inser_lklist(linklist_t *plklist, node_t *pnew)
    {
    if(plklist->head==NULL)
    {
    plklist->head = pnew;
    plklist->tail = pnew;
    plklist->length++;
    }
    else
    {
    pnew->next = plklist->head;
    plklist->head = pnew;
    plklist->length++;
    }
    }

    int middle_inser_lklist(linklist_t *plklist, int pos, int val)//瑕佸湪绗�簩涓�綅缃�紑濮嬫彃鍏?
    {
    int i=1;
    node_t *p = plklist->head;

    if(pos == 1 || pos == 0)
    {
    node_t *pnew = (node_t *)malloc(sizeof(node_t *)); //鎶婁紶杩涙潵 鐨勬暟鎹�皝瑁呮垚鑺傜偣锛屾敞鎰忚�鍒嗛厤绌洪棿
    pnew->data = val;
    head_inser_lklist(plklist, pnew);
    return 0;
    }

    while(p != NULL && i <pos-1) //绉诲姩娲诲姩鑺傜偣鍒皃os浣嶇疆鐨勫墠涓€涓?
    {
    p = p->next;
    i++;
    }
    if( i<pos-1 ||p==NULL ) //鍒ゆ柇鏄�惁瓒婄晫
    {
    printf("insert error ! ");
    exit(-1);
    }

    node_t *pnew = (node_t *)malloc(sizeof(node_t *)); //鎶婁紶杩涙潵 鐨勬暟鎹�皝瑁呮垚鑺傜偣锛屾敞鎰忚�鍒嗛厤绌洪棿
    pnew->data = val;

    node_t *q = p->next; //瀹氫箟鏂拌妭鐐规寚鍚憄鐨勪笅涓€涓�妭鐐?

    pnew->next = q; //鎻掑叆鎿嶄綔
    p->next = pnew;

    return 0;
    }

    int tail_inser_lklist(linklist_t *plklist, node_t *pnew)
    {
    if(plklist->head==NULL)
    {
    plklist->head = pnew;
    plklist->tail = pnew;
    plklist->length++;
    }
    else
    {
    plklist->tail->next = pnew;
    plklist->tail = pnew;
    plklist->length++;
    }
    return 0;
    }
    int delete_lklist(linklist_t *plklist, int pos)//瑕佸湪绗�簩涓�綅缃�紑濮嬫彃鍏?
    {
    int i=1;
    node_t *p = plklist->head;

    if(pos == 1 ||pos == 0) //删除第一个元素独立处理
    {
    plklist->head = plklist->head->next;
    p->next = NULL;
    }
    else
    {
    while(p != NULL && i <pos-1) //绉诲姩娲诲姩鑺傜偣鍒皃os浣嶇疆鐨勫墠涓€涓?
    {
    p = p->next;
    i++;
    }
    if( i<pos-1 ||p==NULL ) //鍒ゆ柇鏄�惁瓒婄晫
    {
    printf("delete error ! ");
    exit(-1);
    }


    p->next = p->next->next;
    }
    return 0;
    }

    int delete_same(linklist_t *plklist)
    {
    node_t *p1 = NULL;
    node_t *p2 = NULL;
    node_t *p3 = NULL; //p3 用来存放相等的节点

    p1 = plklist->head;
    p2 = plklist->head; //开始p1 p2都指向头节点

    while(p1 != NULL) //外循环
    {
    while(p2->next !=NULL) //内循环
    {
    if(p1->data == p2->next->data)
    {
    p3 = p2->next; //p3指向相等的节点
    p2->next = p3->next; //把链表跳过p3
    free(p3); //释放内存
    }
    else
    {
    p2 = p2->next; //遍历后面的节点
    }
    }
    p1 = p1->next; //外循环移动节点向后
    p2 = p1;
    }
    }

    int search_lklist(linklist_t *plklist, int val)
    {
    int i = 1;
    node_t *p = plklist->head;

    while(p != NULL && p->data != val)
    {
    p = p->next;
    i++;
    }
    if(i > plklist->length)
    {
    printf("can not find anything ! ");
    exit(-1);
    }

    printf("the position is %d ",i);
    return 0;
    }

    int length_list(linklist_t *plklist)
    {
    node_t *p = plklist->head;
    int count = 0;

    while(p != NULL)
    {
    p = p->next;
    count++;
    }
    return count;
    }


    int sort_list(linklist_t *plklist)
    {

    node_t *p;
    node_t *q;
    int temp;

    for(p = plklist->head; p !=NULL; p=p->next)
    {
    for(q = p->next; q!=NULL; q = q->next)
    {
    if(p->data > q->data)
    {
    temp = p->data;
    p->data = q->data;
    q->data = temp;
    }
    }
    }
    }

    int sort_list2(linklist_t *plklist)
    {
    linklist_t sortlist;
    linklist_t *slist= init_lklist(&sortlist);//定义一个新的链表,用来存放排序好的

    node_t *pnew = NULL;

    printf("here1 ");
    while(1)
    {printf("here2 ");
    pnew = plklist->head; //定义一个中间节点,取出1 的头结点

    if(pnew == NULL) //当pnew 指向空的时候,说明1 已经取完了,跳出循环
    break;

    plklist->head = plklist->head->next; //把头结点向后移动,不能移动pnew节点,会死循环
    pnew->next = NULL; //把pnew 从1 中断出来

    if(slist->head == NULL) // 1,当2 为空的时候就直接就直接插在第一个
    {
    slist->head = pnew;
    slist->tail = pnew;
    slist->length++;
    }
    else // 2, 2不为空的情况
    {
    if(pnew->data <= slist->head->data) // 1 。2不为空,pnew小于等于2 的头结点的时候直接头插
    {
    head_inser_lklist(slist, pnew);
    }
    else if(pnew->data > slist->tail->data) // 2 。2不为空,pnew大于2 的尾节点的时候直接尾插
    {
    tail_inser_lklist(slist, pnew);
    }
    else //中间插入的情况
    {

    node_t *pcur = NULL;
    node_t *pre = NULL;

    pcur = slist->head->next;
    pre = slist->head; //定义两个节点,指向前驱和后驱

    while(pcur != NULL) //必须加循环
    {
    if(pnew->data <= pcur->data) //因为2 已经是有序的了,只要满足这个就可以直接插入了
    {
    pnew->next = pcur;
    pre->next = pnew;
    slist->length++;
    break; //插入完成后,跳出循环,在1 中再取一个元素
    }
    else //移动前驱和后驱
    {
    pre = pcur;
    pcur = pcur->next;
    }
    }
    }
    }
    }
    plklist->head = slist->head;//把有序的新链表赋给原来的链表,返回结果
    plklist->tail = slist->tail;
    plklist->length = slist->length;
    }
    int create_list(linklist_t *plklist)
    {
    int num;
    node_t *pnode;

    printf("input the number to create a linklist end with '0' : ");
    scanf("%d",&num);

    while(num != 0)
    {
    pnode=(node_t*)malloc(sizeof(node_t));
    pnode->data = num;
    pnode->next = NULL;

    tail_inser_lklist(plklist, pnode);
    scanf("%d",&num);
    }
    }


    int show_llist(linklist_t *plklist)
    {
    node_t *pcur = plklist->head;
    printf("hellos%d ",plklist->length);

    while(pcur != NULL)
    {
    printf("%d ",pcur->data);
    pcur = pcur->next;
    }
    }


    int main(int argc, char* argv[])
    {
    int num;
    int pos;
    int count;
    int delpos;
    int searval;

    linklist_t lklist;
    linklist_t *list;
    list = init_lklist(&lklist); //鍒濆�鍖栧畬閾捐〃锛屽緱鍒伴摼琛ㄦ寚閽?

    create_list(list); //鍒涘缓閾捐〃骞朵笖鏄剧ず
    show_llist(list);

    count = length_list(list); //鑾峰緱閾捐〃鐨勯暱搴﹀苟涓旀樉绀?
    printf("length = %d ",count);
    /*
    printf("insert the position and number :"); //瀵瑰簲浣嶇疆鎻掑叆鏁板€硷紝骞舵樉绀烘彃鍏ュ悗鐨勯摼琛?
    scanf("%d,%d",&pos,&num);
    middle_inser_lklist(list, pos, num);
    show_llist(list);

    printf("delete the position :"); //瀵瑰簲浣嶇疆鍒犻櫎鏁板€硷紝骞舵樉绀哄垹闄ゅ悗鐨勯摼琛?
    scanf("%d",&delpos);
    delete_lklist(list, delpos);
    show_llist(list);

    printf("search the number :"); //瀵瑰簲浣嶇疆鍒犻櫎鏁板€硷紝骞舵樉绀哄垹闄ゅ悗鐨勯摼琛?
    scanf("%d",&searval);
    search_lklist(list, searval);

    // sort_list(list);
    //show_llist(list);

    sort_list2(list);
    show_llist(list);
    */

    delete_same(list);
    show_llist(list);
    return 0;
    }

    这些都是简单的小功能,需要的时候还要继续加深巩固。代码风格和规范都有待加强啊,多写写注释,还要好好设计形式参数和返回值,这些都要养成良好的习惯。

      不多数说了,现在的任务是用链表实现成绩管理系统(向着2000+选课系统又迈近一小步。。。)

  • 相关阅读:
    北京大学数学分析习题集参考解答03.07难题
    北京大学数学分析习题集参考解答03.06一致连续性
    北京大学数学分析习题集参考解答03.05最大、最小值
    北京大学数学分析习题集参考解答03.03中间值性质03.04初等函数的连续性
    北京大学数学分析习题集参考解答03.02连续函数的运算
    北京大学数学分析习题集参考解答03.01连续与间断
    [Oracle工程师手记] 利用 DBMS_SQLTUNE.report_sql_monitor 生成 SQL 语句的监控信息
    [Oracle工程师手记] Data Guard 环境中,查找最近发生的与 Data Guard 相关的错误的方法
    [Oracle 工程师手记] Windows 环境下,获取与 oracle 相关 registry 的小技巧
    [Oracle工程师手记]从RAC环境备份后向新环境(文件系统)恢复的试验
  • 原文地址:https://www.cnblogs.com/ygy1784717631/p/4746089.html
Copyright © 2020-2023  润新知