C语言基础-链表
12.1 链表
通过组合使用结构体和指针创建强大的数据结构。
链表(linked list)就是一些包含数据的独立数据结构(通常成为节点)的集合 。
通常节点是通过动态分配的,但是也可以通过节点数组构建链表。即使在这种情况下,程序也是通过指针遍历链表的。
12.2 单链表
在单链表中,每个节点包含一个指向链表下一个节点的指针。
链表最后一个节点为NULL指针。为了记录链表的起始位置,可以使用一个跟指针(root pointer)。
根指针指向链表的第一个节点。单链表只能单向遍历,各个节点分布在内存的各个地方,不一定连续。
12.2.1 在单链表中插入
例子:
/*
插入到一个有序的单链表。函数的参数是一个指向链表第一个节点的指针以及需要插入的值。
*/
#include <stdlib.h>
#include <stdio.h>
#define FALSE 0
#define TURE 1
typedef struct node_t {
struct node_t *link;
int value;
} node;
/*
版本3:rootp参数改为linkp,表示现在指向的是不同的link段。
消除特殊情况,看上去不同的操作总结出共性。
*/
int list_insert( register node **linkp, int new_value )
{
register node *new;
register node *current;
current = *linkp;
/*
顺序访问链表,直到找到第一个大于等于新插入值的节点
确保current指针不会指向链表尾部NULL指针,对空指针进行间接访问操作是违法的。
*/
while( current != NULL && current->value < new_value ){
linkp = ¤t->link;
current = *linkp;
}
/*
为新的节点分配内存,并把新值存储到新节点中,如果动态分配内存失败,函数返回FALSE
*/
new = (node *)malloc( sizeof( node ) );
if( new == NULL )
return FALSE;
new->value = new_value;
/*
把新的节点插入到链表中。
*/
new->link = current;
*linkp = new;
return TURE;
}
//用下面方式调用函数
insert( &root, 12 );
12.3 双链表
在一个双链表中,每个都包含两个节点,一个指向节点前面,一个指向节点后面。
例子:
/*
把一个新值插入到一个双链表中。rootp是一个指向根节点的指针
value是要插入的新值
返回值:如果链表中已经存在这个值,函数返回0
如果为新值分配内存失败,返回-1
如果新值成功插入链表,返回1.
*/
#include <stdlib.h>
#include <stdio.h>
typedef struct node_t {
struct node_t *fwd; //指向后一个节点指针
struct node_t *bwd; //指向前一个节点指针
int value;
} node;
int dll_insert( register node *rootp, int value)
{
register node *this;
register node *next;
register node *newnode;
/*
查看value是否已经存在链表中,是就返回
否则创建一个新的节点
this指针指向新节点之前的那个节点
next指针指向新节点之后的那个节点
*/
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;
}
浙公网安备 33010602011771号