zoukankan      html  css  js  c++  java
  • 简单的线性表3

    不带空头节点的链表

      在这种链表中每一个节点都用来存放数据。

      我们可以在链表结构体中把指向节点结构体的头尾指针定义出来,并选取一个int型的变量length来控制链表的长度。

      同样以简单的学生成绩管理系统为例。

    #include <stdio.h>
    #include <stdlib.h>
    
    
    /*数据结构体*/
    typedef struct Student
    {
        int     number;
        char    name[20];
        float   math;
    }STU;
    typedef STU* PtStu;
    
    /*节点结构体*/
    typedef struct Node
    {
        /*数据域*/
        STU     data;
        /*指针域*/
        struct Node* pnext;
    }NODE;
    typedef NODE* PtNode;
    
    /*链表*/
    typedef struct List
    {
        /*头尾指针*/
        PtNode      pfront;
        PtNode      prear;
        /*长度*/
        int         length;
    }LIST;
    typedef LIST* PtList;

      首先,同样要初始化链表:

        我们都知道在带有空头节点的链表中,可以直接把空头节点创建出来;

          现在初始化链表要确定头指针、尾指针指向哪里,长度究竟是多少(即创建链表的“管理者”)

           

        这里的plist指向的内存是链表里面的节点。

    //创建一个头结点(是链表的一部分)
    PtList ListInit()
    {
        PtList ptlist = (PtList)malloc(sizeof(LIST));
        ptlist->pfront = NULL;
        ptlist->prear = NULL;
        ptlist->length = 0;
    
        return ptlist;
    }

      接着,判断链表是否为空

    //为空返回1  不为空返回0
    unsigned char IsEmpty(PtList ptlist)//此处想用八个位的char表示布尔型,在c++中可直接用bool函数
    {
        if (NULL == ptlist->pfront&&  NULL == ptlist->prear && 0 == ptlist->length)
            return 1;
        else
            return 0;
    }

      之后,我们就可以操作链表来达到目的了。

        在增加节点的时候,以增加第一个节点为例:头尾指针都指向第一个节点,同时length变为1,增加第二个节点时尾指针后移,length+1,如图

       接下来依次类推,在后面增加只要尾指针后移,如果我们想要在前面增加可以把头指针向前移动,效果一样。

       我们可以在外面(main函数中)开辟内存空间,

       因此在main函数中我们就可以增加以下代码,仍然用for循环来控制增加个数。

    int n = 0;
        printf("需要增加几条信息:");
        scanf("%d", &n);
        for (int i = 0; i <n; i++)
        {
            PtNode ptnode = (PtNode)malloc(sizeof(NODE));
            memset(ptnode, 0, sizeof(NODE));
            printf("input numeber:
    ");
            scanf("%d", &ptnode->data.number);
            printf("input name:
    ");
            scanf("%s", ptnode->data.name);
            printf("input score:
    ");
            scanf("%f", &ptnode->data.math);
            AddListNode(ptlist, ptnode);
        }

      在函数中就可以只针对链表了,把链表的节点作为参数带进去,作为链表结构体的指针。

      我们也就能分为原本为空和不为空两种。

    为空时

        

     不为空时

     简化后代码如下:

    //增加链表的节点 在ptlist这个链表中增加ptnode
    void AddListNode(PtList ptlist, PtNode ptnode)
    {
        if (IsEmpty(ptlist) != 1)   //不为空的
            ptlist->prear->pnext = ptnode;
        else                        //为空
            ptlist->pfront = ptnode;
    
        ptlist->prear = ptnode;
        ptlist->length++;
    }

      接下来遍历链表可以使用函数指针,只要不是空,就查看数据

    //查看一个节点数据
    void SeekData(PtNode ptnode)
    {
        if (ptnode != NULL)
        {
            printf("number:%d
    ", ptnode->data.number);
            printf("name:%s
    ", ptnode->data.name);
            printf("math:%.2f
    ", ptnode->data.math);
        }
    }

        因为length为节点的个数,我们可以直接由此依次输出,每遍历一次指针后移一个,节点数也就减少一个。

    //遍历
    void TaverseList(PtList ptlist, void(*Traverse)(PtNode ptnode))
    {
        PtNode ptnode = ptlist->pfront;
        int num = ptlist->length;
        while (num)
        {
            Traverse(ptnode);
            ptnode = ptnode->pnext;
            num--;
        }
    }

       这样TaverseList(ptlist, SeekData);就可以达到遍历链表的目的。

      我们也就可以想到查找就是把固定的节点遍历出来,也就能够解决了,并且修改过之后也可以通过该函数指针遍历出来。

      删除节点时要注意length要-1并且最后要返回头节点

    PtNode DeleteList(PtList ptlist, PtNode ptlistnode)
    {
        PtNode ptnode = ptlist->pfront;
    
        if (IsEmpty(ptlist) != 1)
        {
            memcpy(ptlistnode, ptnode, sizeof(NODE));
            ptlist->pfront = ptlist->pfront->pnext;
            free(ptnode);
            ptlist->length--;
            if (0 == ptlist->length)
                ptlist->prear = NULL;
        }
        return ptlist->pfront;
    }

     与带空头节点的链表相比,不带空头节点的链表更有掌握全局的感觉,但是代码也会更复杂一点。

  • 相关阅读:
    [Z]芯片设计经验
    ADF4350初始化程序(verilog)
    基于Altera FPGA的LVDS配置应用一例
    M4K使用率
    榨干FPGA片上存储资源
    ios通讯录复制出来的电话号码两端有隐藏字符串
    PHP做APP接口时,如何保证接口的安全性
    【PHP】微信开放平台---消息加解密-php7.1 使用openssl代替Mcrypt
    Gram矩阵(pytorch)
    数据库范式
  • 原文地址:https://www.cnblogs.com/wst-blog/p/12717081.html
Copyright © 2011-2022 走看看