这一章详细讲了单链表,考虑的很全面,我感觉很有用,特此记录下来。
单链表的头文件(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 );