《C和指针》第12章 使用结构和指针

这一章详细讲了单链表,考虑的很全面,我感觉很有用,特此记录下来。

单链表的头文件(sll_node.h):

typedef struct NODE
{
    struct NODE *link;
    int         value;
} Node;

插入函数(sll_insert):

#include <stdio.h>
#include <stdlib.h>
#include "sll_node.h"

define FALSE 0
define TRUE  1
int sll_insert(Node *current, int new_value)
{
    Node *previous;
    Node *new;

    /*
    **寻找正确的插入位置,方法是按顺序访问链表,直到到达其值大于或等于
    **新插入值的节点。
    */
    while(current->value < new_value)
    {
        previous=current;
        current=current->link;
    }
    /*
    **为新节点分配内存,并把新值存储到新节点中,如果内存分配失败,函数返回FALSE
    */
    new=(Node*)malloc(sizeof(Node));
    if(new==NULL)
        return FALSE;
    new->value=new_value;
    /*
    **把新节点插入到链表中,并返回TRUE
    */
    new->link=current;
    previous->link=new;
    return TRUE;
}

我们用下面这种方法调用这个函数:

result = sll_insert(root, 12);

这个插入函数是不对的,while循环会越过链表的尾部,并对一个NULL指针执行间接访问操作。为了解决这个问题,我们必须对current的值进行测试,在执行表达式current->value之前确保它不是一个NULL指针:

while(current != null && current->value < new_value)

但是还有一个问题,不能在链表的起始位置插入一个节点,因为函数不能访问变量root。

改进后:

#include <stdio.h>
#include <stdlib.h>
#include "sll_node.h"

define FALSE 0
define TRUE  1
int sll_insert(Node **rootp, int new_value)
{
    Node *current;
    Node *previous;
    Node *new;

    /*
    **得到指向第1个节点的指针。
    */
    current = *rootp;
    previous = NULL;
    
    /*
    **寻找正确的插入位置,方法是按顺序访问链表,直到到达其值大于或等于
    **新插入值的节点。
    */
    while(current != null && current->value < new_value)
    {
        previous=current;
        current=current->link;
    }
    /*
    **为新节点分配内存,并把新值存储到新节点中,如果内存分配失败,函数返回FALSE
    */
    new=(Node*)malloc(sizeof(Node));
    if(new==NULL)
        return FALSE;
    new->value=new_value;
    /*
    **把新节点插入到链表中,并返回TRUE
    */
    new->link=current;
    if(previous == NULL)//检查新值是否应为链表的第1个节点
        *rootp=new;
    else
        previous->link=new;
    return TRUE;
}

我们必须用下面这种方式调用这个函数:

result = sll_insert( &root, 12 );


 

转载于:https://my.oschina.net/u/923087/blog/279186

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值