(十二)使用结构和指针
单链表
typedef struct NODE {
struct NODE *link;
int value;
} Node;
#include <stdlib.h>
#include <stdio.h>
#include "sll_node.h"
#define FALSE 0
#define TRUE 1
int sll_insert(register Node **linkp, int new_value)
{
register Node *current;
register Node *new;
while((current = *linkp) != NULL && current->value < new_value){
linkp = ¤t->link;
}
new = (Node *)malloc(sizeof(Node));
if(new == NULL)
return FALSE;
new->value = new_value;
new->link = current;
*linkp = new;
return TRUE;
}
上面的程序存在一个问题:为了在链表起始位置插入一个节点,函数必须修改根指针。但是函数不能访问变量root。
把一个指向root的指针作为参数传递给函数,然后使用间接访问,函数不仅可以获得root的值,也可以向它存储一个新的指针值。
#include <stdlib.h>
#include <stdio.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;
current = *rootp;/*得到指向链表第1个节点的指针 */
previous = NULL;
while(current != NULL && current->value < new_value){
previous = current;
current = current -> link;
}
new = (Node *)malloc(sizeof(Node));
if(new == NULL)
return FALSE;
new->value = new_value;
new->link = current;
if(previous == NULL)
*rootp = new;
else
previous->link = new;
return TRUE;
}
进一步优化:我们可以保存一个“指向下一个节点的link字段的”指针,而不是保存一个“指向前一个节点的”指针。
#include <stdlib.h>
#include <stdio.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;
current = *rootp;/*得到指向链表第1个节点的指针 */
previous = NULL;
while(current != NULL && current->value < new_value){
previous = current;
current = current -> link;
}
new = (Node *)malloc(sizeof(Node));
if(new == NULL)
return FALSE;
new->value = new_value;
new->link = current;
if(previous == NULL)
*rootp = new;
else
previous->link = new;
return TRUE;
}
双链表
typedef struct NODE {
struct NODE *fwd;
struct NODE *bwd;
int value;
} Node;
#include <stdlib.h>
#include <stdio.h>
#include "doubly_liked_list_node.h"
int dll_insert(register Node *rootp, int value)
{
register Node *this;
register Node *next;
register Node *newnode;
for(this = rootp; (next = this->fwd) != NULL; this = next){
if(next->value == value)
return 0;
if(next->value > value)
break;
}
newnode = (Node *)malloc(sizeof(Node)); /*在决定是否应该插入到链表之前,不应该为新值分配内存。如果分配了内存又不插入链表就有可能发生内存泄漏 */
if(newnode == NULL)
return -1;
newnode->value = value;
newnode->fwd = next;
this->fwd = newnode;
if(this != rootp)
newnode->bwd = this;
else
newnode->bwd = NULL;
if(next != NULL)
next->bwd = newnode;
else
rootp->bwd = newnode;
return 1;
}