设为首页 加入收藏

TOP

链表(单向链表的建立、删除、插入、打印)(二)
2019-08-13 05:39:26 】 浏览:154
Tags:链表 单向 建立 删除 插入 打印
的节点数据值
    p->next = NULL;        //将新建的节点置为表尾
    return head;        //返回添加节点后的链表的头指针
}
/* 函数的功能:显示链表中所有节点的节点号和该节点中的数据项的内容*/
void DisplyNode (struct link *head)
{
    struct link *p = head;
    int j = 1;
    while (p != NULL)  //若不是表尾,则循环打印节点的数值
    {
        printf("%5d%10d\n", j, p->data);//打印第j个节点数据
        p = p->next;  //让p指向下一个节点
        j++;
    }
}
//函数的功能:释放head所指向的链表中所有节点占用的内存
void DeletMemory(struct link *head)
{
    struct link *p = head, *pr = NULL;
    while (p != NULL)  //若不是表尾,则释放节点占用的内存
    {
        pr = p;        //在pr中保存当前节点的指针
        p = p->next;//让p指向下一个节点
        free(pr);    //释放pr指向的当前节点占用的内存
    }
}


上面的代码使用了三个函数AppendNode、DisplyNode、DeletMemory


struct link *AppendNode (struct link *head);(函数作用:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针)


void DisplyNode (struct link *head);(函数功能:显示链表中所有节点的节点号和该节点中的数据项的内容)


void DeletMemory (struct link *head);(函数功能:释放head所指向的链表中所有节点占用的内存)


(还使用了malloc函数和free函数)


 


5、malloc函数


作用:用于分配若干字节的内存空间,返回一个指向该内存首地址的指针,若系统不能提供足够的内存单元,函数将返回空指针NULL,函数原型为void *malloc(unsigned int size)


其中size是表示向系统申请空间的大小,函数调用成功将返回一个指向void的指针(void*指针是ANSIC新标准中增加的一种指针类型,


具有一般性,通常称为通用指针或者无类型的指针)常用来说明其基类型未知的指针,即声明了一个指针变量,但未指定它可以指向哪一种基类型的数据,


因此,若要将函数调用的返回值赋予某个指针,则应先根据该指针的基类型,用强转的方法将返回的指针值强转为所需的类型,然后再进行赋值


 1 int *pi; 2 pi = (int *)malloc(4);


其中malloc(4)表示申请一个大小为4字节的内存,将malloc(4)返回值的void*类型强转为int*类型后再赋值给int型指针变量pi,即用int型指针变量pi指向这段存储空间的首地址


若不能确定某种类型所占内存的字节数,则需使用sizeof()计算本系统中该类型所占的内存字节数,然后再用malloc()向系统申请相应字节数的存储空间


pi = (int *)malloc(sizeof(int));


6、free函数


释放向系统动态申请的由指针p指向的内存存储空间,其原型为:Void free(void *p);该函数无返回值,唯一的形参p给出的地址只能由malloc()和calloc()申请内存时返回的地址,


该函数执行后,将以前分配的指针p指向的内存返还给系统,以便系统重新分配


 为什么要用free释放内存


(在程序运行期间,用动态内存分配函数来申请的内存都是从堆上分配的,动态内存的生存期有程序员自己来决定,使用非常灵活,但也易出现内存泄漏的问题,


为了防止内存泄漏的发生,程序员必须及时调用free()释放已不再使用的内存)


7、单向链表的删除操作


删除操作就是将一个待删除的节点从链表中断开,不再与链表的其他节点有任何联系


需考虑四种情况:


  1.若原链表为空表,则无需删除节点,直接退出程序


  2.若找到的待删除节点p是头节点,则将head指向当前节点的下一个节点(p->next),即可删除当前节点


   3.若找到的待删除节点不是头节点,则将前一节点的指针域指向当前节点的下一节点(pr->next = p->next),即可删除当前节点,当待删除节点是末节点时,


由于p->next值为NULL,因此执行pr->next = p->next后,pr->next的值也变成NULL,从而使pr所指向的节点由倒数第2个节点变成了末节点


  4.若已搜索到表尾(p->next == NULL),仍未找到待删除节点,则显示“未找到”,注意:节点被删除后,只是将它从链表中断开而已,它仍占用着内存,必须释放其所占的内存,否则将出现内存泄漏


(头结点不是头指针,注意两者区别)


8、头节点和头指针


头指针存储的是头节点内存的首地址,头结点的数据域可以存储如链表长度等附加信息,也可以不存储任何信息



值得注意的是:


  1.无论链表是否为空,头指针均不为空。头指针是链表的必要元素


  2.链表可以没有头节点,但不能没有头指针,头指针是链表的必要元素


   3.记得使用free释放内存


单向链表的删除操作实现


struct link *DeleteNode (struct link *head, int nodeData)
{
    struct link *p = head, *pr = head;


    if (head == NULL)
    {
        printf("Linked table is empty!\n");
        return 0;
    }
    while (nodeData != p->data && p->next != NULL)
    {
        pr = p;            /* pr保存当前节点 */
        p = p->next;    /* p指向当前节点的下一节点 */
    }
   

首页 上一页 1 2 3 4 5 下一页 尾页 2/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C语言 栈(链式栈) 下一篇C语言 队列(循环队列)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目