今天励志短语:“人生的价值,即以其人对于当代所做的工作为尺度。”
昨天我们看了线性表的一些定义概念,今天来看下其中的单项链表代码如何实现。
1. 声明结构
如下声明一个指向结构的指针。(存放整数的节点,我们也可以根据需要创建字符的链表)
typedef
struct
list_node *list_pointer;
typedef
struct
list_node{
intdata;
list_pointerlink;
};
list_pointerptr =
NULL;
2. 定义宏
定义一个宏,来检测空表
#define
IS_EMPTY(ptr) (!(ptr))
定义宏,检查是否有可用空间。
#define
IS_FULL(ptr) (!(ptr))
3. 创建二节点的函数
函数如下,创建两个节点first和second.
First指向第一个节点,second指向第二个节点。同时第一个节点中的link指向第二个节点。
而第二个节点的link为NULL。
list_pointer create2()
{
list_pointerfirst,second;
first= (list_pointer) malloc (sizeof(list_node));
second= (list_pointer) malloc (sizeof(list_node));
second->link=
NULL;
second->data= 2;
first->data=1;
first->link=second;
returnfirst;
}
4. 表的前端插入
在表中前端插入一个值为dat的节点,实现如下。考虑了首节点是否为空的情况。
void insert(list_pointer *ptr,
int
dat)
{
list_pointertemp;
temp =(list_pointer)malloc(sizeof(list_node));
if(
IS_FULL(temp)){
fprintf(stderr,"Thememory is full\n");
exit(1);
}
temp->data=dat;
if(*ptr){
temp->link=*ptr;
*ptr=temp;
}
else{
temp->link=NULL;
*ptr=temp;
}
}
5. 节点的删除
删除节点需要3个输入,一个是链表的起始,一个是删除点的前驱节点,另一个是删除的节点本身。要判断链表是否为空,为空就不能再free了。
如果删除的是首节点,那么首节点的前驱节点一定是NULL,那么直接将trail指向下一个即可。
void deletenode(list_pointer *ptr,list_pointer
trail,list_pointer
node)
{
if(IS_EMPTY(ptr))
{
fprintf(stderr,"emptylist ");
exit(1);
}
if(trail)
trail->link=
node->link;
else
*ptr=(*ptr)->link;
free(node);
}
6. 表的输出
查看链表上有多少节点,输出节点中的数字。
void print_list(list_pointer
ptr)
{
printf("Thelist contains:");
for(;ptr;ptr=ptr->link)
printf("%4d",ptr->data);
printf("\n");
}
7. 表的释放
我们必须保持释放的习惯。不然会吃亏的。
void free_list(list_pointer
ptr)
{
list_pointertemp =
NULL;
for(;ptr;)
{
temp=ptr;
ptr=ptr->link;
temp->link=NULL;
free(temp);
}
}
8. 综合
执行如下代码后
void main()
{
ptr=create2();
print_list(ptr);
printf("afterinsert \n");
insert(&ptr,3);
print_list(ptr);
free_list(ptr);
}
如下图1:
删除头结点,代码如下,
如下图2
ptr=create2();
print_list(ptr);
printf("afterinsert \n");
insert(&ptr,3);
print_list(ptr);
deletenode(&ptr,NULL,ptr);
printf("afterdelete first node \n");
print_list(ptr);
free_list(ptr);
删除非头结点,代码
//删除非头结点
ptr=create2();
print_list(ptr);
printf("afterinsert \n");
insert(&ptr,3);
print_list(ptr);
deletenode(&ptr,ptr,ptr->link);
printf("afterdelete no first node \n");
print_list(ptr);
free_list(ptr);
得到如下图3.
9. 全部源码
为方便大家调试,这里附上全部代码,可直接编译运行。(蛤蟆在VS2012和 Linux GCC4.47编译均可正常运行)
#include
"stdio.h"
#include
"stdlib.h"
#define
IS_EMPTY(ptr)(!(ptr))
#define
IS_FULL(ptr) (!(ptr))
typedef
struct list_node *list_pointer;
typedef
struct list_node{
int data;
list_pointerlink;
}list_node;
//建立空表ptr
list_pointer ptr =
NULL;
void insert(list_pointer *ptr,
int
dat)
{
list_pointertemp;
temp =(list_pointer)malloc(sizeof(list_node));
if(
IS_FULL(temp)){
fprintf(stderr,"Thememory is full\n");
exit(1);
}
temp->data=dat;
if(*ptr){
temp->link=*ptr;
*ptr=temp;
}
else{
temp->link=NULL;
*ptr=temp;
}
}
void deletenode(list_pointer *ptr,list_pointer
trail,list_pointer
node)
{
if(IS_EMPTY(ptr))
{
fprintf(stderr,"emptylist ");
exit(1);
}
if(trail)
trail->link=
node->link;
else
*ptr=(*ptr)->link;
free(node);
}
void print_list(list_pointer
ptr)
{
printf("Thelist contains:");
for(;ptr;ptr=ptr->link)
printf("%4d",ptr->data);
printf("\n");
}
void free_list(list_pointer
ptr)
{
list_pointertemp =
NULL;
for(;ptr;)
{
temp=ptr;
ptr=ptr->link;
temp->link=NULL;
free(temp);
}
}
list_pointer create2()
{
list_pointerfirst,second;
first= (list_pointer) malloc (sizeof(list_node));
second= (list_pointer) malloc (sizeof(list_node));
second->link=
NULL;
second->data= 2;
first->data=1;
first->link=second;
returnfirst;
}
void main()
{
//基本运行
/* ptr=create2();
print_list(ptr);
printf("afterinsert \n");
insert(&ptr,3);
print_list(ptr);
free_list(ptr);*/
//删除头结点
ptr=create2();
print_list(ptr);
printf("afterinsert \n");
insert(&ptr,3);
print_list(ptr);
deletenode(&ptr,NULL,ptr);
printf("afterdelete first node \n");
print_list(ptr);
free_list(ptr);
//删除非头结点
/* ptr=create2();
print_list(ptr);
printf("afterinsert \n");
insert(&ptr,3);
print_list(ptr);
deletenode(&ptr,ptr,ptr->link);
printf("afterdelete no first node \n");
print_list(ptr);
free_list(ptr);
*/
}